From 6bfd3ea7c593ca72d015a90ff3328bcbc1d016d1 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 08:31:04 -0500 Subject: [PATCH 01/53] new pyfpdf, thanks Mariano --- VERSION | 2 +- gluon/contrib/pyfpdf/README | 1 - gluon/contrib/pyfpdf/__init__.py | 19 +- gluon/contrib/pyfpdf/designer.py | 736 -------------------- gluon/contrib/pyfpdf/fonts.py | 156 +++++ gluon/contrib/pyfpdf/fpdf.py | 1098 ++++++++++++++++++------------ gluon/contrib/pyfpdf/html.py | 127 +--- gluon/contrib/pyfpdf/php.py | 49 ++ gluon/contrib/pyfpdf/template.py | 107 +-- gluon/contrib/pyfpdf/ttfonts.py | 1033 ++++++++++++++++++++++++++++ 10 files changed, 1997 insertions(+), 1331 deletions(-) delete mode 100644 gluon/contrib/pyfpdf/README delete mode 100644 gluon/contrib/pyfpdf/designer.py create mode 100644 gluon/contrib/pyfpdf/fonts.py create mode 100644 gluon/contrib/pyfpdf/php.py mode change 100755 => 100644 gluon/contrib/pyfpdf/template.py create mode 100644 gluon/contrib/pyfpdf/ttfonts.py diff --git a/VERSION b/VERSION index 88809e6c..775477a3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-22 19:47:08) dev +Version 2.00.0 (2012-08-23 08:31:01) dev diff --git a/gluon/contrib/pyfpdf/README b/gluon/contrib/pyfpdf/README deleted file mode 100644 index 88916d70..00000000 --- a/gluon/contrib/pyfpdf/README +++ /dev/null @@ -1 +0,0 @@ -Read more about this http://code.google.com/p/pyfpdf diff --git a/gluon/contrib/pyfpdf/__init__.py b/gluon/contrib/pyfpdf/__init__.py index 7c4a2ca3..3ba17860 100644 --- a/gluon/contrib/pyfpdf/__init__.py +++ b/gluon/contrib/pyfpdf/__init__.py @@ -1,5 +1,16 @@ -from fpdf import FPDF -from html import HTMLMixin +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"FPDF for python" + +__license__ = "LGPL 3.0" +__version__ = "1.7" + +from fpdf import * +try: + from html import HTMLMixin +except ImportError: + import warnings + warnings.warn("web2py gluon package not installed, required for html2pdf") + from template import Template - - diff --git a/gluon/contrib/pyfpdf/designer.py b/gluon/contrib/pyfpdf/designer.py deleted file mode 100644 index 3807bd6d..00000000 --- a/gluon/contrib/pyfpdf/designer.py +++ /dev/null @@ -1,736 +0,0 @@ -#!/usr/bin/python -# -*- coding: latin-1 -*- -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 3, or (at your option) any later -# version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. - -"Visual Template designer for PyFPDF (using wxPython OGL library)" - -__author__ = "Mariano Reingart " -__copyright__ = "Copyright (C) 2011 Mariano Reingart" -__license__ = "GPL 3.0" -__version__ = "1.01a" - -# Based on: -# * pySjetch.py wxPython sample application -# * OGL.py and other wxPython demo modules - - -import os, sys -import wx -import wx.lib.ogl as ogl -from wx.lib.wordwrap import wordwrap - -DEBUG = True - - -class CustomDialog(wx.Dialog): - "A dinamyc dialog to ask user about arbitrary fields" - - def __init__( - self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE, fields=None, data=None, - ): - - wx.Dialog.__init__ (self, parent, ID, title, pos, size, style) - - sizer = wx.BoxSizer(wx.VERTICAL) - - self.textctrls = {} - for field in fields: - box = wx.BoxSizer(wx.HORIZONTAL) - label = wx.StaticText(self, -1, field) - label.SetHelpText("This is the help text for the label") - box.Add(label, 1, wx.ALIGN_CENTRE|wx.ALL, 5) - text = wx.TextCtrl(self, -1, "", size=(80,-1)) - text.SetHelpText("Here's some help text for field #1") - if field in data: - text.SetValue(repr(data[field])) - box.Add(text, 1, wx.ALIGN_CENTRE|wx.ALL, 1) - sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 1) - self.textctrls[field] = text - - line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL) - sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5) - - btnsizer = wx.StdDialogButtonSizer() - - btn = wx.Button(self, wx.ID_OK) - btn.SetHelpText("The OK button completes the dialog") - btn.SetDefault() - btnsizer.AddButton(btn) - - btn = wx.Button(self, wx.ID_CANCEL) - btn.SetHelpText("The Cancel button cancels the dialog. (Cool, huh?)") - btnsizer.AddButton(btn) - btnsizer.Realize() - - sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - self.SetSizer(sizer) - sizer.Fit(self) - - @classmethod - def do_input(Class, parent, title, fields, data): - dlg = Class(parent, -1, title, size=(350, 200), - style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX, - fields=fields, data=data - ) - dlg.CenterOnScreen() - while 1: - val = dlg.ShowModal() - if val == wx.ID_OK: - values = {} - for field in fields: - try: - values[field] = eval(dlg.textctrls[field].GetValue()) - except Exception, e: - msg = wx.MessageDialog(parent, unicode(e), - "Error in field %s" % field, - wx.OK | wx.ICON_INFORMATION - ) - msg.ShowModal() - msg.Destroy() - break - else: - return dict([(field, values[field]) for field in fields]) - else: - return None - - -class MyEvtHandler(ogl.ShapeEvtHandler): - "Custom Event Handler for Shapes" - def __init__(self, callback): - ogl.ShapeEvtHandler.__init__(self) - self.callback = callback - - def OnLeftClick(self, x, y, keys=0, attachment=0): - shape = self.GetShape() - canvas = shape.GetCanvas() - dc = wx.ClientDC(canvas) - canvas.PrepareDC(dc) - - if shape.Selected() and keys & ogl.KEY_SHIFT: - shape.Select(False, dc) - #canvas.Redraw(dc) - canvas.Refresh(False) - else: - redraw = False - shapeList = canvas.GetDiagram().GetShapeList() - toUnselect = [] - - for s in shapeList: - if s.Selected() and not keys & ogl.KEY_SHIFT: - # If we unselect it now then some of the objects in - # shapeList will become invalid (the control points are - # shapes too!) and bad things will happen... - toUnselect.append(s) - - shape.Select(True, dc) - - if toUnselect: - for s in toUnselect: - s.Select(False, dc) - ##canvas.Redraw(dc) - canvas.Refresh(False) - - self.callback() - - def OnEndDragLeft(self, x, y, keys=0, attachment=0): - shape = self.GetShape() - ogl.ShapeEvtHandler.OnEndDragLeft(self, x, y, keys, attachment) - - if not shape.Selected(): - self.OnLeftClick(x, y, keys, attachment) - - self.callback() - - def OnSizingEndDragLeft(self, pt, x, y, keys, attch): - ogl.ShapeEvtHandler.OnSizingEndDragLeft(self, pt, x, y, keys, attch) - self.callback() - - def OnMovePost(self, dc, x, y, oldX, oldY, display): - shape = self.GetShape() - ogl.ShapeEvtHandler.OnMovePost(self, dc, x, y, oldX, oldY, display) - self.callback() - if "wxMac" in wx.PlatformInfo: - shape.GetCanvas().Refresh(False) - - def OnLeftDoubleClick(self, x, y, keys = 0, attachment = 0): - self.callback("LeftDoubleClick") - - def OnRightClick(self, *dontcare): - self.callback("RightClick") - - -class Element(object): - "Visual class that represent a placeholder in the template" - - fields = ['name', 'type', - 'x1', 'y1', 'x2', 'y2', - 'font', 'size', - 'bold', 'italic', 'underline', - 'foreground', 'background', - 'align', 'text', 'priority',] - - def __init__(self, canvas=None, frame=None, zoom=5.0, static=False, **kwargs): - self.kwargs = kwargs - self.zoom = zoom - self.frame = frame - self.canvas = canvas - self.static = static - - name = kwargs['name'] - kwargs['type'] - type = kwargs['type'] - - x, y, w, h = self.set_coordinates(kwargs['x1'], kwargs['y1'], kwargs['x2'], kwargs['y2']) - - text = kwargs['text'] - - shape = self.shape = ogl.RectangleShape(w, h) - - if not static: - shape.SetDraggable(True, True) - - shape.SetX(x) - shape.SetY(y) - #if pen: shape.SetPen(pen) - #if brush: shape.SetBrush(brush) - shape.SetBrush(wx.TRANSPARENT_BRUSH) - - if type not in ('L', 'B', 'BC'): - if not static: - pen = wx.LIGHT_GREY_PEN - else: - pen = wx.RED_PEN - shape.SetPen(pen) - - self.text = kwargs['text'] - - evthandler = MyEvtHandler(self.evt_callback) - evthandler.SetShape(shape) - evthandler.SetPreviousHandler(shape.GetEventHandler()) - shape.SetEventHandler(evthandler) - shape.SetCentreResize(False) - shape.SetMaintainAspectRatio(False) - - canvas.AddShape( shape ) - - @classmethod - def new(Class, parent): - data = dict(name='some_name', type='T', - x1=5.0, y1=5.0, x2=100.0, y2=10.0, - font="Arial", size=12, - bold=False, italic=False, underline=False, - foreground= 0x000000, background=0xFFFFFF, - align="L", text="", priority=0) - data = CustomDialog.do_input(parent, 'New element', Class.fields, data) - if data: - return Class(canvas=parent.canvas, frame=parent, **data) - - def edit(self): - "Edit current element (show a dialog box with all fields)" - data = self.kwargs.copy() - x1, y1, x2, y2 = self.get_coordinates() - data.update(dict(name=self.name, - text=self.text, - x1=x1, y1=y1, x2=x2, y2=y2, - )) - data = CustomDialog.do_input(self.frame, 'Edit element', self.fields, data) - if data: - self.kwargs.update(data) - self.name = data['name'] - self.text = data['text'] - x,y, w, h = self.set_coordinates(data['x1'], data['y1'], data['x2'], data['y2']) - self.shape.SetX(x) - self.shape.SetY(y) - self.shape.SetWidth(w) - self.shape.SetHeight(h) - self.canvas.Refresh(False) - self.canvas.GetDiagram().ShowAll(1) - - def edit_text(self): - "Allow text edition (i.e. for doubleclick)" - dlg = wx.TextEntryDialog( - self.frame, 'Text for %s' % self.name, - 'Edit Text', '') - if self.text: - dlg.SetValue(self.text) - if dlg.ShowModal() == wx.ID_OK: - self.text = dlg.GetValue().encode("latin1") - dlg.Destroy() - - def copy(self): - "Return an identical duplicate" - kwargs = self.as_dict() - element = Element(canvas=self.canvas, frame=self.frame, zoom=self.zoom, static=self.static, **kwargs) - return element - - def remove(self): - "Erases visual shape from OGL canvas (element must be deleted manually)" - self.canvas.RemoveShape(self.shape) - - def move(self, dx, dy): - "Change pdf coordinates (converting to wx internal values)" - x1, y1, x2, y2 = self.get_coordinates() - x1 += dx - x2 += dx - y1 += dy - y2 += dy - x, y, w, h = self.set_coordinates(x1, y1, x2, y2) - self.shape.SetX(x) - self.shape.SetY(y) - - def evt_callback(self, evt_type=None): - "Event dispatcher" - if evt_type=="LeftDoubleClick": - self.edit_text() - if evt_type=='RightClick': - self.edit() - - # update the status bar - x1, y1, x2, y2 = self.get_coordinates() - self.frame.SetStatusText("%s (%0.2f, %0.2f) - (%0.2f, %0.2f)" % - (self.name, x1, y1, x2, y2)) - - def get_coordinates(self): - "Convert from wx to pdf coordinates" - x, y = self.shape.GetX(), self.shape.GetY() - w, h = self.shape.GetBoundingBoxMax() - w -= 1 - h -= 1 - x1 = x/self.zoom - w/self.zoom/2.0 - x2 = x/self.zoom + w/self.zoom/2.0 - y1 = y/self.zoom - h/self.zoom/2.0 - y2 = y/self.zoom + h/self.zoom/2.0 - return x1, y1, x2, y2 - - def set_coordinates(self, x1, y1, x2, y2): - "Convert from pdf to wx coordinates" - x1 = x1 * self.zoom - x2 = x2 * self.zoom - y1 = y1 * self.zoom - y2 = y2 * self.zoom - - # shapes seems to be centred, pdf coord not - w = max(x1, x2) - min(x1, x2) + 1 - h = max(y1, y2) - min(y1, y2) + 1 - x = (min(x1, x2) + w/2.0) - y = (min(y1, y2) + h/2.0) - return x, y, w, h - - def text(self, txt=None): - if txt is not None: - if not isinstance(txt,str): - txt = str(txt) - self.kwargs['text'] = txt - self.shape.ClearText() - for line in txt.split('\n'): - self.shape.AddText(unicode(line, "latin1")) - self.canvas.Refresh(False) - return self.kwargs['text'] - text = property(text, text) - - def set_x(self, x): - self.shape.SetX(x) - self.canvas.Refresh(False) - self.evt_callback() - def set_y(self, y): - self.shape.SetY(y) - self.canvas.Refresh(False) - self.evt_callback() - def get_x(self): - return self.shape.GetX() - def get_y(self): - return self.shape.GetY() - - x = property(get_x, set_x) - y = property(get_y, set_y) - - def selected(self, sel=None): - if sel is not None: - print "Setting Select(%s)" % sel - self.shape.Select(sel) - return self.shape.Selected() - selected = property(selected, selected) - - def name(self, name=None): - if name is not None: - self.kwargs['name'] = name - return self.kwargs['name'] - name = property(name, name) - - def __contains__(self, k): - "Implement in keyword for searchs" - return k in self.name.lower() or self.text and k in self.text.lower() - - def as_dict(self): - "Return a dictionary representation, used by pyfpdf" - d = self.kwargs - x1, y1, x2, y2 = self.get_coordinates() - d.update({ - 'x1': x1, 'y1': y1, 'x2': x2, 'y2': y2, - 'text': self.text}) - return d - - -class AppFrame(wx.Frame): - "OGL Designer main window" - title = "PyFPDF Template Designer (wx OGL)" - - def __init__(self): - wx.Frame.__init__( self, - None, -1, self.title, - size=(640,480), - style=wx.DEFAULT_FRAME_STYLE ) - sys.excepthook = self.except_hook - self.filename = "" - # Create a toolbar: - tsize = (16,16) - self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT) - - artBmp = wx.ArtProvider.GetBitmap - self.toolbar.AddSimpleTool( - wx.ID_NEW, artBmp(wx.ART_NEW, wx.ART_TOOLBAR, tsize), "New") - self.toolbar.AddSimpleTool( - wx.ID_OPEN, artBmp(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize), "Open") - self.toolbar.AddSimpleTool( - wx.ID_SAVE, artBmp(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize), "Save") - self.toolbar.AddSimpleTool( - wx.ID_SAVEAS, artBmp(wx.ART_FILE_SAVE_AS, wx.ART_TOOLBAR, tsize), - "Save As...") - #------- - self.toolbar.AddSeparator() - self.toolbar.AddSimpleTool( - wx.ID_UNDO, artBmp(wx.ART_UNDO, wx.ART_TOOLBAR, tsize), "Undo") - self.toolbar.AddSimpleTool( - wx.ID_REDO, artBmp(wx.ART_REDO, wx.ART_TOOLBAR, tsize), "Redo") - self.toolbar.AddSeparator() - #------- - self.toolbar.AddSimpleTool( - wx.ID_CUT, artBmp(wx.ART_CUT, wx.ART_TOOLBAR, tsize), "Remove") - self.toolbar.AddSimpleTool( - wx.ID_COPY, artBmp(wx.ART_COPY, wx.ART_TOOLBAR, tsize), "Duplicate") - self.toolbar.AddSimpleTool( - wx.ID_PASTE, artBmp(wx.ART_PASTE, wx.ART_TOOLBAR, tsize), "Insert") - self.toolbar.AddSeparator() - self.toolbar.AddSimpleTool( - wx.ID_FIND, artBmp(wx.ART_FIND, wx.ART_TOOLBAR, tsize), "Find") - self.toolbar.AddSeparator() - self.toolbar.AddSimpleTool( - wx.ID_PRINT, artBmp(wx.ART_PRINT, wx.ART_TOOLBAR, tsize), "Print") - self.toolbar.AddSimpleTool( - wx.ID_ABOUT, artBmp(wx.ART_HELP, wx.ART_TOOLBAR, tsize), "About") - - self.toolbar.Realize() - - self.toolbar.EnableTool(wx.ID_SAVEAS, False) - self.toolbar.EnableTool(wx.ID_UNDO, False) - self.toolbar.EnableTool(wx.ID_REDO, False) - - menu_handlers = [ - (wx.ID_NEW, self.do_new), - (wx.ID_OPEN, self.do_open), - (wx.ID_SAVE, self.do_save), - (wx.ID_PRINT, self.do_print), - (wx.ID_FIND, self.do_find), - (wx.ID_CUT, self.do_cut), - (wx.ID_COPY, self.do_copy), - (wx.ID_PASTE, self.do_paste), - (wx.ID_ABOUT, self.do_about), - ] - for menu_id, handler in menu_handlers: - self.Bind(wx.EVT_MENU, handler, id = menu_id) - - sizer = wx.BoxSizer(wx.VERTICAL) - # put stuff into sizer - - self.CreateStatusBar() - - canvas = self.canvas = ogl.ShapeCanvas( self ) - maxWidth = 1500 - maxHeight = 2000 - canvas.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) - sizer.Add( canvas, 1, wx.GROW ) - - canvas.SetBackgroundColour("WHITE") # - - diagram = self.diagram = ogl.Diagram() - canvas.SetDiagram( diagram ) - diagram.SetCanvas( canvas ) - diagram.SetSnapToGrid( False ) - - # apply sizer - self.SetSizer(sizer) - self.SetAutoLayout(1) - self.Show(1) - - self.Bind(wx.EVT_CHAR_HOOK, self.on_key_event) - self.elements = [] - - def on_key_event(self, event): - """ Respond to a keypress event. - - We make the arrow keys move the selected object(s) by one pixel in - the given direction. - """ - step = 1 - if event.ControlDown(): - step = 20 - - if event.GetKeyCode() == wx.WXK_UP: - self.move_elements(0, -step) - elif event.GetKeyCode() == wx.WXK_DOWN: - self.move_elements(0, step) - elif event.GetKeyCode() == wx.WXK_LEFT: - self.move_elements(-step, 0) - elif event.GetKeyCode() == wx.WXK_RIGHT: - self.move_elements(step, 0) - elif event.GetKeyCode() == wx.WXK_DELETE: - self.do_cut() - else: - event.Skip() - - def do_new(self, evt=None): - for element in self.elements: - element.remove() - self.elements = [] - # draw paper size guides - for k, (w, h) in [('legal', (216, 356)), ('A4', (210, 297)), ('letter', (216, 279))]: - self.create_elements( - k, 'R', 0, 0, w, h, - size=70, foreground=0x808080, priority=-100, - canvas=self.canvas, frame=self, static=True) - self.diagram.ShowAll( 1 ) - - def do_open(self, evt): - dlg = wx.FileDialog( - self, message="Choose a file", - defaultDir=os.getcwd(), - defaultFile="invoice.csv", - wildcard="CSV Files (*.csv)|*.csv", - style=wx.OPEN - ) - - if dlg.ShowModal() == wx.ID_OK: - # This returns a Python list of files that were selected. - self.filename = dlg.GetPaths()[0] - - dlg.Destroy() - self.SetTitle(self.filename + " - " + self.title) - - self.do_new() - tmp = [] - f = open(self.filename) - try: - filedata = f.readlines() - finally: - f.close() - for lno, linea in enumerate(filedata): - if DEBUG: print "processing line", lno, linea - args = [] - for i,v in enumerate(linea.split(";")): - if not v.startswith("'"): - v = v.replace(",",".") - else: - v = v#.decode('latin1') - if v.strip()=='': - v = None - else: - v = eval(v.strip()) - args.append(v) - tmp.append(args) - - # sort by z-order (priority) - for args in sorted(tmp, key=lambda t: t[-1]): - if DEBUG: print args - self.create_elements(*args) - self.diagram.ShowAll( 1 ) # - - return True - - def do_save(self, evt, filename=None): - try: - from time import gmtime, strftime - ts = strftime("%Y%m%d%H%M%S", gmtime()) - os.rename(self.filename, self.filename + ts + ".bak") - except Exception, e: - if DEBUG: print e - pass - - def csv_repr(v, decimal_sep="."): - if isinstance(v, float): - return ("%0.2f" % v).replace(".", decimal_sep) - else: - return repr(v) - - f = open(self.filename, "w") - try: - for element in sorted(self.elements, key=lambda e:e.name): - if element.static: - continue - d = element.as_dict() - l = [d['name'], d['type'], - d['x1'], d['y1'], d['x2'], d['y2'], - d['font'], d['size'], - d['bold'], d['italic'], d['underline'], - d['foreground'], d['background'], - d['align'], d['text'], d['priority'], - ] - f.write(";".join([csv_repr(v) for v in l])) - f.write("\n") - finally: - f.close() - - def do_print(self, evt): - # genero el renderizador con propiedades del PDF - from template import Template - t = Template(elements=[e.as_dict() for e in self.elements if not e.static]) - t.add_page() - if not t['logo'] or not os.path.exists(t['logo']): - # put a default logo so it doesn't trow an exception - logo = os.path.join(os.path.dirname(__file__), 'tutorial','logo.png') - t.set('logo', logo) - try: - t.render(self.filename +".pdf") - except: - if DEBUG and False: - import pdb; - pdb.pm() - else: - raise - if sys.platform=="linux2": - os.system("evince ""%s""" % self.filename +".pdf") - else: - os.startfile(self.filename +".pdf") - - def do_find(self, evt): - # busco nombre o texto - dlg = wx.TextEntryDialog( - self, 'Enter text to search for', - 'Find Text', '') - if dlg.ShowModal() == wx.ID_OK: - txt = dlg.GetValue().encode("latin1").lower() - for element in self.elements: - if txt in element: - element.selected = True - print "Found:", element.name - self.canvas.Refresh(False) - dlg.Destroy() - - def do_cut(self, evt=None): - "Delete selected elements" - new_elements = [] - for element in self.elements: - if element.selected: - print "Erasing:", element.name - element.selected = False - self.canvas.Refresh(False) - element.remove() - else: - new_elements.append(element) - self.elements = new_elements - self.canvas.Refresh(False) - self.diagram.ShowAll( 1 ) - - def do_copy(self, evt): - "Duplicate selected elements" - fields = ['qty', 'dx', 'dy'] - data = {'qty': 1, 'dx': 0.0, 'dy': 5.0} - data = CustomDialog.do_input(self, 'Copy elements', fields, data) - if data: - new_elements = [] - for i in range(1, data['qty']+1): - for element in self.elements: - if element.selected: - print "Copying:", element.name - new_element = element.copy() - name = new_element.name - if len(name)>2 and name[-2:].isdigit(): - new_element.name = name[:-2] + "%02d" % (int(name[-2:])+i) - else: - new_element.name = new_element.name + "_copy" - new_element.selected = False - new_element.move(data['dx']*i, data['dy']*i) - new_elements.append(new_element) - self.elements.extend(new_elements) - self.canvas.Refresh(False) - self.diagram.ShowAll( 1 ) - - def do_paste(self, evt): - "Insert new elements" - element = Element.new(self) - if element: - self.canvas.Refresh(False) - self.elements.append(element) - self.diagram.ShowAll( 1 ) - - def create_elements(self, name, type, x1, y1, x2, y2, - font="Arial", size=12, - bold=False, italic=False, underline=False, - foreground= 0x000000, background=0xFFFFFF, - align="L", text="", priority=0, canvas=None, frame=None, static=False, - **kwargs): - element = Element(name=name, type=type, x1=x1, y1=y1, x2=x2, y2=y2, - font=font, size=size, - bold=bold, italic=italic, underline=underline, - foreground= foreground, background=background, - align=align, text=text, priority=priority, - canvas=canvas or self.canvas, frame=frame or self, - static=static) - self.elements.append(element) - - def move_elements(self, x, y): - for element in self.elements: - if element.selected: - print "moving", element.name, x, y - element.x = element.x + x - element.y = element.y + y - - def do_about(self, evt): - info = wx.AboutDialogInfo() - info.Name = self.title - info.Version = __version__ - info.Copyright = __copyright__ - info.Description = ( - "Visual Template designer for PyFPDF (using wxPython OGL library)\n" - "Input files are CSV format describing the layout, separated by ;\n" - "Use toolbar buttons to open, save, print (preview) your template, " - "and there are buttons to find, add, remove or duplicate elements.\n" - "Over an element, a double left click opens edit text dialog, " - "and a right click opens edit properties dialog. \n" - "Multiple element can be selected with shift left click. \n" - "Use arrow keys or drag-and-drop to move elements.\n" - "For further information see project webpage:" - ) - info.WebSite = ("http://code.google.com/p/pyfpdf/wiki/Templates", - "pyfpdf Google Code Project") - info.Developers = [ __author__, ] - - info.License = wordwrap(__license__, 500, wx.ClientDC(self)) - - # Then we call wx.AboutBox giving it that info object - wx.AboutBox(info) - - def except_hook(self, type, value, trace): - import traceback - exc = traceback.format_exception(type, value, trace) - for e in exc: wx.LogError(e) - wx.LogError('Unhandled Error: %s: %s'%(str(type), str(value))) - - -app = wx.PySimpleApp() -ogl.OGLInitialize() -frame = AppFrame() -app.MainLoop() -app.Destroy() - - - diff --git a/gluon/contrib/pyfpdf/fonts.py b/gluon/contrib/pyfpdf/fonts.py new file mode 100644 index 00000000..433fbf61 --- /dev/null +++ b/gluon/contrib/pyfpdf/fonts.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# -*- coding: latin-1 -*- + +# Fonts: + +fpdf_charwidths = {} + +fpdf_charwidths['courier']={} + +for i in xrange(0,256): + fpdf_charwidths['courier'][chr(i)]=600 + fpdf_charwidths['courierB']=fpdf_charwidths['courier'] + fpdf_charwidths['courierI']=fpdf_charwidths['courier'] + fpdf_charwidths['courierBI']=fpdf_charwidths['courier'] + +fpdf_charwidths['helvetica']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667, + 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833, + 'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556, + '\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556, + '\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} + +fpdf_charwidths['helveticaB']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722, + 'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889, + 'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556, + '\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611, + '\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556 +} + +fpdf_charwidths['helveticaBI']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722, + 'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889, + 'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556, + '\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611, + '\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556} + +fpdf_charwidths['helveticaI']={ + '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, + '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584, + ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667, + 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, + 'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833, + 'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556, + '\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, + '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556, + '\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} + +fpdf_charwidths['symbol']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':713,'#':500,'$':549,'%':833,'&':778,'\'':439,'(':333,')':333,'*':500,'+':549, + ',':250,'-':549,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':549,'=':549,'>':549,'?':444,'@':549,'A':722, + 'B':667,'C':722,'D':612,'E':611,'F':763,'G':603,'H':722,'I':333,'J':631,'K':722,'L':686,'M':889,'N':722,'O':722,'P':768,'Q':741,'R':556,'S':592,'T':611,'U':690,'V':439,'W':768, + 'X':645,'Y':795,'Z':611,'[':333,'\\':863,']':333,'^':658,'_':500,'`':500,'a':631,'b':549,'c':549,'d':494,'e':439,'f':521,'g':411,'h':603,'i':329,'j':603,'k':549,'l':549,'m':576, + 'n':521,'o':549,'p':549,'q':521,'r':549,'s':603,'t':439,'u':576,'v':713,'w':686,'x':493,'y':686,'z':494,'{':480,'|':200,'}':480,'~':549,'\x7f':0,'\x80':0,'\x81':0,'\x82':0,'\x83':0, + '\x84':0,'\x85':0,'\x86':0,'\x87':0,'\x88':0,'\x89':0,'\x8a':0,'\x8b':0,'\x8c':0,'\x8d':0,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0, + '\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':750,'\xa1':620,'\xa2':247,'\xa3':549,'\xa4':167,'\xa5':713,'\xa6':500,'\xa7':753,'\xa8':753,'\xa9':753,'\xaa':753,'\xab':1042,'\xac':987,'\xad':603,'\xae':987,'\xaf':603, + '\xb0':400,'\xb1':549,'\xb2':411,'\xb3':549,'\xb4':549,'\xb5':713,'\xb6':494,'\xb7':460,'\xb8':549,'\xb9':549,'\xba':549,'\xbb':549,'\xbc':1000,'\xbd':603,'\xbe':1000,'\xbf':658,'\xc0':823,'\xc1':686,'\xc2':795,'\xc3':987,'\xc4':768,'\xc5':768, + '\xc6':823,'\xc7':768,'\xc8':768,'\xc9':713,'\xca':713,'\xcb':713,'\xcc':713,'\xcd':713,'\xce':713,'\xcf':713,'\xd0':768,'\xd1':713,'\xd2':790,'\xd3':790,'\xd4':890,'\xd5':823,'\xd6':549,'\xd7':250,'\xd8':713,'\xd9':603,'\xda':603,'\xdb':1042, + '\xdc':987,'\xdd':603,'\xde':987,'\xdf':603,'\xe0':494,'\xe1':329,'\xe2':790,'\xe3':790,'\xe4':786,'\xe5':713,'\xe6':384,'\xe7':384,'\xe8':384,'\xe9':384,'\xea':384,'\xeb':384,'\xec':494,'\xed':494,'\xee':494,'\xef':494,'\xf0':0,'\xf1':329, + '\xf2':274,'\xf3':686,'\xf4':686,'\xf5':686,'\xf6':384,'\xf7':384,'\xf8':384,'\xf9':384,'\xfa':384,'\xfb':384,'\xfc':494,'\xfd':494,'\xfe':494,'\xff':0} + +fpdf_charwidths['times']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':408,'#':500,'$':500,'%':833,'&':778,'\'':180,'(':333,')':333,'*':500,'+':564, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':564,'=':564,'>':564,'?':444,'@':921,'A':722, + 'B':667,'C':667,'D':722,'E':611,'F':556,'G':722,'H':722,'I':333,'J':389,'K':722,'L':611,'M':889,'N':722,'O':722,'P':556,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':722,'W':944, + 'X':722,'Y':722,'Z':611,'[':333,'\\':278,']':333,'^':469,'_':500,'`':333,'a':444,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':500,'i':278,'j':278,'k':500,'l':278,'m':778, + 'n':500,'o':500,'p':500,'q':500,'r':333,'s':389,'t':278,'u':500,'v':500,'w':722,'x':500,'y':500,'z':444,'{':480,'|':200,'}':480,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':444,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':889,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':444,'\x94':444,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':980, + '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':200,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':564,'\xad':333,'\xae':760,'\xaf':333, + '\xb0':400,'\xb1':564,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':453,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':444,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':564,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':722,'\xde':556,'\xdf':500,'\xe0':444,'\xe1':444,'\xe2':444,'\xe3':444,'\xe4':444,'\xe5':444,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':564,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':500,'\xfe':500,'\xff':500} + +fpdf_charwidths['timesB']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':555,'#':500,'$':500,'%':1000,'&':833,'\'':278,'(':333,')':333,'*':500,'+':570, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':930,'A':722, + 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':778,'I':389,'J':500,'K':778,'L':667,'M':944,'N':722,'O':778,'P':611,'Q':778,'R':722,'S':556,'T':667,'U':722,'V':722,'W':1000, + 'X':722,'Y':722,'Z':667,'[':333,'\\':278,']':333,'^':581,'_':500,'`':333,'a':500,'b':556,'c':444,'d':556,'e':444,'f':333,'g':500,'h':556,'i':278,'j':333,'k':556,'l':278,'m':833, + 'n':556,'o':500,'p':556,'q':556,'r':444,'s':389,'t':333,'u':556,'v':500,'w':722,'x':500,'y':500,'z':444,'{':394,'|':220,'}':394,'~':520,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':667,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':300,'\xab':500,'\xac':570,'\xad':333,'\xae':747,'\xaf':333, + '\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':556,'\xb6':540,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':330,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, + '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':570,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':722,'\xde':611,'\xdf':556,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} + +fpdf_charwidths['timesBI']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':389,'"':555,'#':500,'$':500,'%':833,'&':778,'\'':278,'(':333,')':333,'*':500,'+':570, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':832,'A':667, + 'B':667,'C':667,'D':722,'E':667,'F':667,'G':722,'H':778,'I':389,'J':500,'K':667,'L':611,'M':889,'N':722,'O':722,'P':611,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':667,'W':889, + 'X':667,'Y':611,'Z':611,'[':333,'\\':278,']':333,'^':570,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':556,'i':278,'j':278,'k':500,'l':278,'m':778, + 'n':556,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':556,'v':444,'w':667,'x':500,'y':444,'z':389,'{':348,'|':220,'}':348,'~':570,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000, + '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':389,'\x9f':611,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':266,'\xab':500,'\xac':606,'\xad':333,'\xae':747,'\xaf':333, + '\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':576,'\xb6':500,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':300,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, + '\xc6':944,'\xc7':667,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':570,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':611,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':444,'\xfe':500,'\xff':444} + +fpdf_charwidths['timesI']={ + '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, + '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':420,'#':500,'$':500,'%':833,'&':778,'\'':214,'(':333,')':333,'*':500,'+':675, + ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':675,'=':675,'>':675,'?':500,'@':920,'A':611, + 'B':611,'C':667,'D':722,'E':611,'F':611,'G':722,'H':722,'I':333,'J':444,'K':667,'L':556,'M':833,'N':667,'O':722,'P':611,'Q':722,'R':611,'S':500,'T':556,'U':722,'V':611,'W':833, + 'X':611,'Y':556,'Z':556,'[':389,'\\':278,']':389,'^':422,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':278,'g':500,'h':500,'i':278,'j':278,'k':444,'l':278,'m':722, + 'n':500,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':500,'v':444,'w':667,'x':444,'y':444,'z':389,'{':400,'|':275,'}':400,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, + '\x84':556,'\x85':889,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':500,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':556,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':556,'\x94':556,'\x95':350,'\x96':500,'\x97':889,'\x98':333,'\x99':980, + '\x9a':389,'\x9b':333,'\x9c':667,'\x9d':350,'\x9e':389,'\x9f':556,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':275,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':675,'\xad':333,'\xae':760,'\xaf':333, + '\xb0':400,'\xb1':675,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':523,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':611,'\xc1':611,'\xc2':611,'\xc3':611,'\xc4':611,'\xc5':611, + '\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':667,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':675,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, + '\xdc':722,'\xdd':556,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500, + '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':675,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':444,'\xfe':500,'\xff':444} + +fpdf_charwidths['zapfdingbats']={ + '\x00':0,'\x01':0,'\x02':0,'\x03':0,'\x04':0,'\x05':0,'\x06':0,'\x07':0,'\x08':0,'\t':0,'\n':0,'\x0b':0,'\x0c':0,'\r':0,'\x0e':0,'\x0f':0,'\x10':0,'\x11':0,'\x12':0,'\x13':0,'\x14':0,'\x15':0, + '\x16':0,'\x17':0,'\x18':0,'\x19':0,'\x1a':0,'\x1b':0,'\x1c':0,'\x1d':0,'\x1e':0,'\x1f':0,' ':278,'!':974,'"':961,'#':974,'$':980,'%':719,'&':789,'\'':790,'(':791,')':690,'*':960,'+':939, + ',':549,'-':855,'.':911,'/':933,'0':911,'1':945,'2':974,'3':755,'4':846,'5':762,'6':761,'7':571,'8':677,'9':763,':':760,';':759,'<':754,'=':494,'>':552,'?':537,'@':577,'A':692, + 'B':786,'C':788,'D':788,'E':790,'F':793,'G':794,'H':816,'I':823,'J':789,'K':841,'L':823,'M':833,'N':816,'O':831,'P':923,'Q':744,'R':723,'S':749,'T':790,'U':792,'V':695,'W':776, + 'X':768,'Y':792,'Z':759,'[':707,'\\':708,']':682,'^':701,'_':826,'`':815,'a':789,'b':789,'c':707,'d':687,'e':696,'f':689,'g':786,'h':787,'i':713,'j':791,'k':785,'l':791,'m':873, + 'n':761,'o':762,'p':762,'q':759,'r':759,'s':892,'t':892,'u':788,'v':784,'w':438,'x':138,'y':277,'z':415,'{':392,'|':392,'}':668,'~':668,'\x7f':0,'\x80':390,'\x81':390,'\x82':317,'\x83':317, + '\x84':276,'\x85':276,'\x86':509,'\x87':509,'\x88':410,'\x89':410,'\x8a':234,'\x8b':234,'\x8c':334,'\x8d':334,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0, + '\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':0,'\xa1':732,'\xa2':544,'\xa3':544,'\xa4':910,'\xa5':667,'\xa6':760,'\xa7':760,'\xa8':776,'\xa9':595,'\xaa':694,'\xab':626,'\xac':788,'\xad':788,'\xae':788,'\xaf':788, + '\xb0':788,'\xb1':788,'\xb2':788,'\xb3':788,'\xb4':788,'\xb5':788,'\xb6':788,'\xb7':788,'\xb8':788,'\xb9':788,'\xba':788,'\xbb':788,'\xbc':788,'\xbd':788,'\xbe':788,'\xbf':788,'\xc0':788,'\xc1':788,'\xc2':788,'\xc3':788,'\xc4':788,'\xc5':788, + '\xc6':788,'\xc7':788,'\xc8':788,'\xc9':788,'\xca':788,'\xcb':788,'\xcc':788,'\xcd':788,'\xce':788,'\xcf':788,'\xd0':788,'\xd1':788,'\xd2':788,'\xd3':788,'\xd4':894,'\xd5':838,'\xd6':1016,'\xd7':458,'\xd8':748,'\xd9':924,'\xda':748,'\xdb':918, + '\xdc':927,'\xdd':928,'\xde':928,'\xdf':834,'\xe0':873,'\xe1':828,'\xe2':924,'\xe3':924,'\xe4':917,'\xe5':930,'\xe6':931,'\xe7':463,'\xe8':883,'\xe9':836,'\xea':836,'\xeb':867,'\xec':867,'\xed':696,'\xee':696,'\xef':874,'\xf0':0,'\xf1':874, + '\xf2':760,'\xf3':946,'\xf4':771,'\xf5':865,'\xf6':771,'\xf7':888,'\xf8':967,'\xf9':888,'\xfa':831,'\xfb':873,'\xfc':927,'\xfd':970,'\xfe':918,'\xff':0} + diff --git a/gluon/contrib/pyfpdf/fpdf.py b/gluon/contrib/pyfpdf/fpdf.py index fec42f03..dd8d2a7f 100644 --- a/gluon/contrib/pyfpdf/fpdf.py +++ b/gluon/contrib/pyfpdf/fpdf.py @@ -1,20 +1,27 @@ #!/usr/bin/env python # -*- coding: latin-1 -*- -# ****************************************************************************** -# * Software: FPDF for python * -# * Version: 1.54c * -# * Date: 2010-09-10 * -# * License: LGPL v3.0 * -# * * -# * Original Author (PHP): Olivier PLATHEY 2004-12-31 * -# * Ported to Python 2.4 by Max (maxpat78@yahoo.it) on 2006-05 * -# * Maintainer: Mariano Reingart (reingart@gmail.com) et al since 2008 (est.) * -# * NOTE: 'I' and 'D' destinations are disabled, and simply print to STDOUT * -# *****************************************************************************/ +# **************************************************************************** +# * Software: FPDF for python * +# * Version: 1.7.1 * +# * Date: 2010-09-10 * +# * Last update: 2012-08-16 * +# * License: LGPL v3.0 * +# * * +# * Original Author (PHP): Olivier PLATHEY 2004-12-31 * +# * Ported to Python 2.4 by Max (maxpat78@yahoo.it) on 2006-05 * +# * Maintainer: Mariano Reingart (reingart@gmail.com) et al since 2008 est. * +# * NOTE: 'I' and 'D' destinations are disabled, and simply print to STDOUT * +# **************************************************************************** from datetime import datetime import math -import os, sys, zlib, struct +import errno +import os, sys, zlib, struct, re, tempfile, struct + +try: + import cPickle as pickle +except ImportError: + import pickle try: # Check if PIL is available, necessary for JPEG support. @@ -22,115 +29,62 @@ try: except ImportError: Image = None -def substr(s, start, length=-1): - if length < 0: - length=len(s)-start - return s[start:start+length] -def sprintf(fmt, *args): return fmt % args +from ttfonts import TTFontFile +from fonts import fpdf_charwidths +from php import substr, sprintf, print_r, UTF8ToUTF16BE, UTF8StringToArray + # Global variables -FPDF_VERSION='1.54b' -FPDF_FONT_DIR=os.path.join(os.path.dirname(__file__),'font') -fpdf_charwidths = {} +FPDF_VERSION = '1.7.1' +FPDF_FONT_DIR = os.path.join(os.path.dirname(__file__),'font') +SYSTEM_TTFONTS = None -class FPDF: -#Private properties -#~ page; #current page number -#~ n; #current object number -#~ offsets; #array of object offsets -#~ buffer; #buffer holding in-memory PDF -#~ pages; #array containing pages -#~ state; #current document state -#~ compress; #compression flag -#~ def_orientation; #default orientation -#~ cur_orientation; #current orientation -#~ orientation_changes; #array indicating orientation changes -#~ k; #scale factor (number of points in user unit) -#~ fw_pt,fh_pt; #dimensions of page format in points -#~ fw,fh; #dimensions of page format in user unit -#~ w_pt,h_pt; #current dimensions of page in points -#~ w,h; #current dimensions of page in user unit -#~ l_margin; #left margin -#~ t_margin; #top margin -#~ r_margin; #right margin -#~ b_margin; #page break margin -#~ c_margin; #cell margin -#~ x,y; #current position in user unit for cell positioning -#~ lasth; #height of last cell printed -#~ line_width; #line width in user unit -#~ core_fonts; #array of standard font names -#~ fonts; #array of used fonts -#~ font_files; #array of font files -#~ diffs; #array of encoding differences -#~ images; #array of used images -#~ page_links; #array of links in pages -#~ links; #array of internal links -#~ font_family; #current font family -#~ font_style; #current font style -#~ underline; #underlining flag -#~ current_font; #current font info -#~ font_size_pt; #current font size in points -#~ font_size; #current font size in user unit -#~ draw_color; #commands for drawing color -#~ fill_color; #commands for filling color -#~ text_color; #commands for text color -#~ color_flag; #indicates whether fill and text colors are different -#~ ws; #word spacing -#~ auto_page_break; #automatic page breaking -#~ page_break_trigger; #threshold used to trigger page breaks -#~ in_footer; #flag set when processing footer -#~ zoom_mode; #zoom display mode -#~ layout_mode; #layout display mode -#~ title; #title -#~ subject; #subject -#~ author; #author -#~ keywords; #keywords -#~ creator; #creator -#~ alias_nb_pages; #alias for total number of pages -#~ pdf_version; #PDF version number +PY3K = sys.version_info >= (3, 0) -# ****************************************************************************** -# * * -# * Public methods * -# * * -# *******************************************************************************/ +def set_global(var, val): + globals()[var] = val + + +class FPDF(object): + "PDF Generation class" + def __init__(self, orientation='P',unit='mm',format='A4'): - #Some checks + # Some checks self._dochecks() - #Initialization of properties - self.offsets={} - self.page=0 - self.n=2 - self.buffer='' - self.pages={} - self.orientation_changes={} - self.state=0 - self.fonts={} - self.font_files={} - self.diffs={} - self.images={} - self.page_links={} - self.links={} - self.in_footer=0 + # Initialization of properties + self.offsets={} # array of object offsets + self.page=0 # current page number + self.n=2 # current object number + self.buffer='' # buffer holding in-memory PDF + self.pages={} # array containing pages + self.orientation_changes={} # array indicating orientation changes + self.state=0 # current document state + self.fonts={} # array of used fonts + self.font_files={} # array of font files + self.diffs={} # array of encoding differences + self.images={} # array of used images + self.page_links={} # array of links in pages + self.links={} # array of internal links + self.in_footer=0 # flag set when processing footer self.lastw=0 - self.lasth=0 - self.font_family='' - self.font_style='' - self.font_size_pt=12 - self.underline=0 + self.lasth=0 # height of last cell printed + self.font_family='' # current font family + self.font_style='' # current font style + self.font_size_pt=12 # current font size in points + self.underline=0 # underlining flag self.draw_color='0 G' self.fill_color='0 g' self.text_color='0 g' - self.color_flag=0 - self.ws=0 + self.color_flag=0 # indicates whether fill and text colors are different + self.ws=0 # word spacing self.angle=0 - #Standard fonts + # Standard fonts self.core_fonts={'courier':'Courier','courierB':'Courier-Bold','courierI':'Courier-Oblique','courierBI':'Courier-BoldOblique', 'helvetica':'Helvetica','helveticaB':'Helvetica-Bold','helveticaI':'Helvetica-Oblique','helveticaBI':'Helvetica-BoldOblique', 'times':'Times-Roman','timesB':'Times-Bold','timesI':'Times-Italic','timesBI':'Times-BoldItalic', 'symbol':'Symbol','zapfdingbats':'ZapfDingbats'} - #Scale factor + # Scale factor if(unit=='pt'): self.k=1 elif(unit=='mm'): @@ -141,7 +95,7 @@ class FPDF: self.k=72 else: self.error('Incorrect unit: '+unit) - #Page format + # Page format if(isinstance(format,basestring)): format=format.lower() if(format=='a3'): @@ -163,7 +117,7 @@ class FPDF: self.fh_pt=format[1]*self.k self.fw=self.fw_pt/self.k self.fh=self.fh_pt/self.k - #Page orientation + # Page orientation orientation=orientation.lower() if(orientation=='p' or orientation=='portrait'): self.def_orientation='P' @@ -178,20 +132,20 @@ class FPDF: self.cur_orientation=self.def_orientation self.w=self.w_pt/self.k self.h=self.h_pt/self.k - #Page margins (1 cm) + # Page margins (1 cm) margin=28.35/self.k self.set_margins(margin,margin) - #Interior cell margin (1 mm) + # Interior cell margin (1 mm) self.c_margin=margin/10.0 - #line width (0.2 mm) + # line width (0.2 mm) self.line_width=.567/self.k - #Automatic page break + # Automatic page break self.set_auto_page_break(1,2*margin) - #Full width display mode + # Full width display mode self.set_display_mode('fullwidth') - #Enable compression + # Enable compression self.set_compression(1) - #Set default PDF version number + # Set default PDF version number self.pdf_version='1.3' def set_margins(self, left,top,right=-1): @@ -389,8 +343,20 @@ class FPDF: cw=self.current_font['cw'] w=0 l=len(s) - for i in xrange(0, l): - w += cw.get(s[i],0) + if self.unifontsubset: + for char in s: + char = ord(char) + if len(cw) > char: + w += cw[char] # ord(cw[2*char])<<8 + ord(cw[2*char+1]) + #elif (char>0 and char<128 and isset($cw[chr($char)])) { $w += $cw[chr($char)]; } + elif (self.current_font['desc']['MissingWidth']) : + w += self.current_font['desc']['MissingWidth'] + #elif (isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; } + else: + w += 500 + else: + for i in xrange(0, l): + w += cw.get(s[i],0) return w*self.font_size/1000.0 def set_line_width(self, width): @@ -413,42 +379,119 @@ class FPDF: op='S' self._out(sprintf('%.2f %.2f %.2f %.2f re %s',x*self.k,(self.h-y)*self.k,w*self.k,-h*self.k,op)) - def add_font(self, family,style='',fname=''): + def add_font(self, family, style='', fname='', uni=False): "Add a TrueType or Type1 font" - family=family.lower() - if(fname==''): - fname=family.replace(' ','')+style.lower()+'.font' - fname=os.path.join(FPDF_FONT_DIR,fname) - if(family=='arial'): - family='helvetica' - style=style.upper() - if(style=='IB'): - style='BI' - fontkey=family+style + family = family.lower() + if (fname == ''): + fname = family.replace(' ','') + style.lower() + '.pkl' + if (family == 'arial'): + family = 'helvetica' + style = style.upper() + if (style == 'IB'): + style = 'BI' + fontkey = family+style if fontkey in self.fonts: - self.error('Font already added: '+family+' '+style) - execfile(fname, globals(), globals()) - if 'name' not in globals(): - self.error('Could not include font definition file') - i=len(self.fonts)+1 - self.fonts[fontkey]={'i':i,'type':type,'name':name,'desc':desc,'up':up,'ut':ut,'cw':cw,'enc':enc,'file':filename} - if(diff): - #Search existing encodings - d=0 - nb=len(self.diffs) - for i in xrange(1,nb+1): - if(self.diffs[i]==diff): - d=i - break - if(d==0): - d=nb+1 - self.diffs[d]=diff - self.fonts[fontkey]['diff']=d - if(filename): - if(type=='TrueType'): - self.font_files[filename]={'length1':originalsize} + # Font already added! + return + if (uni): + global SYSTEM_TTFONTS + if os.path.exists(fname): + ttffilename = fname + elif (FPDF_FONT_DIR and + os.path.exists(os.path.join(FPDF_FONT_DIR, fname))): + ttffilename = os.path.join(FPDF_FONT_DIR, fname) + elif (SYSTEM_TTFONTS and + os.path.exists(os.path.join(SYSTEM_TTFONTS, fname))): + ttffilename = os.path.join(SYSTEM_TTFONTS, fname) else: - self.font_files[filename]={'length1':size1,'length2':size2} + raise RuntimeError("TTF Font file not found: %s" % fname) + unifilename = os.path.splitext(ttffilename)[0] + '.pkl' + name = '' + if os.path.exists(unifilename): + fh = open(unifilename) + try: + font_dict = pickle.load(fh) + finally: + fh.close() + else: + ttf = TTFontFile() + ttf.getMetrics(ttffilename) + desc = { + 'Ascent': int(round(ttf.ascent, 0)), + 'Descent': int(round(ttf.descent, 0)), + 'CapHeight': int(round(ttf.capHeight, 0)), + 'Flags': ttf.flags, + 'FontBBox': "[%s %s %s %s]" % ( + int(round(ttf.bbox[0], 0)), + int(round(ttf.bbox[1], 0)), + int(round(ttf.bbox[2], 0)), + int(round(ttf.bbox[3], 0))), + 'ItalicAngle': int(ttf.italicAngle), + 'StemV': int(round(ttf.stemV, 0)), + 'MissingWidth': int(round(ttf.defaultWidth, 0)), + } + # Generate metrics .pkl file + font_dict = { + 'name': re.sub('[ ()]', '', ttf.fullName), + 'type': 'TTF', + 'desc': desc, + 'up': round(ttf.underlinePosition), + 'ut': round(ttf.underlineThickness), + 'ttffile': ttffilename, + 'fontkey': fontkey, + 'originalsize': os.stat(ttffilename).st_size, + 'cw': ttf.charWidths, + } + try: + fh = open(unifilename, "w") + pickle.dump(font_dict, fh) + fh.close() + except IOError as e: + if not e.errno == errno.EACCES: + raise # Not a permission error. + del ttf + if hasattr(self,'str_alias_nb_pages'): + sbarr = range(0,57) # include numbers in the subset! + else: + sbarr = range(0,32) + self.fonts[fontkey] = { + 'i': len(self.fonts)+1, 'type': font_dict['type'], + 'name': font_dict['name'], 'desc': font_dict['desc'], + 'up': font_dict['up'], 'ut': font_dict['ut'], + 'cw': font_dict['cw'], + 'ttffile': font_dict['ttffile'], 'fontkey': fontkey, + 'subset': sbarr, 'unifilename': unifilename, + } + self.font_files[fontkey] = {'length1': font_dict['originalsize'], + 'type': "TTF", 'ttffile': ttffilename} + self.font_files[fname] = {'type': "TTF"} + else: + fontfile = open(fname) + try: + font_dict = pickle.load(fontfile) + finally: + fontfile.close() + self.fonts[fontkey] = {'i': len(self.fonts)+1} + self.fonts[fontkey].update(font_dict) + if (diff): + #Search existing encodings + d = 0 + nb = len(self.diffs) + for i in xrange(1, nb+1): + if(self.diffs[i] == diff): + d = i + break + if (d == 0): + d = nb + 1 + self.diffs[d] = diff + self.fonts[fontkey]['diff'] = d + filename = font_dict.get('filename') + if (filename): + if (type == 'TrueType'): + self.font_files[filename]={'length1': originalsize} + else: + self.font_files[filename]={'length1': size1, + 'length2': size2} def set_font(self, family,style='',size=0): "Select a font; size given in points" @@ -495,6 +538,7 @@ class FPDF: self.font_size_pt=size self.font_size=size/self.k self.current_font=self.fonts[fontkey] + self.unifontsubset = (self.fonts[fontkey]['type'] == 'TTF') if(self.page>0): self._out(sprintf('BT /F%d %.2f Tf ET',self.current_font['i'],self.font_size_pt)) @@ -527,9 +571,16 @@ class FPDF: self.page_links[self.page] = [] self.page_links[self.page] += [(x*self.k,self.h_pt-y*self.k,w*self.k,h*self.k,link),] - def text(self, x,y,txt): + def text(self, x, y, txt=''): "Output a string" - s=sprintf('BT %.2f %.2f Td (%s) Tj ET',x*self.k,(self.h-y)*self.k,self._escape(txt)) + txt = self.normalize_text(txt) + if (self.unifontsubset): + txt2 = self._escape(UTF8ToUTF16BE(txt, False)) + for uni in UTF8StringToArray(txt): + self.current_font['subset'].append(uni) + else: + txt2 = self._escape(txt) + s=sprintf('BT %.2f %.2f Td (%s) Tj ET',x*self.k,(self.h-y)*self.k, txt2) if(self.underline and txt!=''): s+=' '+self._dounderline(x,y,txt) if(self.color_flag): @@ -559,6 +610,7 @@ class FPDF: def cell(self, w,h=0,txt='',border=0,ln=0,align='',fill=0,link=''): "Output a cell" + txt = self.normalize_text(txt) k=self.k if(self.y+h>self.page_break_trigger and not self.in_footer and self.accept_page_break()): #Automatic page break @@ -604,8 +656,33 @@ class FPDF: dx=self.c_margin if(self.color_flag): s+='q '+self.text_color+' ' - txt2=txt.replace('\\','\\\\').replace(')','\\)').replace('(','\\(') - s+=sprintf('BT %.2f %.2f Td (%s) Tj ET',(self.x+dx)*k,(self.h-(self.y+.5*h+.3*self.font_size))*k,txt2) + + # If multibyte, Tw has no effect - do word spacing using an adjustment before each space + if (self.ws and self.unifontsubset): + for uni in UTF8StringToArray(txt): + self.current_font['subset'].append(uni) + space = self._escape(UTF8ToUTF16BE(' ', False)) + s += sprintf('BT 0 Tw %.2F %.2F Td [',(self.x + dx) * k,(self.h - (self.y + 0.5*h+ 0.3 * self.font_size)) * k) + t = txt.split(' ') + numt = len(t) + for i in range(numt): + tx = t[i] + tx = '(' + self._escape(UTF8ToUTF16BE(tx, False)) + ')' + s += sprintf('%s ', tx); + if ((i+1)0): self.ws=0 - self._out('0 Tw') + if not split_only: + self._out('0 Tw') if not split_only: self.cell(w,h,substr(s,j,i-j),b,2,align,fill) else: @@ -681,7 +760,10 @@ class FPDF: sep=i ls=l ns+=1 - l+=cw.get(c,0) + if self.unifontsubset: + l += self.get_string_width(c) / self.font_size*1000.0 + else: + l += cw.get(c,0) if(l>wmax): #Automatic line break if(sep==-1): @@ -689,7 +771,8 @@ class FPDF: i+=1 if(self.ws>0): self.ws=0 - self._out('0 Tw') + if not split_only: + self._out('0 Tw') if not split_only: self.cell(w,h,substr(s,j,i-j),b,2,align,fill) else: @@ -700,7 +783,8 @@ class FPDF: self.ws=(wmax-ls)/1000.0*self.font_size/(ns-1) else: self.ws=0 - self._out(sprintf('%.3f Tw',self.ws*self.k)) + if not split_only: + self._out(sprintf('%.3f Tw',self.ws*self.k)) if not split_only: self.cell(w,h,substr(s,j,sep-j),b,2,align,fill) else: @@ -718,18 +802,20 @@ class FPDF: #Last chunk if(self.ws>0): self.ws=0 - self._out('0 Tw') + if not split_only: + self._out('0 Tw') if(border and 'B' in border): b+='B' if not split_only: self.cell(w,h,substr(s,j,i-j),b,2,align,fill) + self.x=self.l_margin else: ret.append(substr(s,j,i-j)) - self.x=self.l_margin return ret - def write(self, h,txt,link=''): + def write(self, h, txt='', link=''): "Output text in flowing mode" + txt = self.normalize_text(txt) cw=self.current_font['cw'] w=self.w-self.r_margin-self.x wmax=(w-2*self.c_margin)*1000.0/self.font_size @@ -758,7 +844,10 @@ class FPDF: continue if(c==' '): sep=i - l+=cw.get(c,0) + if self.unifontsubset: + l += self.get_string_width(c) / self.font_size*1000.0 + else: + l += cw.get(c,0) if(l>wmax): #Automatic line break if(sep==-1): @@ -791,7 +880,7 @@ class FPDF: if(i!=j): self.cell(l/1000.0*self.font_size,h,substr(s,j),0,0,'',0,link) - def image(self, name,x,y,w=0,h=0,type='',link=''): + def image(self, name, x=None, y=None, w=0,h=0,type='',link=''): "Put an image on the page" if not name in self.images: #First use of image, get info @@ -810,7 +899,7 @@ class FPDF: mtd='_parse'+type if not hasattr(self,mtd): self.error('Unsupported image type: '+type) - info=self.mtd(name) + info=getattr(self, mtd)(name) info['i']=len(self.images)+1 self.images[name]=info else: @@ -820,10 +909,21 @@ class FPDF: #Put image at 72 dpi w=info['w']/self.k h=info['h']/self.k - if(w==0): + elif(w==0): w=h*info['w']/info['h'] - if(h==0): + elif(h==0): h=w*info['h']/info['w'] + # Flowing mode + if y is None: + if (self.y + h > self.page_break_trigger and not self.in_footer and self.accept_page_break()): + #Automatic page break + x = self.x + self.add_page(self.cur_orientation) + self.x = x + y = self.y + self.y += h + if x is None: + x = self.x self._out(sprintf('q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q',w*self.k,h*self.k,x*self.k,(self.h-(y+h))*self.k,info['i'])) if(link): self.link(x,y,w,h,link) @@ -869,12 +969,6 @@ class FPDF: #Finish document if necessary if(self.state<3): self.close() - #Normalize parameters - # if(type(dest)==type(bool())): - # if dest: - # dest='D' - # else: - # dest='F' dest=dest.upper() if(dest==''): if(name==''): @@ -888,10 +982,14 @@ class FPDF: print self.buffer elif dest=='F': #Save to local file - f=file(name,'wb') + f=open(name,'wb') if(not f): self.error('Unable to create output file: '+name) - f.write(self.buffer) + if PY3K: + # TODO: proper unicode support + f.write(self.buffer.encode("latin1")) + else: + f.write(self.buffer) f.close() elif dest=='S': #Return as a string @@ -900,11 +998,17 @@ class FPDF: self.error('Incorrect output destination: '+dest) return '' -# ****************************************************************************** -# * * -# * Protected methods * -# * * -# *******************************************************************************/ + def normalize_text(self, txt): + "Check that text input is in the correct format/encoding" + # - for TTF unicode fonts: unicode object (utf8 encoding) + # - for built-in fonts: string instances (latin 1 encoding) + if self.unifontsubset and isinstance(txt, str): + txt = txt.decode('utf8') + elif not self.unifontsubset and isinstance(txt, unicode) and not PY3K: + txt = txt.encode('latin1') + return txt + + def _dochecks(self): #Check for locale-related bug # if(1.1==1): @@ -920,7 +1024,12 @@ class FPDF: def _putpages(self): nb=self.page if hasattr(self,'str_alias_nb_pages'): - #Replace number of pages + # Replace number of pages in fonts using subsets (unicode) + alias = UTF8ToUTF16BE(self.str_alias_nb_pages, False); + r = UTF8ToUTF16BE(str(nb), False) + for n in xrange(1, nb+1): + self.pages[n] = self.pages[n].replace(alias, r) + # Now repeat for no pages in non-subset fonts for n in xrange(1,nb+1): self.pages[n]=self.pages[n].replace(self.str_alias_nb_pages,str(nb)) if(self.def_orientation=='P'): @@ -957,6 +1066,8 @@ class FPDF: h=h_pt annots+=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*l[0],h-l[1]*self.k) self._out(annots+']') + if(self.pdf_version>'1.3'): + self._out('/Group <>') self._out('/Contents '+str(self.n+1)+' 0 R>>') self._out('endobj') #Page content @@ -989,33 +1100,34 @@ class FPDF: self._out('<>') self._out('endobj') for name,info in self.font_files.iteritems(): - #Font file embedding - self._newobj() - self.font_files[name]['n']=self.n - font='' - f=file(self._getfontpath()+name,'rb',1) - if(not f): - self.error('Font file not found') - font=f.read() - f.close() - compressed=(substr(name,-2)=='.z') - if(not compressed and 'length2' in info): - header=(ord(font[0])==128) - if(header): - #Strip first binary header - font=substr(font,6) - if(header and ord(font[info['length1']])==128): - #Strip second binary header - font=substr(font,0,info['length1'])+substr(font,info['length1']+6) - self._out('<>') - self._putstream(font) - self._out('endobj') + if 'type' in info and info['type'] != 'TTF': + #Font file embedding + self._newobj() + self.font_files[name]['n']=self.n + font='' + f=open(self._getfontpath()+name,'rb',1) + if(not f): + self.error('Font file not found') + font=f.read() + f.close() + compressed=(substr(name,-2)=='.z') + if(not compressed and 'length2' in info): + header=(ord(font[0])==128) + if(header): + #Strip first binary header + font=substr(font,6) + if(header and ord(font[info['length1']])==128): + #Strip second binary header + font=substr(font,0,info['length1'])+substr(font,info['length1']+6) + self._out('<>') + self._putstream(font) + self._out('endobj') for k,font in self.fonts.iteritems(): #Font objects self.fonts[k]['n']=self.n+1 @@ -1059,8 +1171,8 @@ class FPDF: #Descriptor self._newobj() s='<>') self._out('endobj') + elif (type == 'TTF'): + self.fonts[k]['n'] = self.n + 1 + ttf = TTFontFile() + fontname = 'MPDFAA' + '+' + font['name'] + subset = font['subset'] + del subset[0] + ttfontstream = ttf.makeSubset(font['ttffile'], subset) + ttfontsize = len(ttfontstream) + fontstream = zlib.compress(ttfontstream) + codeToGlyph = ttf.codeToGlyph + ##del codeToGlyph[0] + # Type0 Font + # A composite font - a font composed of other fonts, organized hierarchically + self._newobj() + self._out('<>') + self._out('endobj') + + # CIDFontType2 + # A CIDFont whose glyph descriptions are based on TrueType font technology + self._newobj() + self._out('<>') + self._out('endobj') + + # ToUnicode + self._newobj() + toUni = "/CIDInit /ProcSet findresource begin\n" \ + "12 dict begin\n" \ + "begincmap\n" \ + "/CIDSystemInfo\n" \ + "<> def\n" \ + "/CMapName /Adobe-Identity-UCS def\n" \ + "/CMapType 2 def\n" \ + "1 begincodespacerange\n" \ + "<0000> \n" \ + "endcodespacerange\n" \ + "1 beginbfrange\n" \ + "<0000> <0000>\n" \ + "endbfrange\n" \ + "endcmap\n" \ + "CMapName currentdict /CMap defineresource pop\n" \ + "end\n" \ + "end" + self._out('<>') + self._putstream(toUni) + self._out('endobj') + + # CIDSystemInfo dictionary + self._newobj() + self._out('<>') + self._out('endobj') + + # Font descriptor + self._newobj() + self._out('<>') + self._out('endobj') + + # Embed CIDToGIDMap + # A specification of the mapping from CIDs to glyph indices + cidtogidmap = ''; + cidtogidmap = ["\x00"] * 256*256*2 + for cc, glyph in codeToGlyph.items(): + cidtogidmap[cc*2] = chr(glyph >> 8) + cidtogidmap[cc*2 + 1] = chr(glyph & 0xFF) + cidtogidmap = zlib.compress(''.join(cidtogidmap)); + self._newobj() + self._out('<>') + self._putstream(cidtogidmap) + self._out('endobj') + + #Font file + self._newobj() + self._out('<>') + self._putstream(fontstream) + self._out('endobj') + del ttf else: #Allow for additional types mtd='_put'+type.lower() @@ -1076,13 +1298,121 @@ class FPDF: self.error('Unsupported font type: '+type) self.mtd(font) + def _putTTfontwidths(self, font, maxUni): + cw127fname = os.path.splitext(font['unifilename'])[0] + '.cw127.pkl' + if (os.path.exists(cw127fname)): + fh = open(cw127fname); + try: + font_dict = pickle.load(fh) + finally: + fh.close() + rangeid = font_dict['rangeid'] + range_ = font_dict['range'] + prevcid = font_dict['prevcid'] + prevwidth = font_dict['prevwidth'] + interval = font_dict['interval'] + range_interval = font_dict['range_interval'] + startcid = 128 + else: + rangeid = 0 + range_ = {} + range_interval = {} + prevcid = -2 + prevwidth = -1 + interval = False + startcid = 1 + cwlen = maxUni + 1 + + # for each character + for cid in range(startcid, cwlen): + if (cid==128 and not os.path.exists(cw127fname)): + try: + fh = open(cw127fname, "wb") + font_dict = {} + font_dict['rangeid'] = rangeid + font_dict['prevcid'] = prevcid + font_dict['prevwidth'] = prevwidth + font_dict['interval'] = interval + font_dict['range_interval'] = range_interval + font_dict['range'] = range_ + pickle.dump(font_dict, fh) + fh.close() + except IOError as e: + if not e.errno == errno.EACCES: + raise # Not a permission error. + if (font['cw'][cid] == 0): + continue + width = font['cw'][cid] + if (width == 65535): width = 0 + if (cid > 255 and (cid not in font['subset']) or not cid): # + continue + if ('dw' not in font or (font['dw'] and width != font['dw'])): + if (cid == (prevcid + 1)): + if (width == prevwidth): + if (width == range_[rangeid][0]): + range_.setdefault(rangeid, []).append(width) + else: + range_[rangeid].pop() + # new range + rangeid = prevcid + range_[rangeid] = [prevwidth, width] + interval = True + range_interval[rangeid] = True + else: + if (interval): + # new range + rangeid = cid + range_[rangeid] = [width] + else: + range_[rangeid].append(width) + interval = False + else: + rangeid = cid + range_[rangeid] = [width] + interval = False + prevcid = cid + prevwidth = width + prevk = -1 + nextk = -1 + prevint = False + for k, ws in sorted(range_.items()): + cws = len(ws) + if (k == nextk and not prevint and (not k in range_interval or cws < 3)): + if (k in range_interval): + del range_interval[k] + range_[prevk] = range_[prevk] + range_[k] + del range_[k] + else: + prevk = k + nextk = k + cws + if (k in range_interval): + prevint = (cws > 3) + del range_interval[k] + nextk -= 1 + else: + prevint = False + w = [] + for k, ws in sorted(range_.items()): + if (len(set(ws)) == 1): + w.append(' %s %s %s' % (k, k + len(ws) - 1, ws[0])) + else: + w.append(' %s [ %s ]\n' % (k, ' '.join([str(int(h)) for h in ws]))) ## + self._out('/W [%s]' % ''.join(w)) + def _putimages(self): filter='' if self.compress: filter='/Filter /FlateDecode ' for filename,info in self.images.iteritems(): + self._putimage(info) + del info['data'] + if 'smask' in info: + del info['smask'] + + def _putimage(self, info): + if 'data' in info: self._newobj() - self.images[filename]['n']=self.n + info['n']=self.n self._out('<>') + if('trns' in info and isinstance(info['trns'], list)): trns='' for i in xrange(0,len(info['trns'])): trns+=str(info['trns'][i])+' '+str(info['trns'][i])+' ' self._out('/Mask ['+trns+']') + if('smask' in info): + self._out('/SMask ' + str(self.n+1) + ' 0 R'); self._out('/Length '+str(len(info['data']))+'>>') self._putstream(info['data']) - self.images[filename]['data'] = None self._out('endobj') + # Soft mask + if('smask' in info): + dp = '/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns ' + str(info['w']) + smask = {'w': info['w'], 'h': info['h'], 'cs': 'DeviceGray', 'bpc': 8, 'f': info['f'], 'dp': dp, 'data': info['smask']} + self._putimage(smask) #Palette if(info['cs']=='Indexed'): self._newobj() + filter = self.compress and '/Filter /FlateDecode ' or '' if self.compress: pal=zlib.compress(info['pal']) else: @@ -1288,6 +1625,25 @@ class FPDF: f.close() return {'w':a[0],'h':a[1],'cs':colspace,'bpc':bpc,'f':'DCTDecode','data':data} + def _parsegif(self, filename): + # Extract info from a GIF file (via PNG conversion) + if Image is None: + self.error('PIL is required for GIF support') + try: + im = Image.open(filename) + except Exception, e: + self.error('Missing or incorrect image file: %s. error: %s' % (filename, str(e))) + else: + # Use temporary file + f = tempfile.NamedTemporaryFile(delete=False, suffix=".png") + tmp = f.name + transparency = im.info['transparency'] + f.close() + im.save(tmp, transparency=transparency) + info = self._parsepng(tmp) + os.unlink(tmp) + return info + def _parsepng(self, name): #Extract info from a PNG file if name.startswith("http://") or name.startswith("https://"): @@ -1310,14 +1666,14 @@ class FPDF: if(bpc>8): self.error('16-bit depth not supported: '+name) ct=ord(f.read(1)) - if(ct==0): + if(ct==0 or ct==4): colspace='DeviceGray' - elif(ct==2): + elif(ct==2 or ct==6): colspace='DeviceRGB' elif(ct==3): colspace='Indexed' else: - self.error('Alpha channel not supported: '+name) + self.error('Unknown color type: '+name) if(ord(f.read(1))!=0): self.error('Unknown compression method: '+name) if(ord(f.read(1))!=0): @@ -1325,12 +1681,12 @@ class FPDF: if(ord(f.read(1))!=0): self.error('Interlacing not supported: '+name) f.read(4) - parms='/DecodeParms <>' + dp+='1' + dp+=' /BitsPerComponent '+str(bpc)+' /Columns '+str(w)+'' #Scan chunks looking for palette, transparency and image data pal='' trns='' @@ -1366,7 +1722,39 @@ class FPDF: if(colspace=='Indexed' and not pal): self.error('Missing palette in '+name) f.close() - return {'w':w,'h':h,'cs':colspace,'bpc':bpc,'f':'FlateDecode','parms':parms,'pal':pal,'trns':trns,'data':data} + info = {'w':w,'h':h,'cs':colspace,'bpc':bpc,'f':'FlateDecode','dp':dp,'pal':pal,'trns':trns,} + if(ct>=4): + # Extract alpha channel + data = zlib.decompress(data) + color = ''; + alpha = ''; + if(ct==4): + # Gray image + length = 2*w + for i in range(h): + pos = (1+length)*i + color += data[pos] + alpha += data[pos] + line = substr(data, pos+1, length) + color += re.sub('(.).',lambda m: m.group(1),line, flags=re.DOTALL) + alpha += re.sub('.(.)',lambda m: m.group(1),line, flags=re.DOTALL) + else: + # RGB image + length = 4*w + for i in range(h): + pos = (1+length)*i + color += data[pos] + alpha += data[pos] + line = substr(data, pos+1, length) + color += re.sub('(.{3}).',lambda m: m.group(1),line, flags=re.DOTALL) + alpha += re.sub('.{3}(.)',lambda m: m.group(1),line, flags=re.DOTALL) + del data + data = zlib.compress(color) + info['smask'] = zlib.compress(alpha) + if (self.pdf_version < '1.4'): + self.pdf_version = '1.4' + info['data'] = data + return info def _freadint(self, f): #Read a 4-byte integer from file @@ -1397,44 +1785,34 @@ class FPDF: def interleaved2of5(self, txt, x, y, w=1.0, h=10.0): "Barcode I2of5 (numeric), adds a 0 if odd lenght" - narrow = w / 3.0 + narrow = w / 3.0 wide = w - + # wide/narrow codes for the digits - bar_char={} - bar_char['0'] = 'nnwwn' - bar_char['1'] = 'wnnnw' - bar_char['2'] = 'nwnnw' - bar_char['3'] = 'wwnnn' - bar_char['4'] = 'nnwnw' - bar_char['5'] = 'wnwnn' - bar_char['6'] = 'nwwnn' - bar_char['7'] = 'nnnww' - bar_char['8'] = 'wnnwn' - bar_char['9'] = 'nwnwn' - bar_char['A'] = 'nn' - bar_char['Z'] = 'wn' - + bar_char={'0': 'nnwwn', '1': 'wnnnw', '2': 'nwnnw', '3': 'wwnnn', + '4': 'nnwnw', '5': 'wnwnn', '6': 'nwwnn', '7': 'nnnww', + '8': 'wnnwn', '9': 'nwnwn', 'A': 'nn', 'Z': 'wn'} + self.set_fill_color(0) code = txt # add leading zero if code-length is odd if len(code) % 2 != 0: code = '0' + code - + # add start and stop codes code = 'AA' + code.lower() + 'ZA' for i in xrange(0, len(code), 2): # choose next pair of digits - char_bar = code[i]; - char_space = code[i+1]; + char_bar = code[i] + char_space = code[i+1] # check whether it is a valid digit if not char_bar in bar_char.keys(): - raise RuntimeError ('Caractér "%s" inválido para el código de barras I25: ' % char_bar) + raise RuntimeError ('Char "%s" invalid for I25: ' % char_bar) if not char_space in bar_char.keys(): - raise RuntimeError ('Caractér "%s" inválido para el código de barras I25: ' % char_space) + raise RuntimeError ('Char "%s" invalid for I25: ' % char_space) - # create a wide/narrow-sequence (first digit=bars, second digit=spaces) + # create a wide/narrow-seq (first digit=bars, second digit=spaces) seq = '' for s in xrange(0, len(bar_char[char_bar])): seq += bar_char[char_bar][s] + bar_char[char_space][s] @@ -1446,7 +1824,7 @@ class FPDF: else: line_width = wide - # draw every second value, because the second digit of the pair is represented by the spaces + # draw every second value, the other is represented by space if bar % 2 == 0: self.rect(x, y, line_width, h, 'F') @@ -1456,68 +1834,38 @@ class FPDF: def code39(self, txt, x, y, w=1.5, h=5.0): "Barcode 3of9" wide = w - narrow = w /3.0 + narrow = w / 3.0 gap = narrow - bar_char={} - bar_char['0'] = 'nnnwwnwnn' - bar_char['1'] = 'wnnwnnnnw' - bar_char['2'] = 'nnwwnnnnw' - bar_char['3'] = 'wnwwnnnnn' - bar_char['4'] = 'nnnwwnnnw' - bar_char['5'] = 'wnnwwnnnn' - bar_char['6'] = 'nnwwwnnnn' - bar_char['7'] = 'nnnwnnwnw' - bar_char['8'] = 'wnnwnnwnn' - bar_char['9'] = 'nnwwnnwnn' - bar_char['A'] = 'wnnnnwnnw' - bar_char['B'] = 'nnwnnwnnw' - bar_char['C'] = 'wnwnnwnnn' - bar_char['D'] = 'nnnnwwnnw' - bar_char['E'] = 'wnnnwwnnn' - bar_char['F'] = 'nnwnwwnnn' - bar_char['G'] = 'nnnnnwwnw' - bar_char['H'] = 'wnnnnwwnn' - bar_char['I'] = 'nnwnnwwnn' - bar_char['J'] = 'nnnnwwwnn' - bar_char['K'] = 'wnnnnnnww' - bar_char['L'] = 'nnwnnnnww' - bar_char['M'] = 'wnwnnnnwn' - bar_char['N'] = 'nnnnwnnww' - bar_char['O'] = 'wnnnwnnwn' - bar_char['P'] = 'nnwnwnnwn' - bar_char['Q'] = 'nnnnnnwww' - bar_char['R'] = 'wnnnnnwwn' - bar_char['S'] = 'nnwnnnwwn' - bar_char['T'] = 'nnnnwnwwn' - bar_char['U'] = 'wwnnnnnnw' - bar_char['V'] = 'nwwnnnnnw' - bar_char['W'] = 'wwwnnnnnn' - bar_char['X'] = 'nwnnwnnnw' - bar_char['Y'] = 'wwnnwnnnn' - bar_char['Z'] = 'nwwnwnnnn' - bar_char['-'] = 'nwnnnnwnw' - bar_char['.'] = 'wwnnnnwnn' - bar_char[' '] = 'nwwnnnwnn' - bar_char['*'] = 'nwnnwnwnn' - bar_char['$'] = 'nwnwnwnnn' - bar_char['/'] = 'nwnwnnnwn' - bar_char['+'] = 'nwnnnwnwn' - bar_char['%'] = 'nnnwnwnwn' + bar_char={'0': 'nnnwwnwnn', '1': 'wnnwnnnnw', '2': 'nnwwnnnnw', + '3': 'wnwwnnnnn', '4': 'nnnwwnnnw', '5': 'wnnwwnnnn', + '6': 'nnwwwnnnn', '7': 'nnnwnnwnw', '8': 'wnnwnnwnn', + '9': 'nnwwnnwnn', 'A': 'wnnnnwnnw', 'B': 'nnwnnwnnw', + 'C': 'wnwnnwnnn', 'D': 'nnnnwwnnw', 'E': 'wnnnwwnnn', + 'F': 'nnwnwwnnn', 'G': 'nnnnnwwnw', 'H': 'wnnnnwwnn', + 'I': 'nnwnnwwnn', 'J': 'nnnnwwwnn', 'K': 'wnnnnnnww', + 'L': 'nnwnnnnww', 'M': 'wnwnnnnwn', 'N': 'nnnnwnnww', + 'O': 'wnnnwnnwn', 'P': 'nnwnwnnwn', 'Q': 'nnnnnnwww', + 'R': 'wnnnnnwwn', 'S': 'nnwnnnwwn', 'T': 'nnnnwnwwn', + 'U': 'wwnnnnnnw', 'V': 'nwwnnnnnw', 'W': 'wwwnnnnnn', + 'X': 'nwnnwnnnw', 'Y': 'wwnnwnnnn', 'Z': 'nwwnwnnnn', + '-': 'nwnnnnwnw', '.': 'wwnnnnwnn', ' ': 'nwwnnnwnn', + '*': 'nwnnwnwnn', '$': 'nwnwnwnnn', '/': 'nwnwnnnwn', + '+': 'nwnnnwnwn', '%': 'nnnwnwnwn'} self.set_fill_color(0) - code = txt - + code = txt + code = code.upper() for i in xrange (0, len(code), 2): - char_bar = code[i]; + char_bar = code[i] if not char_bar in bar_char.keys(): - raise RuntimeError ('Caracter "%s" inválido para el código de barras' % char_bar) + raise RuntimeError ('Char "%s" invalid for Code39' % char_bar) seq= '' for s in xrange(0, len(bar_char[char_bar])): - seq += bar_char[char_bar][s] + seq += bar_char[char_bar][s] for bar in xrange(0, len(seq)): if seq[bar] == 'n': @@ -1526,162 +1874,8 @@ class FPDF: line_width = wide if bar % 2 == 0: - self.rect(x,y,line_width,h,'F') + self.rect(x, y, line_width, h, 'F') x += line_width x += gap -#End of class - -# Fonts: - -fpdf_charwidths['courier']={} - -for i in xrange(0,256): - fpdf_charwidths['courier'][chr(i)]=600 - fpdf_charwidths['courierB']=fpdf_charwidths['courier'] - fpdf_charwidths['courierI']=fpdf_charwidths['courier'] - fpdf_charwidths['courierBI']=fpdf_charwidths['courier'] - -fpdf_charwidths['helvetica']={ - '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, - '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584, - ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667, - 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, - 'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833, - 'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556, - '\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, - '\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, - '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, - '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556, - '\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} - -fpdf_charwidths['helveticaB']={ - '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, - '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584, - ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722, - 'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, - 'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889, - 'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556, - '\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, - '\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, - '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, - '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611, - '\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556 -} - -fpdf_charwidths['helveticaBI']={ - '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, - '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':333,'"':474,'#':556,'$':556,'%':889,'&':722,'\'':238,'(':333,')':333,'*':389,'+':584, - ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':333,';':333,'<':584,'=':584,'>':584,'?':611,'@':975,'A':722, - 'B':722,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':556,'K':722,'L':611,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, - 'X':667,'Y':667,'Z':611,'[':333,'\\':278,']':333,'^':584,'_':556,'`':333,'a':556,'b':611,'c':556,'d':611,'e':556,'f':333,'g':611,'h':611,'i':278,'j':278,'k':556,'l':278,'m':889, - 'n':611,'o':611,'p':611,'q':611,'r':389,'s':556,'t':333,'u':611,'v':556,'w':778,'x':556,'y':556,'z':500,'{':389,'|':280,'}':389,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':278,'\x83':556, - '\x84':500,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':278,'\x92':278,'\x93':500,'\x94':500,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, - '\x9a':556,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':280,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, - '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':611,'\xb6':556,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, - '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':556,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':611,'\xf1':611, - '\xf2':611,'\xf3':611,'\xf4':611,'\xf5':611,'\xf6':611,'\xf7':584,'\xf8':611,'\xf9':611,'\xfa':611,'\xfb':611,'\xfc':611,'\xfd':556,'\xfe':611,'\xff':556} - -fpdf_charwidths['helveticaI']={ - '\x00':278,'\x01':278,'\x02':278,'\x03':278,'\x04':278,'\x05':278,'\x06':278,'\x07':278,'\x08':278,'\t':278,'\n':278,'\x0b':278,'\x0c':278,'\r':278,'\x0e':278,'\x0f':278,'\x10':278,'\x11':278,'\x12':278,'\x13':278,'\x14':278,'\x15':278, - '\x16':278,'\x17':278,'\x18':278,'\x19':278,'\x1a':278,'\x1b':278,'\x1c':278,'\x1d':278,'\x1e':278,'\x1f':278,' ':278,'!':278,'"':355,'#':556,'$':556,'%':889,'&':667,'\'':191,'(':333,')':333,'*':389,'+':584, - ',':278,'-':333,'.':278,'/':278,'0':556,'1':556,'2':556,'3':556,'4':556,'5':556,'6':556,'7':556,'8':556,'9':556,':':278,';':278,'<':584,'=':584,'>':584,'?':556,'@':1015,'A':667, - 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':722,'I':278,'J':500,'K':667,'L':556,'M':833,'N':722,'O':778,'P':667,'Q':778,'R':722,'S':667,'T':611,'U':722,'V':667,'W':944, - 'X':667,'Y':667,'Z':611,'[':278,'\\':278,']':278,'^':469,'_':556,'`':333,'a':556,'b':556,'c':500,'d':556,'e':556,'f':278,'g':556,'h':556,'i':222,'j':222,'k':500,'l':222,'m':833, - 'n':556,'o':556,'p':556,'q':556,'r':333,'s':500,'t':278,'u':556,'v':500,'w':722,'x':500,'y':500,'z':500,'{':334,'|':260,'}':334,'~':584,'\x7f':350,'\x80':556,'\x81':350,'\x82':222,'\x83':556, - '\x84':333,'\x85':1000,'\x86':556,'\x87':556,'\x88':333,'\x89':1000,'\x8a':667,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':222,'\x92':222,'\x93':333,'\x94':333,'\x95':350,'\x96':556,'\x97':1000,'\x98':333,'\x99':1000, - '\x9a':500,'\x9b':333,'\x9c':944,'\x9d':350,'\x9e':500,'\x9f':667,'\xa0':278,'\xa1':333,'\xa2':556,'\xa3':556,'\xa4':556,'\xa5':556,'\xa6':260,'\xa7':556,'\xa8':333,'\xa9':737,'\xaa':370,'\xab':556,'\xac':584,'\xad':333,'\xae':737,'\xaf':333, - '\xb0':400,'\xb1':584,'\xb2':333,'\xb3':333,'\xb4':333,'\xb5':556,'\xb6':537,'\xb7':278,'\xb8':333,'\xb9':333,'\xba':365,'\xbb':556,'\xbc':834,'\xbd':834,'\xbe':834,'\xbf':611,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, - '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':278,'\xcd':278,'\xce':278,'\xcf':278,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':584,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':667,'\xde':667,'\xdf':611,'\xe0':556,'\xe1':556,'\xe2':556,'\xe3':556,'\xe4':556,'\xe5':556,'\xe6':889,'\xe7':500,'\xe8':556,'\xe9':556,'\xea':556,'\xeb':556,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':556,'\xf1':556, - '\xf2':556,'\xf3':556,'\xf4':556,'\xf5':556,'\xf6':556,'\xf7':584,'\xf8':611,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} - -fpdf_charwidths['symbol']={ - '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, - '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':713,'#':500,'$':549,'%':833,'&':778,'\'':439,'(':333,')':333,'*':500,'+':549, - ',':250,'-':549,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':549,'=':549,'>':549,'?':444,'@':549,'A':722, - 'B':667,'C':722,'D':612,'E':611,'F':763,'G':603,'H':722,'I':333,'J':631,'K':722,'L':686,'M':889,'N':722,'O':722,'P':768,'Q':741,'R':556,'S':592,'T':611,'U':690,'V':439,'W':768, - 'X':645,'Y':795,'Z':611,'[':333,'\\':863,']':333,'^':658,'_':500,'`':500,'a':631,'b':549,'c':549,'d':494,'e':439,'f':521,'g':411,'h':603,'i':329,'j':603,'k':549,'l':549,'m':576, - 'n':521,'o':549,'p':549,'q':521,'r':549,'s':603,'t':439,'u':576,'v':713,'w':686,'x':493,'y':686,'z':494,'{':480,'|':200,'}':480,'~':549,'\x7f':0,'\x80':0,'\x81':0,'\x82':0,'\x83':0, - '\x84':0,'\x85':0,'\x86':0,'\x87':0,'\x88':0,'\x89':0,'\x8a':0,'\x8b':0,'\x8c':0,'\x8d':0,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0, - '\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':750,'\xa1':620,'\xa2':247,'\xa3':549,'\xa4':167,'\xa5':713,'\xa6':500,'\xa7':753,'\xa8':753,'\xa9':753,'\xaa':753,'\xab':1042,'\xac':987,'\xad':603,'\xae':987,'\xaf':603, - '\xb0':400,'\xb1':549,'\xb2':411,'\xb3':549,'\xb4':549,'\xb5':713,'\xb6':494,'\xb7':460,'\xb8':549,'\xb9':549,'\xba':549,'\xbb':549,'\xbc':1000,'\xbd':603,'\xbe':1000,'\xbf':658,'\xc0':823,'\xc1':686,'\xc2':795,'\xc3':987,'\xc4':768,'\xc5':768, - '\xc6':823,'\xc7':768,'\xc8':768,'\xc9':713,'\xca':713,'\xcb':713,'\xcc':713,'\xcd':713,'\xce':713,'\xcf':713,'\xd0':768,'\xd1':713,'\xd2':790,'\xd3':790,'\xd4':890,'\xd5':823,'\xd6':549,'\xd7':250,'\xd8':713,'\xd9':603,'\xda':603,'\xdb':1042, - '\xdc':987,'\xdd':603,'\xde':987,'\xdf':603,'\xe0':494,'\xe1':329,'\xe2':790,'\xe3':790,'\xe4':786,'\xe5':713,'\xe6':384,'\xe7':384,'\xe8':384,'\xe9':384,'\xea':384,'\xeb':384,'\xec':494,'\xed':494,'\xee':494,'\xef':494,'\xf0':0,'\xf1':329, - '\xf2':274,'\xf3':686,'\xf4':686,'\xf5':686,'\xf6':384,'\xf7':384,'\xf8':384,'\xf9':384,'\xfa':384,'\xfb':384,'\xfc':494,'\xfd':494,'\xfe':494,'\xff':0} - -fpdf_charwidths['times']={ - '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, - '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':408,'#':500,'$':500,'%':833,'&':778,'\'':180,'(':333,')':333,'*':500,'+':564, - ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':278,';':278,'<':564,'=':564,'>':564,'?':444,'@':921,'A':722, - 'B':667,'C':667,'D':722,'E':611,'F':556,'G':722,'H':722,'I':333,'J':389,'K':722,'L':611,'M':889,'N':722,'O':722,'P':556,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':722,'W':944, - 'X':722,'Y':722,'Z':611,'[':333,'\\':278,']':333,'^':469,'_':500,'`':333,'a':444,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':500,'i':278,'j':278,'k':500,'l':278,'m':778, - 'n':500,'o':500,'p':500,'q':500,'r':333,'s':389,'t':278,'u':500,'v':500,'w':722,'x':500,'y':500,'z':444,'{':480,'|':200,'}':480,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, - '\x84':444,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':889,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':444,'\x94':444,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':980, - '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':200,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':564,'\xad':333,'\xae':760,'\xaf':333, - '\xb0':400,'\xb1':564,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':453,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':444,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, - '\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':564,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':722,'\xde':556,'\xdf':500,'\xe0':444,'\xe1':444,'\xe2':444,'\xe3':444,'\xe4':444,'\xe5':444,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500, - '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':564,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':500,'\xfe':500,'\xff':500} - -fpdf_charwidths['timesB']={ - '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, - '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':555,'#':500,'$':500,'%':1000,'&':833,'\'':278,'(':333,')':333,'*':500,'+':570, - ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':930,'A':722, - 'B':667,'C':722,'D':722,'E':667,'F':611,'G':778,'H':778,'I':389,'J':500,'K':778,'L':667,'M':944,'N':722,'O':778,'P':611,'Q':778,'R':722,'S':556,'T':667,'U':722,'V':722,'W':1000, - 'X':722,'Y':722,'Z':667,'[':333,'\\':278,']':333,'^':581,'_':500,'`':333,'a':500,'b':556,'c':444,'d':556,'e':444,'f':333,'g':500,'h':556,'i':278,'j':333,'k':556,'l':278,'m':833, - 'n':556,'o':500,'p':556,'q':556,'r':444,'s':389,'t':333,'u':556,'v':500,'w':722,'x':500,'y':500,'z':444,'{':394,'|':220,'}':394,'~':520,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, - '\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':1000,'\x8d':350,'\x8e':667,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000, - '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':444,'\x9f':722,'\xa0':250,'\xa1':333,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':300,'\xab':500,'\xac':570,'\xad':333,'\xae':747,'\xaf':333, - '\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':556,'\xb6':540,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':330,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':722,'\xc1':722,'\xc2':722,'\xc3':722,'\xc4':722,'\xc5':722, - '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':570,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':722,'\xde':611,'\xdf':556,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556, - '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} - -fpdf_charwidths['timesBI']={ - '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, - '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':389,'"':555,'#':500,'$':500,'%':833,'&':778,'\'':278,'(':333,')':333,'*':500,'+':570, - ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':570,'=':570,'>':570,'?':500,'@':832,'A':667, - 'B':667,'C':667,'D':722,'E':667,'F':667,'G':722,'H':778,'I':389,'J':500,'K':667,'L':611,'M':889,'N':722,'O':722,'P':611,'Q':722,'R':667,'S':556,'T':611,'U':722,'V':667,'W':889, - 'X':667,'Y':611,'Z':611,'[':333,'\\':278,']':333,'^':570,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':333,'g':500,'h':556,'i':278,'j':278,'k':500,'l':278,'m':778, - 'n':556,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':556,'v':444,'w':667,'x':500,'y':444,'z':389,'{':348,'|':220,'}':348,'~':570,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, - '\x84':500,'\x85':1000,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':556,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':611,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':500,'\x94':500,'\x95':350,'\x96':500,'\x97':1000,'\x98':333,'\x99':1000, - '\x9a':389,'\x9b':333,'\x9c':722,'\x9d':350,'\x9e':389,'\x9f':611,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':220,'\xa7':500,'\xa8':333,'\xa9':747,'\xaa':266,'\xab':500,'\xac':606,'\xad':333,'\xae':747,'\xaf':333, - '\xb0':400,'\xb1':570,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':576,'\xb6':500,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':300,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':667,'\xc1':667,'\xc2':667,'\xc3':667,'\xc4':667,'\xc5':667, - '\xc6':944,'\xc7':667,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':570,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':611,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556, - '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':444,'\xfe':500,'\xff':444} - -fpdf_charwidths['timesI']={ - '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, - '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':420,'#':500,'$':500,'%':833,'&':778,'\'':214,'(':333,')':333,'*':500,'+':675, - ',':250,'-':333,'.':250,'/':278,'0':500,'1':500,'2':500,'3':500,'4':500,'5':500,'6':500,'7':500,'8':500,'9':500,':':333,';':333,'<':675,'=':675,'>':675,'?':500,'@':920,'A':611, - 'B':611,'C':667,'D':722,'E':611,'F':611,'G':722,'H':722,'I':333,'J':444,'K':667,'L':556,'M':833,'N':667,'O':722,'P':611,'Q':722,'R':611,'S':500,'T':556,'U':722,'V':611,'W':833, - 'X':611,'Y':556,'Z':556,'[':389,'\\':278,']':389,'^':422,'_':500,'`':333,'a':500,'b':500,'c':444,'d':500,'e':444,'f':278,'g':500,'h':500,'i':278,'j':278,'k':444,'l':278,'m':722, - 'n':500,'o':500,'p':500,'q':500,'r':389,'s':389,'t':278,'u':500,'v':444,'w':667,'x':444,'y':444,'z':389,'{':400,'|':275,'}':400,'~':541,'\x7f':350,'\x80':500,'\x81':350,'\x82':333,'\x83':500, - '\x84':556,'\x85':889,'\x86':500,'\x87':500,'\x88':333,'\x89':1000,'\x8a':500,'\x8b':333,'\x8c':944,'\x8d':350,'\x8e':556,'\x8f':350,'\x90':350,'\x91':333,'\x92':333,'\x93':556,'\x94':556,'\x95':350,'\x96':500,'\x97':889,'\x98':333,'\x99':980, - '\x9a':389,'\x9b':333,'\x9c':667,'\x9d':350,'\x9e':389,'\x9f':556,'\xa0':250,'\xa1':389,'\xa2':500,'\xa3':500,'\xa4':500,'\xa5':500,'\xa6':275,'\xa7':500,'\xa8':333,'\xa9':760,'\xaa':276,'\xab':500,'\xac':675,'\xad':333,'\xae':760,'\xaf':333, - '\xb0':400,'\xb1':675,'\xb2':300,'\xb3':300,'\xb4':333,'\xb5':500,'\xb6':523,'\xb7':250,'\xb8':333,'\xb9':300,'\xba':310,'\xbb':500,'\xbc':750,'\xbd':750,'\xbe':750,'\xbf':500,'\xc0':611,'\xc1':611,'\xc2':611,'\xc3':611,'\xc4':611,'\xc5':611, - '\xc6':889,'\xc7':667,'\xc8':611,'\xc9':611,'\xca':611,'\xcb':611,'\xcc':333,'\xcd':333,'\xce':333,'\xcf':333,'\xd0':722,'\xd1':667,'\xd2':722,'\xd3':722,'\xd4':722,'\xd5':722,'\xd6':722,'\xd7':675,'\xd8':722,'\xd9':722,'\xda':722,'\xdb':722, - '\xdc':722,'\xdd':556,'\xde':611,'\xdf':500,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':667,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':500, - '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':675,'\xf8':500,'\xf9':500,'\xfa':500,'\xfb':500,'\xfc':500,'\xfd':444,'\xfe':500,'\xff':444} - -fpdf_charwidths['zapfdingbats']={ - '\x00':0,'\x01':0,'\x02':0,'\x03':0,'\x04':0,'\x05':0,'\x06':0,'\x07':0,'\x08':0,'\t':0,'\n':0,'\x0b':0,'\x0c':0,'\r':0,'\x0e':0,'\x0f':0,'\x10':0,'\x11':0,'\x12':0,'\x13':0,'\x14':0,'\x15':0, - '\x16':0,'\x17':0,'\x18':0,'\x19':0,'\x1a':0,'\x1b':0,'\x1c':0,'\x1d':0,'\x1e':0,'\x1f':0,' ':278,'!':974,'"':961,'#':974,'$':980,'%':719,'&':789,'\'':790,'(':791,')':690,'*':960,'+':939, - ',':549,'-':855,'.':911,'/':933,'0':911,'1':945,'2':974,'3':755,'4':846,'5':762,'6':761,'7':571,'8':677,'9':763,':':760,';':759,'<':754,'=':494,'>':552,'?':537,'@':577,'A':692, - 'B':786,'C':788,'D':788,'E':790,'F':793,'G':794,'H':816,'I':823,'J':789,'K':841,'L':823,'M':833,'N':816,'O':831,'P':923,'Q':744,'R':723,'S':749,'T':790,'U':792,'V':695,'W':776, - 'X':768,'Y':792,'Z':759,'[':707,'\\':708,']':682,'^':701,'_':826,'`':815,'a':789,'b':789,'c':707,'d':687,'e':696,'f':689,'g':786,'h':787,'i':713,'j':791,'k':785,'l':791,'m':873, - 'n':761,'o':762,'p':762,'q':759,'r':759,'s':892,'t':892,'u':788,'v':784,'w':438,'x':138,'y':277,'z':415,'{':392,'|':392,'}':668,'~':668,'\x7f':0,'\x80':390,'\x81':390,'\x82':317,'\x83':317, - '\x84':276,'\x85':276,'\x86':509,'\x87':509,'\x88':410,'\x89':410,'\x8a':234,'\x8b':234,'\x8c':334,'\x8d':334,'\x8e':0,'\x8f':0,'\x90':0,'\x91':0,'\x92':0,'\x93':0,'\x94':0,'\x95':0,'\x96':0,'\x97':0,'\x98':0,'\x99':0, - '\x9a':0,'\x9b':0,'\x9c':0,'\x9d':0,'\x9e':0,'\x9f':0,'\xa0':0,'\xa1':732,'\xa2':544,'\xa3':544,'\xa4':910,'\xa5':667,'\xa6':760,'\xa7':760,'\xa8':776,'\xa9':595,'\xaa':694,'\xab':626,'\xac':788,'\xad':788,'\xae':788,'\xaf':788, - '\xb0':788,'\xb1':788,'\xb2':788,'\xb3':788,'\xb4':788,'\xb5':788,'\xb6':788,'\xb7':788,'\xb8':788,'\xb9':788,'\xba':788,'\xbb':788,'\xbc':788,'\xbd':788,'\xbe':788,'\xbf':788,'\xc0':788,'\xc1':788,'\xc2':788,'\xc3':788,'\xc4':788,'\xc5':788, - '\xc6':788,'\xc7':788,'\xc8':788,'\xc9':788,'\xca':788,'\xcb':788,'\xcc':788,'\xcd':788,'\xce':788,'\xcf':788,'\xd0':788,'\xd1':788,'\xd2':788,'\xd3':788,'\xd4':894,'\xd5':838,'\xd6':1016,'\xd7':458,'\xd8':748,'\xd9':924,'\xda':748,'\xdb':918, - '\xdc':927,'\xdd':928,'\xde':928,'\xdf':834,'\xe0':873,'\xe1':828,'\xe2':924,'\xe3':924,'\xe4':917,'\xe5':930,'\xe6':931,'\xe7':463,'\xe8':883,'\xe9':836,'\xea':836,'\xeb':867,'\xec':867,'\xed':696,'\xee':696,'\xef':874,'\xf0':0,'\xf1':874, - '\xf2':760,'\xf3':946,'\xf4':771,'\xf5':865,'\xf6':771,'\xf7':888,'\xf8':967,'\xf9':888,'\xfa':831,'\xfb':873,'\xfc':927,'\xfd':970,'\xfe':918,'\xff':0} - - diff --git a/gluon/contrib/pyfpdf/html.py b/gluon/contrib/pyfpdf/html.py index 71e5ef57..bc1c53b7 100644 --- a/gluon/contrib/pyfpdf/html.py +++ b/gluon/contrib/pyfpdf/html.py @@ -26,22 +26,23 @@ def hex2dec(color = "#000000"): class HTML2FPDF(HTMLParser): "Render basic HTML to FPDF" - def __init__(self, pdf, image_map, **kwargs): + def __init__(self, pdf): HTMLParser.__init__(self) - self.image_map = image_map self.style = {} self.pre = False self.href = '' self.align = '' self.page_links = {} self.font_list = ("times","courier", "helvetica") + self.font = None + self.font_stack = [] self.pdf = pdf self.r = self.g = self.b = 0 self.indent = 0 self.bullet = [] - self.font_face="times" # initialize font - self.color=0 # initialize font color - self.set_font(kwargs.get("font","times"), kwargs.get("fontsize",12)) + self.set_font("times", 12) + self.font_face = "times" # initialize font + self.color = 0 #initialize font color self.table = None # table attributes self.table_col_width = None # column (header) widths self.table_col_index = None # current column index @@ -53,7 +54,7 @@ class HTML2FPDF(HTMLParser): self.thead = None self.tfoot = None self.theader_out = self.tfooter_out = False - + def width2mm(self, length): if length[-1]=='%': total = self.pdf.w - self.pdf.r_margin - self.pdf.l_margin @@ -66,7 +67,10 @@ class HTML2FPDF(HTMLParser): def handle_data(self, txt): if self.td is not None: # drawing a table? if 'width' not in self.td and 'colspan' not in self.td: - l = [self.table_col_width[self.table_col_index]] + try: + l = [self.table_col_width[self.table_col_index]] + except IndexError: + raise RuntimeError("Table column/cell width not specified, unable to continue") elif 'colspan' in self.td: i = self.table_col_index colspan = int(self.td['colspan']) @@ -83,7 +87,7 @@ class HTML2FPDF(HTMLParser): else: self.set_style('B',True) border = border or 'B' - align = self.td.get('align', 'C')[0].upper() + align = 'C' bgcolor = hex2dec(self.td.get('bgcolor', self.tr.get('bgcolor', ''))) # parsing table header/footer (drawn later): if self.thead is not None: @@ -97,13 +101,13 @@ class HTML2FPDF(HTMLParser): self.pdf.add_page() self.theader_out = self.tfooter_out = False if self.tfoot is None and self.thead is None: - if not self.theader_out: + if not self.theader_out: self.output_table_header() self.box_shadow(w, h, bgcolor) if DEBUG: print "td cell", self.pdf.x, w, txt, "*" self.pdf.cell(w,h,txt,border,0,align) elif self.table is not None: - # ignore anything else than td inside a table + # ignore anything else than td inside a table pass elif self.align: if DEBUG: print "cell", txt, "*" @@ -138,7 +142,7 @@ class HTML2FPDF(HTMLParser): self.pdf.set_x(self.table_offset) #self.pdf.set_x(x) self.theader_out = True - + def output_table_footer(self): if self.tfooter: x = self.pdf.x @@ -152,7 +156,7 @@ class HTML2FPDF(HTMLParser): if int(self.table.get('border', 0)): self.output_table_sep() self.tfooter_out = True - + def output_table_sep(self): self.pdf.set_x(self.table_offset) x1 = self.pdf.x @@ -173,7 +177,7 @@ class HTML2FPDF(HTMLParser): if tag=='p': self.pdf.ln(5) if attrs: - self.align=attrs['align'].lower() + if attrs: self.align = attrs.get('align') if tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'): k = (2, 1.5, 1.17, 1, 0.83, 0.67)[int(tag[1])] self.pdf.ln(5*k) @@ -208,6 +212,8 @@ class HTML2FPDF(HTMLParser): self.pdf.write(self.h,'%s%s ' % (' '*5*self.indent, bullet)) self.set_text_color() if tag=='font': + # save previous font state: + self.font_stack.append((self.font_face, self.font_size, self.color)) if 'color' in attrs: self.color = hex2dec(attrs['color']) self.set_text_color(*color) @@ -234,6 +240,7 @@ class HTML2FPDF(HTMLParser): self.tfooter = [] self.thead = None self.tfoot = None + self.table_h = 0 self.pdf.ln() if tag=='tr': self.tr = dict([(k.lower(), v) for k,v in attrs.items()]) @@ -244,7 +251,7 @@ class HTML2FPDF(HTMLParser): if tag=='th': self.td = dict([(k.lower(), v) for k,v in attrs.items()]) self.th = True - if self.td['width']: + if 'width' in self.td: self.table_col_width.append(self.td['width']) if tag=='thead': self.thead = {} @@ -258,8 +265,7 @@ class HTML2FPDF(HTMLParser): h = px2mm(attrs.get('height',0)) if self.align and self.align[0].upper() == 'C': x = (self.pdf.w-x)/2.0 - w/2.0 - self.pdf.image(self.image_map(attrs['src']), - x, y, w, h, link=self.href) + self.pdf.image(attrs['src'], x, y, w, h, link=self.href) self.pdf.set_x(x+w) self.pdf.set_y(y+h) if tag=='b' or tag=='i' or tag=='u': @@ -324,12 +330,13 @@ class HTML2FPDF(HTMLParser): self.td = None self.th = False if tag=='font': - if self.color: + # recover last font state + face, size, color = self.font_stack.pop() + if face: self.pdf.set_text_color(0,0,0) self.color = None - if self.font_face: - self.set_font('Times',12) - + self.set_font(face, size) + self.font = None if tag=='center': self.align = None @@ -345,7 +352,7 @@ class HTML2FPDF(HTMLParser): self.set_style('u', False) self.set_style('b', False) self.set_style('i', False) - self.set_text_color() + self.set_text_color() def set_style(self, tag=None, enable=None): #Modify style and select corresponding font @@ -367,7 +374,7 @@ class HTML2FPDF(HTMLParser): self.r = r self.g = g self.b = b - + def put_link(self, url, txt): #Put a hyperlink self.set_text_color(0,0,255) @@ -381,79 +388,9 @@ class HTML2FPDF(HTMLParser): self.pdf.line(self.pdf.get_x(),self.pdf.get_y(),self.pdf.get_x()+187,self.pdf.get_y()) self.pdf.ln(3) -class HTMLMixin(): - def write_html(self, text, image_map=lambda x:x, **kwargs): +class HTMLMixin(object): + def write_html(self, text): "Parse HTML and convert it to PDF" - h2p = HTML2FPDF(self,image_map=image_map,**kwargs) + h2p = HTML2FPDF(self) h2p.feed(text) -if __name__=='__main__': - html=""" -

html2fpdf

-

Basic usage

-

You can now easily print text mixing different -styles : bold, italic, underlined, or -all at once!
You can also insert links -on text, such as www.fpdf.org, -or on an image: click on the logo.
-

- -
-

Sample List

-
  • option 1
  • -
    1. option 2
    -
  • option 3
- - - - - - - -
Header 1header 2
cell 1cell 2
cell 2cell 3
- - - - - - - - - - - - - -""" + """ - - - -""" * 200 + """ - -
Header 1header 2
footer 1footer 2
cell 1cell 2
cell 1cell 2
cell spanned
cell 3cell 4
cell 5cell 6
-""" - - class MyFPDF(FPDF, HTMLMixin): - def header(self): - self.image('tutorial/logo_pb.png',10,8,33) - self.set_font('Arial','B',15) - self.cell(80) - self.cell(30,10,'Title',1,0,'C') - self.ln(20) - - def footer(self): - self.set_y(-15) - self.set_font('Arial','I',8) - txt = 'Page %s of %s' % (self.page_no(), self.alias_nb_pages()) - self.cell(0,10,txt,0,0,'C') - - pdf=MyFPDF() - #First page - pdf.add_page() - pdf.write_html(html) - pdf.output('html.pdf','F') - - import os - os.system("evince html.pdf") - - diff --git a/gluon/contrib/pyfpdf/php.py b/gluon/contrib/pyfpdf/php.py new file mode 100644 index 00000000..80a4622d --- /dev/null +++ b/gluon/contrib/pyfpdf/php.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# -*- coding: latin-1 -*- + +# fpdf php helpers: + +def substr(s, start, length=-1): + if length < 0: + length=len(s)-start + return s[start:start+length] + +def sprintf(fmt, *args): return fmt % args + +def print_r(array): + if not isinstance(array, dict): + array = dict([(k, k) for k in array]) + for k, v in array.items(): + print "[%s] => %s" % (k, v), + +def UTF8ToUTF16BE(instr, setbom=True): + "Converts UTF-8 strings to UTF16-BE." + outstr = "" + if (setbom): + outstr += "\xFE\xFF"; + if not isinstance(instr, unicode): + instr = instr.decode('UTF-8') + outstr += instr.encode('UTF-16BE') + return outstr + +def UTF8StringToArray(instr): + "Converts UTF-8 strings to codepoints array" + return [ord(c) for c in instr] + +# ttfints php helpers: + +def die(msg): + raise RuntimeError(msg) + +def str_repeat(s, count): + return s * count + +def str_pad(s, pad_length=0, pad_char= " ", pad_type= +1 ): + if pad_type<0: # pad left + return s.rjust(pad_length, pad_char) + elif pad_type>0: # pad right + return s.ljust(pad_length, pad_char) + else: # pad both + return s.center(pad_length, pad_char) + +strlen = count = lambda s: len(s) \ No newline at end of file diff --git a/gluon/contrib/pyfpdf/template.py b/gluon/contrib/pyfpdf/template.py old mode 100755 new mode 100644 index 8b158b36..2d38c9f9 --- a/gluon/contrib/pyfpdf/template.py +++ b/gluon/contrib/pyfpdf/template.py @@ -16,8 +16,9 @@ class Template: def __init__(self, infile=None, elements=None, format='A4', orientation='portrait', title='', author='', subject='', creator='', keywords=''): if elements: - self.elements = dict([(v['name'].lower(),v) for v in elements]) - self.handlers = {'T': self.text, 'L': self.line, 'I': self.image, + self.elements = elements + self.keys = [v['name'].lower() for v in self.elements] + self.handlers = {'T': self.text, 'L': self.line, 'I': self.image, 'B': self.rect, 'BC': self.barcode, } self.pg_no = 0 self.texts = {} @@ -32,34 +33,33 @@ class Template: "Parse template format csv file and create elements dict" keys = ('name','type','x1','y1','x2','y2','font','size', 'bold','italic','underline','foreground','background', - 'align','text','priority') - self.elements = {} - f = open(infile, 'rb') - try: - for row in csv.reader(f, delimiter=delimiter): - kargs = {} - for i,v in enumerate(row): - if not v.startswith("'") and decimal_sep!=".": - v = v.replace(decimal_sep,".") - else: - v = v - if v=='': - v = None - else: - v = eval(v.strip()) - kargs[keys[i]] = v - self.elements[kargs['name'].lower()] = kargs - finally: - f.close() + 'align','text','priority', 'multiline') + self.elements = [] + for row in csv.reader(open(infile, 'rb'), delimiter=delimiter): + kargs = {} + for i,v in enumerate(row): + if not v.startswith("'") and decimal_sep!=".": + v = v.replace(decimal_sep,".") + else: + v = v + if v=='': + v = None + else: + v = eval(v.strip()) + kargs[keys[i]] = v + self.elements.append(kargs) + self.keys = [v['name'].lower() for v in self.elements] def add_page(self): self.pg_no += 1 self.texts[self.pg_no] = {} - + def __setitem__(self, name, value): - if name.lower() in self.elements: + if self.has_key(name): if isinstance(value,unicode): value = value.encode("latin1","ignore") + elif value is None: + value = "" else: value = str(value) self.texts[self.pg_no][name.lower()] = value @@ -67,14 +67,27 @@ class Template: # setitem shortcut (may be further extended) set = __setitem__ + def has_key(self, name): + return name.lower() in self.keys + def __getitem__(self, name): - if name.lower() in self.elements: - return self.texts[self.pg_no].get(name.lower(), self.elements[name.lower()]['text']) + if self.has_key(name): + key = name.lower() + if key in self.texts: + # text for this page: + return self.texts[self.pg_no][key] + else: + # find first element for default text: + elements = [element for element in self.elements + if element['name'].lower() == key] + if elements: + return elements[0]['text'] def split_multicell(self, text, element_name): "Divide (\n) a string using a given element width" pdf = self.pdf - element = self.elements[element_name.lower()] + element = [element for element in self.elements + if element['name'].lower() == element_name.lower()][0] style = "" if element['bold']: style += "B" if element['italic']: style += "I" @@ -88,7 +101,7 @@ class Template: return pdf.multi_cell(w=element['x2']-element['x1'], h=element['y2']-element['y1'], txt=text,align=align,split_only=True) - + def render(self, outfile, dest="F"): pdf = self.pdf for pg in range(1, self.pg_no+1): @@ -96,7 +109,7 @@ class Template: pdf.set_font('Arial','B',16) pdf.set_auto_page_break(False,margin=0) - for element in sorted(self.elements.values(),key=lambda x: x['priority']): + for element in sorted(self.elements,key=lambda x: x['priority']): #print "dib",element['type'], element['name'], element['x1'], element['y1'], element['x2'], element['y2'] element = element.copy() element['text'] = self.texts[pg].get(element['name'].lower(), element['text']) @@ -105,12 +118,12 @@ class Template: self.handlers[element['type'].upper()](pdf, **element) if 'rotate' in element: pdf.rotate(0) - + return pdf.output(outfile, dest) - - def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10, - bold=False, italic=False, underline=False, align="", - foreground=0, backgroud=65535, + + def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10, + bold=False, italic=False, underline=False, align="", + foreground=0, backgroud=65535, multiline=None, *args, **kwargs): if text: if pdf.text_color!=rgb(foreground): @@ -134,7 +147,19 @@ class Template: ##m_k = 72 / 2.54 ##h = (size/m_k) pdf.set_xy(x1,y1) - pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align) + if multiline is None: + # multiline==None: write without wrapping/trimming (default) + pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align) + elif multiline: + # multiline==True: automatic word - warp + pdf.multi_cell(w=x2-x1,h=y2-y1,txt=text,border=0,align=align) + else: + # multiline==False: trim to fit exactly the space defined + text = pdf.multi_cell(w=x2-x1, h=y2-y1, + txt=text, align=align, split_only=True)[0] + print "trimming: *%s*" % text + pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align) + #pdf.Text(x=x1,y=y1,txt=text) def line(self, pdf, x1=0, y1=0, x2=0, y2=0, size=0, foreground=0, *args, **kwargs): @@ -176,7 +201,7 @@ if __name__ == "__main__": title="Sample Invoice", author="Sample Company", subject="Sample Customer", keywords="Electronic TAX Invoice") f.parse_csv(infile="invoice.csv", delimiter=";", decimal_sep=",") - + detail = "Lorem ipsum dolor sit amet, consectetur. " * 30 items = [] for i in range(1, 30): @@ -185,7 +210,7 @@ if __name__ == "__main__": price = round(random.random()*100,3) code = "%s%s%02d" % (chr(random.randint(65,90)), chr(random.randint(65,90)),i) items.append(dict(code=code, unit='u', - qty=qty, price=price, + qty=qty, price=price, amount=qty*price, ds="%s: %s" % (i,ds))) @@ -228,7 +253,7 @@ if __name__ == "__main__": f["company_name"] = "Sample Company" f["company_logo"] = "tutorial/logo.png" f["company_header1"] = "Some Address - somewhere -" - f["company_header2"] = "http://www.example.com" + f["company_header2"] = "http://www.example.com" f["company_footer1"] = "Tax Code ..." f["company_footer2"] = "Tax/VAT ID ..." f['number'] = '0001-00001234' @@ -236,9 +261,9 @@ if __name__ == "__main__": f['due_date'] = '2099-09-10' f['customer_name'] = "Sample Client" f['customer_address'] = "Siempreviva 1234" - + # print line item... - li = 0 + li = 0 k = 0 total = Decimal("0.00") for it in li_items: @@ -268,11 +293,9 @@ if __name__ == "__main__": else: f['total_label'] = 'SubTotal:' f['total'] = "%0.2f" % total - + f.render("./invoice.pdf") if sys.platform.startswith("linux"): os.system("evince ./invoice.pdf") else: os.system("./invoice.pdf") - - diff --git a/gluon/contrib/pyfpdf/ttfonts.py b/gluon/contrib/pyfpdf/ttfonts.py new file mode 100644 index 00000000..cdb280a3 --- /dev/null +++ b/gluon/contrib/pyfpdf/ttfonts.py @@ -0,0 +1,1033 @@ +#****************************************************************************** +# TTFontFile class +# +# This class is based on The ReportLab Open Source PDF library +# written in Python - http://www.reportlab.com/software/opensource/ +# together with ideas from the OpenOffice source code and others. +# +# Version: 1.04 +# Date: 2011-09-18 +# Author: Ian Back +# License: LGPL +# Copyright (c) Ian Back, 2010 +# Ported to Python 2.7 by Mariano Reingart (reingart@gmail.com) on 2012 +# This header must be retained in any redistribution or +# modification of the file. +# +#****************************************************************************** + +from struct import pack, unpack, unpack_from +import re +import warnings +from php import die, substr, str_repeat, str_pad, strlen, count + + +# Define the value used in the "head" table of a created TTF file +# 0x74727565 "true" for Mac +# 0x00010000 for Windows +# Either seems to work for a font embedded in a PDF file +# when read by Adobe Reader on a Windows PC(!) +_TTF_MAC_HEADER = False + + +# TrueType Font Glyph operators +GF_WORDS = (1 << 0) +GF_SCALE = (1 << 3) +GF_MORE = (1 << 5) +GF_XYSCALE = (1 << 6) +GF_TWOBYTWO = (1 << 7) + + +def sub32(x, y): + xlo = x[1] + xhi = x[0] + ylo = y[1] + yhi = y[0] + if (ylo > xlo): + xlo += 1 << 16 + yhi += 1 + reslo = xlo-ylo + if (yhi > xhi): + xhi += 1 << 16 + reshi = xhi-yhi + reshi = reshi & 0xFFFF + return (reshi, reslo) + +def calcChecksum(data): + if (strlen(data) % 4): + data += str_repeat("\0", (4-(len(data) % 4))) + hi=0x0000 + lo=0x0000 + for i in range(0, len(data), 4): + hi += (ord(data[i])<<8) + ord(data[i+1]) + lo += (ord(data[i+2])<<8) + ord(data[i+3]) + hi += lo >> 16 + lo = lo & 0xFFFF + hi = hi & 0xFFFF + return (hi, lo) + + +class TTFontFile: + + def __init__(self): + self.maxStrLenRead = 200000 # Maximum size of glyf table to read in as string (otherwise reads each glyph from file) + + def getMetrics(self, file): + self.filename = file + self.fh = open(file,'rb') + self._pos = 0 + self.charWidths = [] + self.glyphPos = {} + self.charToGlyph = {} + self.tables = {} + self.otables = {} + self.ascent = 0 + self.descent = 0 + self.TTCFonts = {} + self.version = version = self.read_ulong() + if (version==0x4F54544F): + die("Postscript outlines are not supported") + if (version==0x74746366): + die("ERROR - TrueType Fonts Collections not supported") + if (version not in (0x00010000,0x74727565)): + die("Not a TrueType font: version=" + version) + self.readTableDirectory() + self.extractInfo() + self.fh.close() + + def readTableDirectory(self, ): + self.numTables = self.read_ushort() + self.searchRange = self.read_ushort() + self.entrySelector = self.read_ushort() + self.rangeShift = self.read_ushort() + self.tables = {} + for i in range(self.numTables): + record = {} + record['tag'] = self.read_tag() + record['checksum'] = (self.read_ushort(),self.read_ushort()) + record['offset'] = self.read_ulong() + record['length'] = self.read_ulong() + self.tables[record['tag']] = record + + def get_table_pos(self, tag): + offset = self.tables[tag]['offset'] + length = self.tables[tag]['length'] + return (offset, length) + + def seek(self, pos): + self._pos = pos + self.fh.seek(self._pos) + + def skip(self, delta): + self._pos = self._pos + delta + self.fh.seek(self._pos) + + def seek_table(self, tag, offset_in_table = 0): + tpos = self.get_table_pos(tag) + self._pos = tpos[0] + offset_in_table + self.fh.seek(self._pos) + return self._pos + + def read_tag(self): + self._pos += 4 + return self.fh.read(4) + + def read_short(self): + self._pos += 2 + s = self.fh.read(2) + a = (ord(s[0])<<8) + ord(s[1]) + if (a & (1 << 15) ): + a = (a - (1 << 16)) + return a + + def unpack_short(self, s): + a = (ord(s[0])<<8) + ord(s[1]) + if (a & (1 << 15) ): + a = (a - (1 << 16)) + return a + + def read_ushort(self): + self._pos += 2 + s = self.fh.read(2) + return (ord(s[0])<<8) + ord(s[1]) + + def read_ulong(self): + self._pos += 4 + s = self.fh.read(4) + # if large uInt32 as an integer, PHP converts it to -ve + return (ord(s[0])*16777216) + (ord(s[1])<<16) + (ord(s[2])<<8) + ord(s[3]) # 16777216 = 1<<24 + + def get_ushort(self, pos): + self.fh.seek(pos) + s = self.fh.read(2) + return (ord(s[0])<<8) + ord(s[1]) + + def get_ulong(self, pos): + self.fh.seek(pos) + s = self.fh.read(4) + # iF large uInt32 as an integer, PHP converts it to -ve + return (ord(s[0])*16777216) + (ord(s[1])<<16) + (ord(s[2])<<8) + ord(s[3]) # 16777216 = 1<<24 + + def pack_short(self, val): + if (val<0): + val = abs(val) + val = ~val + val += 1 + return pack(">H",val) + + def splice(self, stream, offset, value): + return substr(stream,0,offset) + value + substr(stream,offset+strlen(value)) + + def _set_ushort(self, stream, offset, value): + up = pack(">H", value) + return self.splice(stream, offset, up) + + def _set_short(self, stream, offset, val): + if (val<0): + val = abs(val) + val = ~val + val += 1 + up = pack(">H",val) + return self.splice(stream, offset, up) + + def get_chunk(self, pos, length): + self.fh.seek(pos) + if (length <1): return '' + return (self.fh.read(length)) + + def get_table(self, tag): + (pos, length) = self.get_table_pos(tag) + if (length == 0): + die('Truetype font (' + self.filename + '): error reading table: ' + tag) + self.fh.seek(pos) + return (self.fh.read(length)) + + def add(self, tag, data): + if (tag == 'head') : + data = self.splice(data, 8, "\0\0\0\0") + self.otables[tag] = data + +############################################/ +############################################/ + +############################################/ + + def extractInfo(self): + #################/ + # name - Naming table + #################/ + self.sFamilyClass = 0 + self.sFamilySubClass = 0 + + name_offset = self.seek_table("name") + format = self.read_ushort() + if (format != 0): + die("Unknown name table format " + format) + numRecords = self.read_ushort() + string_data_offset = name_offset + self.read_ushort() + names = {1:'',2:'',3:'',4:'',6:''} + K = names.keys() + nameCount = len(names) + for i in range(numRecords): + platformId = self.read_ushort() + encodingId = self.read_ushort() + languageId = self.read_ushort() + nameId = self.read_ushort() + length = self.read_ushort() + offset = self.read_ushort() + if (nameId not in K): continue + N = '' + if (platformId == 3 and encodingId == 1 and languageId == 0x409): # Microsoft, Unicode, US English, PS Name + opos = self._pos + self.seek(string_data_offset + offset) + if (length % 2 != 0): + die("PostScript name is UTF-16BE string of odd length") + length /= 2 + N = '' + while (length > 0): + char = self.read_ushort() + N += (chr(char)) + length -= 1 + self._pos = opos + self.seek(opos) + + elif (platformId == 1 and encodingId == 0 and languageId == 0): # Macintosh, Roman, English, PS Name + opos = self._pos + N = self.get_chunk(string_data_offset + offset, length) + self._pos = opos + self.seek(opos) + + if (N and names[nameId]==''): + names[nameId] = N + nameCount -= 1 + if (nameCount==0): break + + + if (names[6]): + psName = names[6] + elif (names[4]): + psName = re.sub(' ','-',names[4]) + elif (names[1]): + psName = re.sub(' ','-',names[1]) + else: + psName = '' + if (not psName): + die("Could not find PostScript font name") + self.name = psName + if (names[1]): + self.familyName = names[1] + else: + self.familyName = psName + if (names[2]): + self.styleName = names[2] + else: + self.styleName = 'Regular' + if (names[4]): + self.fullName = names[4] + else: + self.fullName = psName + if (names[3]): + self.uniqueFontID = names[3] + else: + self.uniqueFontID = psName + if (names[6]): + self.fullName = names[6] + + #################/ + # head - Font header table + #################/ + self.seek_table("head") + self.skip(18) + self.unitsPerEm = unitsPerEm = self.read_ushort() + scale = 1000 / float(unitsPerEm) + self.skip(16) + xMin = self.read_short() + yMin = self.read_short() + xMax = self.read_short() + yMax = self.read_short() + self.bbox = [(xMin*scale), (yMin*scale), (xMax*scale), (yMax*scale)] + self.skip(3*2) + indexToLocFormat = self.read_ushort() + glyphDataFormat = self.read_ushort() + if (glyphDataFormat != 0): + die('Unknown glyph data format ' + glyphDataFormat) + + #################/ + # hhea metrics table + #################/ + # ttf2t1 seems to use this value rather than the one in OS/2 - so put in for compatibility + if ("hhea" in self.tables): + self.seek_table("hhea") + self.skip(4) + hheaAscender = self.read_short() + hheaDescender = self.read_short() + self.ascent = (hheaAscender *scale) + self.descent = (hheaDescender *scale) + + + #################/ + # OS/2 - OS/2 and Windows metrics table + #################/ + if ("OS/2" in self.tables): + self.seek_table("OS/2") + version = self.read_ushort() + self.skip(2) + usWeightClass = self.read_ushort() + self.skip(2) + fsType = self.read_ushort() + if (fsType == 0x0002 or (fsType & 0x0300) != 0): + die('ERROR - Font file ' + self.filename + ' cannot be embedded due to copyright restrictions.') + self.restrictedUse = True + + self.skip(20) + sF = self.read_short() + self.sFamilyClass = (sF >> 8) + self.sFamilySubClass = (sF & 0xFF) + self._pos += 10 #PANOSE = 10 byte length + panose = self.fh.read(10) + self.skip(26) + sTypoAscender = self.read_short() + sTypoDescender = self.read_short() + if (not self.ascent): + self.ascent = (sTypoAscender*scale) + if (not self.descent): + self.descent = (sTypoDescender*scale) + if (version > 1): + self.skip(16) + sCapHeight = self.read_short() + self.capHeight = (sCapHeight*scale) + else: + self.capHeight = self.ascent + + else: + usWeightClass = 500 + if (not self.ascent): self.ascent = (yMax*scale) + if (not self.descent): self.descent = (yMin*scale) + self.capHeight = self.ascent + + self.stemV = 50 + int(pow((usWeightClass / 65.0),2)) + + #################/ + # post - PostScript table + #################/ + self.seek_table("post") + self.skip(4) + self.italicAngle = self.read_short() + self.read_ushort() / 65536.0 + self.underlinePosition = self.read_short() * scale + self.underlineThickness = self.read_short() * scale + isFixedPitch = self.read_ulong() + + self.flags = 4 + + if (self.italicAngle!= 0): + self.flags = self.flags | 64 + if (usWeightClass >= 600): + self.flags = self.flags | 262144 + if (isFixedPitch): + self.flags = self.flags | 1 + + #################/ + # hhea - Horizontal header table + #################/ + self.seek_table("hhea") + self.skip(32) + metricDataFormat = self.read_ushort() + if (metricDataFormat != 0): + die('Unknown horizontal metric data format '.metricDataFormat) + numberOfHMetrics = self.read_ushort() + if (numberOfHMetrics == 0): + die('Number of horizontal metrics is 0') + + #################/ + # maxp - Maximum profile table + #################/ + self.seek_table("maxp") + self.skip(4) + numGlyphs = self.read_ushort() + + #################/ + # cmap - Character to glyph index mapping table + #################/ + cmap_offset = self.seek_table("cmap") + self.skip(2) + cmapTableCount = self.read_ushort() + unicode_cmap_offset = 0 + for i in range(cmapTableCount): + platformID = self.read_ushort() + encodingID = self.read_ushort() + offset = self.read_ulong() + save_pos = self._pos + if ((platformID == 3 and encodingID == 1) or platformID == 0): # Microsoft, Unicode + format = self.get_ushort(cmap_offset + offset) + if (format == 4): + if (not unicode_cmap_offset): + unicode_cmap_offset = cmap_offset + offset + break + self.seek(save_pos ) + + if (not unicode_cmap_offset): + die('Font (' + self.filename + ') does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)') + + glyphToChar = {} + charToGlyph = {} + self.getCMAP4(unicode_cmap_offset, glyphToChar, charToGlyph ) + + #################/ + # hmtx - Horizontal metrics table + #################/ + self.getHMTX(numberOfHMetrics, numGlyphs, glyphToChar, scale) + + +############################################/ +############################################/ + + def makeSubset(self, file, subset): + self.filename = file + self.fh = open(file ,'rb') + self._pos = 0 + self.charWidths = [] + self.glyphPos = {} + self.charToGlyph = {} + self.tables = {} + self.otables = {} + self.ascent = 0 + self.descent = 0 + self.skip(4) + self.maxUni = 0 + self.readTableDirectory() + + #################/ + # head - Font header table + #################/ + self.seek_table("head") + self.skip(50) + indexToLocFormat = self.read_ushort() + glyphDataFormat = self.read_ushort() + + #################/ + # hhea - Horizontal header table + #################/ + self.seek_table("hhea") + self.skip(32) + metricDataFormat = self.read_ushort() + orignHmetrics = numberOfHMetrics = self.read_ushort() + + #################/ + # maxp - Maximum profile table + #################/ + self.seek_table("maxp") + self.skip(4) + numGlyphs = self.read_ushort() + + #################/ + # cmap - Character to glyph index mapping table + #################/ + cmap_offset = self.seek_table("cmap") + self.skip(2) + cmapTableCount = self.read_ushort() + unicode_cmap_offset = 0 + for i in range(cmapTableCount): + platformID = self.read_ushort() + encodingID = self.read_ushort() + offset = self.read_ulong() + save_pos = self._pos + if ((platformID == 3 and encodingID == 1) or platformID == 0): # Microsoft, Unicode + format = self.get_ushort(cmap_offset + offset) + if (format == 4): + unicode_cmap_offset = cmap_offset + offset + break + + self.seek(save_pos ) + + if (not unicode_cmap_offset): + die('Font (' + self.filename + ') does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)') + + glyphToChar = {} + charToGlyph = {} + self.getCMAP4(unicode_cmap_offset, glyphToChar, charToGlyph ) + + self.charToGlyph = charToGlyph + + #################/ + # hmtx - Horizontal metrics table + #################/ + scale = 1 # not used + self.getHMTX(numberOfHMetrics, numGlyphs, glyphToChar, scale) + + #################/ + # loca - Index to location + #################/ + self.getLOCA(indexToLocFormat, numGlyphs) + + subsetglyphs = [(0, 0)] # special "sorted dict"! + subsetCharToGlyph = {} + for code in subset: + if (code in self.charToGlyph): + if (self.charToGlyph[code], code) not in subsetglyphs: + subsetglyphs.append((self.charToGlyph[code], code)) # Old Glyph ID => Unicode + subsetCharToGlyph[code] = self.charToGlyph[code] # Unicode to old GlyphID + self.maxUni = max(self.maxUni, code) + (start,dummy) = self.get_table_pos('glyf') + + subsetglyphs.sort() + glyphSet = {} + n = 0 + fsLastCharIndex = 0 # maximum Unicode index (character code) in this font, according to the cmap subtable for platform ID 3 and platform- specific encoding ID 0 or 1. + for originalGlyphIdx, uni in subsetglyphs: + fsLastCharIndex = max(fsLastCharIndex , uni) + glyphSet[originalGlyphIdx] = n # old glyphID to new glyphID + n += 1 + + codeToGlyph = {} + for uni, originalGlyphIdx in sorted(subsetCharToGlyph.items()): + codeToGlyph[uni] = glyphSet[originalGlyphIdx] + + self.codeToGlyph = codeToGlyph + + for originalGlyphIdx, uni in subsetglyphs: + nonlocals = {'start': start, 'glyphSet': glyphSet, + 'subsetglyphs': subsetglyphs} + self.getGlyphs(originalGlyphIdx, nonlocals) + + numGlyphs = numberOfHMetrics = len(subsetglyphs) + + #tables copied from the original + tags = ['name'] + for tag in tags: + self.add(tag, self.get_table(tag)) + tags = ['cvt ', 'fpgm', 'prep', 'gasp'] + for tag in tags: + if (tag in self.tables): + self.add(tag, self.get_table(tag)) + + # post - PostScript + opost = self.get_table('post') + post = "\x00\x03\x00\x00" + substr(opost,4,12) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + self.add('post', post) + + # Sort CID2GID map into segments of contiguous codes + if 0 in codeToGlyph: + del codeToGlyph[0] + #unset(codeToGlyph[65535]) + rangeid = 0 + range_ = {} + prevcid = -2 + prevglidx = -1 + # for each character + for cid, glidx in sorted(codeToGlyph.items()): + if (cid == (prevcid + 1) and glidx == (prevglidx + 1)): + range_[rangeid].append(glidx) + else: + # new range + rangeid = cid + range_[rangeid] = [] + range_[rangeid].append(glidx) + prevcid = cid + prevglidx = glidx + + # cmap - Character to glyph mapping - Format 4 (MS / ) + segCount = len(range_) + 1 # + 1 Last segment has missing character 0xFFFF + searchRange = 1 + entrySelector = 0 + while (searchRange * 2 <= segCount ): + searchRange = searchRange * 2 + entrySelector = entrySelector + 1 + + searchRange = searchRange * 2 + rangeShift = segCount * 2 - searchRange + length = 16 + (8*segCount ) + (numGlyphs+1) + cmap = [0, 1, # Index : version, number of encoding subtables + 3, 1, # Encoding Subtable : platform (MS=3), encoding (Unicode) + 0, 12, # Encoding Subtable : offset (hi,lo) + 4, length, 0, # Format 4 Mapping subtable: format, length, language + segCount*2, + searchRange, + entrySelector, + rangeShift] + + range_ = sorted(range_.items()) + + # endCode(s) + for start, subrange in range_: + endCode = start + (len(subrange)-1) + cmap.append(endCode) # endCode(s) + + cmap.append(0xFFFF) # endCode of last Segment + cmap.append(0) # reservedPad + + # startCode(s) + for start, subrange in range_: + cmap.append(start) # startCode(s) + + cmap.append(0xFFFF) # startCode of last Segment + # idDelta(s) + for start, subrange in range_: + idDelta = -(start-subrange[0]) + n += count(subrange) + cmap.append(idDelta) # idDelta(s) + + cmap.append(1) # idDelta of last Segment + # idRangeOffset(s) + for subrange in range_: + cmap.append(0) # idRangeOffset[segCount] Offset in bytes to glyph indexArray, or 0 + + cmap.append(0) # idRangeOffset of last Segment + for subrange, glidx in range_: + cmap.extend(glidx) + + cmap.append(0) # Mapping for last character + cmapstr = '' + for cm in cmap: + if cm >= 0: + cmapstr += pack(">H", cm) + else: + try: + cmapstr += pack(">h", cm) + except: + warnings.warn("cmap value too big/small: %s" % cm) + cmapstr += pack(">H", -cm) + self.add('cmap', cmapstr) + + # glyf - Glyph data + (glyfOffset,glyfLength) = self.get_table_pos('glyf') + if (glyfLength < self.maxStrLenRead): + glyphData = self.get_table('glyf') + + offsets = [] + glyf = '' + pos = 0 + + hmtxstr = '' + xMinT = 0 + yMinT = 0 + xMaxT = 0 + yMaxT = 0 + advanceWidthMax = 0 + minLeftSideBearing = 0 + minRightSideBearing = 0 + xMaxExtent = 0 + maxPoints = 0 # points in non-compound glyph + maxContours = 0 # contours in non-compound glyph + maxComponentPoints = 0 # points in compound glyph + maxComponentContours = 0 # contours in compound glyph + maxComponentElements = 0 # number of glyphs referenced at top level + maxComponentDepth = 0 # levels of recursion, set to 0 if font has only simple glyphs + self.glyphdata = {} + + for originalGlyphIdx, uni in subsetglyphs: + # hmtx - Horizontal Metrics + hm = self.getHMetric(orignHmetrics, originalGlyphIdx) + hmtxstr += hm + + offsets.append(pos) + try: + glyphPos = self.glyphPos[originalGlyphIdx] + glyphLen = self.glyphPos[originalGlyphIdx + 1] - glyphPos + except IndexError: + warnings.warn("missing glyph %s" % (originalGlyphIdx)) + glyphLen = 0 + + if (glyfLength < self.maxStrLenRead): + data = substr(glyphData,glyphPos,glyphLen) + else: + if (glyphLen > 0): + data = self.get_chunk(glyfOffset+glyphPos,glyphLen) + else: + data = '' + + if (glyphLen > 0): + up = unpack(">H", substr(data,0,2))[0] + if (glyphLen > 2 and (up & (1 << 15)) ): # If number of contours <= -1 i.e. composiste glyph + pos_in_glyph = 10 + flags = GF_MORE + nComponentElements = 0 + while (flags & GF_MORE): + nComponentElements += 1 # number of glyphs referenced at top level + up = unpack(">H", substr(data,pos_in_glyph,2)) + flags = up[0] + up = unpack(">H", substr(data,pos_in_glyph+2,2)) + glyphIdx = up[0] + self.glyphdata.setdefault(originalGlyphIdx, {}).setdefault('compGlyphs', []).append(glyphIdx) + try: + data = self._set_ushort(data, pos_in_glyph + 2, glyphSet[glyphIdx]) + except KeyError: + data = 0 + warnings.warn("missing glyph data %s" % glyphIdx) + pos_in_glyph += 4 + if (flags & GF_WORDS): + pos_in_glyph += 4 + else: + pos_in_glyph += 2 + if (flags & GF_SCALE): + pos_in_glyph += 2 + elif (flags & GF_XYSCALE): + pos_in_glyph += 4 + elif (flags & GF_TWOBYTWO): + pos_in_glyph += 8 + + maxComponentElements = max(maxComponentElements, nComponentElements) + + glyf += data + pos += glyphLen + if (pos % 4 != 0): + padding = 4 - (pos % 4) + glyf += str_repeat("\0",padding) + pos += padding + + offsets.append(pos) + self.add('glyf', glyf) + + # hmtx - Horizontal Metrics + self.add('hmtx', hmtxstr) + + # loca - Index to location + locastr = '' + if (((pos + 1) >> 1) > 0xFFFF): + indexToLocFormat = 1 # long format + for offset in offsets: + locastr += pack(">L",offset) + else: + indexToLocFormat = 0 # short format + for offset in offsets: + locastr += pack(">H",(offset/2)) + + self.add('loca', locastr) + + # head - Font header + head = self.get_table('head') + head = self._set_ushort(head, 50, indexToLocFormat) + self.add('head', head) + + # hhea - Horizontal Header + hhea = self.get_table('hhea') + hhea = self._set_ushort(hhea, 34, numberOfHMetrics) + self.add('hhea', hhea) + + # maxp - Maximum Profile + maxp = self.get_table('maxp') + maxp = self._set_ushort(maxp, 4, numGlyphs) + self.add('maxp', maxp) + + # OS/2 - OS/2 + os2 = self.get_table('OS/2') + self.add('OS/2', os2 ) + + self.fh.close() + + # Put the TTF file together + stm = self.endTTFile('') + return stm + + + ######################################### + # Recursively get composite glyph data + def getGlyphData(self, originalGlyphIdx, nonlocals): + # &maxdepth, &depth, &points, &contours + nonlocals['depth'] += 1 + nonlocals['maxdepth'] = max(nonlocals['maxdepth'], nonlocals['depth']) + if (len(self.glyphdata[originalGlyphIdx]['compGlyphs'])): + for glyphIdx in self.glyphdata[originalGlyphIdx]['compGlyphs']: + self.getGlyphData(glyphIdx, nonlocals) + + elif ((self.glyphdata[originalGlyphIdx]['nContours'] > 0) and nonlocals['depth'] > 0): # simple + contours += self.glyphdata[originalGlyphIdx]['nContours'] + points += self.glyphdata[originalGlyphIdx]['nPoints'] + + nonlocals['depth'] -= 1 + + + ######################################### + # Recursively get composite glyphs + def getGlyphs(self, originalGlyphIdx, nonlocals): + # &start, &glyphSet, &subsetglyphs) + + try: + glyphPos = self.glyphPos[originalGlyphIdx] + glyphLen = self.glyphPos[originalGlyphIdx + 1] - glyphPos + except IndexError: + warnings.warn("missing glyph %s" % (originalGlyphIdx)) + return + + if (not glyphLen): + return + + self.seek(nonlocals['start'] + glyphPos) + numberOfContours = self.read_short() + if (numberOfContours < 0): + self.skip(8) + flags = GF_MORE + while (flags & GF_MORE): + flags = self.read_ushort() + glyphIdx = self.read_ushort() + if (glyphIdx not in nonlocals['glyphSet']): + nonlocals['glyphSet'][glyphIdx] = len(nonlocals['subsetglyphs']) # old glyphID to new glyphID + nonlocals['subsetglyphs'].append((glyphIdx, 1)) + + savepos = self.fh.tell() + self.getGlyphs(glyphIdx, nonlocals) + self.seek(savepos) + if (flags & GF_WORDS): + self.skip(4) + else: + self.skip(2) + if (flags & GF_SCALE): + self.skip(2) + elif (flags & GF_XYSCALE): + self.skip(4) + elif (flags & GF_TWOBYTWO): + self.skip(8) + + ######################################### + + def getHMTX(self, numberOfHMetrics, numGlyphs, glyphToChar, scale): + start = self.seek_table("hmtx") + aw = 0 + self.charWidths = [0] * 256*256*2 + nCharWidths = 0 + if ((numberOfHMetrics*4) < self.maxStrLenRead): + data = self.get_chunk(start,(numberOfHMetrics*4)) + arr = unpack(">" + "H" * (len(data)/2), data) + else: + self.seek(start) + for glyph in range(numberOfHMetrics): + if ((numberOfHMetrics*4) < self.maxStrLenRead): + aw = arr[(glyph*2)] # PHP starts arrays from index 0!? +1 + else: + aw = self.read_ushort() + lsb = self.read_ushort() + + if (glyph in glyphToChar or glyph == 0): + if (aw >= (1 << 15) ): + aw = 0 # 1.03 Some (arabic) fonts have -ve values for width + # although should be unsigned value - comes out as e.g. 65108 (intended -50) + if (glyph == 0): + self.defaultWidth = scale*aw + continue + + for char in glyphToChar[glyph]: + if (char != 0 and char != 65535): + w = int(round(scale*aw)) + if (w == 0): w = 65535 + if (char < 196608): + self.charWidths[char] = w + nCharWidths += 1 + + + data = self.get_chunk((start+numberOfHMetrics*4),(numGlyphs*2)) + arr = unpack(">" + "H" * (len(data)/2), data) + diff = numGlyphs-numberOfHMetrics + for pos in range(diff): + glyph = pos + numberOfHMetrics + if (glyph in glyphToChar): + for char in glyphToChar[glyph]: + if (char != 0 and char != 65535): + w = int(round(scale*aw)) + if (w == 0): w = 65535 + if (char < 196608): + self.charWidths[char] = w + nCharWidths += 1 + + + # NB 65535 is a set width of 0 + # First bytes define number of chars in font + self.charWidths[0] = nCharWidths + + + def getHMetric(self, numberOfHMetrics, gid): + start = self.seek_table("hmtx") + if (gid < numberOfHMetrics): + self.seek(start+(gid*4)) + hm = self.fh.read(4) + else: + self.seek(start+((numberOfHMetrics-1)*4)) + hm = self.fh.read(2) + self.seek(start+(numberOfHMetrics*2)+(gid*2)) + hm += self.fh.read(2) + return hm + + + def getLOCA(self, indexToLocFormat, numGlyphs): + start = self.seek_table('loca') + self.glyphPos = [] + if (indexToLocFormat == 0): + data = self.get_chunk(start,(numGlyphs*2)+2) + arr = unpack(">" + "H" * (len(data)/2), data) + for n in range(numGlyphs): + self.glyphPos.append((arr[n] * 2)) # n+1 !? + elif (indexToLocFormat == 1): + data = self.get_chunk(start,(numGlyphs*4)+4) + arr = unpack(">" + "L" * (len(data)/4), data) + for n in range(numGlyphs): + self.glyphPos.append((arr[n])) # n+1 !? + else: + die('Unknown location table format ' + indexToLocFormat) + + # CMAP Format 4 + def getCMAP4(self, unicode_cmap_offset, glyphToChar, charToGlyph ): + self.maxUniChar = 0 + self.seek(unicode_cmap_offset + 2) + length = self.read_ushort() + limit = unicode_cmap_offset + length + self.skip(2) + + segCount = self.read_ushort() / 2 + self.skip(6) + endCount = [] + for i in range(segCount): + endCount.append(self.read_ushort()) + self.skip(2) + startCount = [] + for i in range(segCount): + startCount.append(self.read_ushort()) + idDelta = [] + for i in range(segCount): + idDelta.append(self.read_short()) # ???? was unsigned short + idRangeOffset_start = self._pos + idRangeOffset = [] + for i in range(segCount): + idRangeOffset.append(self.read_ushort()) + + for n in range(segCount): + endpoint = (endCount[n] + 1) + for unichar in range(startCount[n], endpoint, 1): + if (idRangeOffset[n] == 0): + glyph = (unichar + idDelta[n]) & 0xFFFF + else: + offset = (unichar - startCount[n]) * 2 + idRangeOffset[n] + offset = idRangeOffset_start + 2 * n + offset + if (offset >= limit): + glyph = 0 + else: + glyph = self.get_ushort(offset) + if (glyph != 0): + glyph = (glyph + idDelta[n]) & 0xFFFF + + charToGlyph[unichar] = glyph + if (unichar < 196608): + self.maxUniChar = max(unichar,self.maxUniChar) + glyphToChar.setdefault(glyph, []).append(unichar) + + + # Put the TTF file together + def endTTFile(self, stm): + stm = '' + numTables = count(self.otables) + searchRange = 1 + entrySelector = 0 + while (searchRange * 2 <= numTables): + searchRange = searchRange * 2 + entrySelector = entrySelector + 1 + + searchRange = searchRange * 16 + rangeShift = numTables * 16 - searchRange + + # Header + if (_TTF_MAC_HEADER): + stm += (pack(">LHHHH", 0x74727565, numTables, searchRange, entrySelector, rangeShift)) # Mac + else: + stm += (pack(">LHHHH", 0x00010000 , numTables, searchRange, entrySelector, rangeShift)) # Windows + + + # Table directory + tables = self.otables + + offset = 12 + numTables * 16 + sorted_tables = sorted(tables.items()) + for tag, data in sorted_tables: + if (tag == 'head'): + head_start = offset + stm += tag + checksum = calcChecksum(data) + stm += pack(">HH", checksum[0],checksum[1]) + stm += pack(">LL", offset, strlen(data)) + paddedLength = (strlen(data)+3)&~3 + offset = offset + paddedLength + + # Table data + for tag, data in sorted_tables: + data += "\0\0\0" + stm += substr(data,0,(strlen(data)&~3)) + + checksum = calcChecksum(stm) + checksum = sub32((0xB1B0,0xAFBA), checksum) + chk = pack(">HH", checksum[0],checksum[1]) + stm = self.splice(stm,(head_start + 8),chk) + return stm + +if __name__ == '__main__': + ttf = TTFontFile() + ttffile = 'DejaVuSansCondensed.ttf'; + ttf.getMetrics(ttffile) + # test basic metrics: + assert round(ttf.descent, 0) == -236 + assert round(ttf.capHeight, 0) == 928 + assert ttf.flags == 4 + assert [round(i, 0) for i in ttf.bbox] == [-918, -415, 1513, 1167] + assert ttf.italicAngle == 0 + assert ttf.stemV == 87 + assert round(ttf.defaultWidth, 0) == 540 + assert round(ttf.underlinePosition, 0) == -63 + assert round(ttf.underlineThickness, 0) == 44 + # test char widths 8(against binary file generated by tfpdf.php): + assert ''.join(ttf.charWidths) == open("dejavusanscondensed.cw.dat").read() + \ No newline at end of file From d03bf8af8854a6b4d387d27cbc9ee9299a5bda75 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 08:35:41 -0500 Subject: [PATCH 02/53] moved pyfpdf to fpdf, thanks Mariano --- VERSION | 2 +- gluon/contrib/{pyfpdf => fpdf}/__init__.py | 0 gluon/contrib/{pyfpdf => fpdf}/fonts.py | 0 gluon/contrib/{pyfpdf => fpdf}/fpdf.py | 0 gluon/contrib/{pyfpdf => fpdf}/html.py | 0 gluon/contrib/{pyfpdf => fpdf}/php.py | 0 gluon/contrib/{pyfpdf => fpdf}/template.py | 0 gluon/contrib/{pyfpdf => fpdf}/ttfonts.py | 0 gluon/contrib/pyfpdf.py | 11 +++++++++++ 9 files changed, 12 insertions(+), 1 deletion(-) rename gluon/contrib/{pyfpdf => fpdf}/__init__.py (100%) rename gluon/contrib/{pyfpdf => fpdf}/fonts.py (100%) rename gluon/contrib/{pyfpdf => fpdf}/fpdf.py (100%) rename gluon/contrib/{pyfpdf => fpdf}/html.py (100%) rename gluon/contrib/{pyfpdf => fpdf}/php.py (100%) rename gluon/contrib/{pyfpdf => fpdf}/template.py (100%) rename gluon/contrib/{pyfpdf => fpdf}/ttfonts.py (100%) create mode 100644 gluon/contrib/pyfpdf.py diff --git a/VERSION b/VERSION index 775477a3..234bace8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 08:31:01) dev +Version 2.00.0 (2012-08-23 08:35:38) dev diff --git a/gluon/contrib/pyfpdf/__init__.py b/gluon/contrib/fpdf/__init__.py similarity index 100% rename from gluon/contrib/pyfpdf/__init__.py rename to gluon/contrib/fpdf/__init__.py diff --git a/gluon/contrib/pyfpdf/fonts.py b/gluon/contrib/fpdf/fonts.py similarity index 100% rename from gluon/contrib/pyfpdf/fonts.py rename to gluon/contrib/fpdf/fonts.py diff --git a/gluon/contrib/pyfpdf/fpdf.py b/gluon/contrib/fpdf/fpdf.py similarity index 100% rename from gluon/contrib/pyfpdf/fpdf.py rename to gluon/contrib/fpdf/fpdf.py diff --git a/gluon/contrib/pyfpdf/html.py b/gluon/contrib/fpdf/html.py similarity index 100% rename from gluon/contrib/pyfpdf/html.py rename to gluon/contrib/fpdf/html.py diff --git a/gluon/contrib/pyfpdf/php.py b/gluon/contrib/fpdf/php.py similarity index 100% rename from gluon/contrib/pyfpdf/php.py rename to gluon/contrib/fpdf/php.py diff --git a/gluon/contrib/pyfpdf/template.py b/gluon/contrib/fpdf/template.py similarity index 100% rename from gluon/contrib/pyfpdf/template.py rename to gluon/contrib/fpdf/template.py diff --git a/gluon/contrib/pyfpdf/ttfonts.py b/gluon/contrib/fpdf/ttfonts.py similarity index 100% rename from gluon/contrib/pyfpdf/ttfonts.py rename to gluon/contrib/fpdf/ttfonts.py diff --git a/gluon/contrib/pyfpdf.py b/gluon/contrib/pyfpdf.py new file mode 100644 index 00000000..26fc2940 --- /dev/null +++ b/gluon/contrib/pyfpdf.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"FPDF for python (a.k.a. pyfpdf)" +# Read more about this http://code.google.com/p/pyfpdf +# Please note that new package name is fpdf (to avoid some naming conflicts) +# import fpdf into pyfpdf for backward compatibility (prior web2py 2.0): +from fpdf import * + +# import warnings +# warnings.warn("pyfpdf package name is deprecated, please use fpdf instead") From 36c191588381249d366e1884cb1387eea212e043 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 08:36:50 -0500 Subject: [PATCH 03/53] removed unwanted trailing spaces from fpdf --- VERSION | 2 +- gluon/contrib/fpdf/__init__.py | 2 + gluon/contrib/fpdf/fonts.py | 5 +- gluon/contrib/fpdf/fpdf.py | 59 +++--- gluon/contrib/fpdf/html.py | 19 +- gluon/contrib/fpdf/php.py | 12 +- gluon/contrib/fpdf/template.py | 31 +-- gluon/contrib/fpdf/ttfonts.py | 354 ++++++++++++++++----------------- 8 files changed, 245 insertions(+), 239 deletions(-) diff --git a/VERSION b/VERSION index 234bace8..03475297 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 08:35:38) dev +Version 2.00.0 (2012-08-23 08:36:47) dev diff --git a/gluon/contrib/fpdf/__init__.py b/gluon/contrib/fpdf/__init__.py index 3ba17860..e0ffc017 100644 --- a/gluon/contrib/fpdf/__init__.py +++ b/gluon/contrib/fpdf/__init__.py @@ -14,3 +14,5 @@ except ImportError: warnings.warn("web2py gluon package not installed, required for html2pdf") from template import Template + + diff --git a/gluon/contrib/fpdf/fonts.py b/gluon/contrib/fpdf/fonts.py index 433fbf61..f584a1e8 100644 --- a/gluon/contrib/fpdf/fonts.py +++ b/gluon/contrib/fpdf/fonts.py @@ -83,7 +83,7 @@ fpdf_charwidths['symbol']={ '\xc6':823,'\xc7':768,'\xc8':768,'\xc9':713,'\xca':713,'\xcb':713,'\xcc':713,'\xcd':713,'\xce':713,'\xcf':713,'\xd0':768,'\xd1':713,'\xd2':790,'\xd3':790,'\xd4':890,'\xd5':823,'\xd6':549,'\xd7':250,'\xd8':713,'\xd9':603,'\xda':603,'\xdb':1042, '\xdc':987,'\xdd':603,'\xde':987,'\xdf':603,'\xe0':494,'\xe1':329,'\xe2':790,'\xe3':790,'\xe4':786,'\xe5':713,'\xe6':384,'\xe7':384,'\xe8':384,'\xe9':384,'\xea':384,'\xeb':384,'\xec':494,'\xed':494,'\xee':494,'\xef':494,'\xf0':0,'\xf1':329, '\xf2':274,'\xf3':686,'\xf4':686,'\xf5':686,'\xf6':384,'\xf7':384,'\xf8':384,'\xf9':384,'\xfa':384,'\xfb':384,'\xfc':494,'\xfd':494,'\xfe':494,'\xff':0} - + fpdf_charwidths['times']={ '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':333,'"':408,'#':500,'$':500,'%':833,'&':778,'\'':180,'(':333,')':333,'*':500,'+':564, @@ -111,7 +111,7 @@ fpdf_charwidths['timesB']={ '\xc6':1000,'\xc7':722,'\xc8':667,'\xc9':667,'\xca':667,'\xcb':667,'\xcc':389,'\xcd':389,'\xce':389,'\xcf':389,'\xd0':722,'\xd1':722,'\xd2':778,'\xd3':778,'\xd4':778,'\xd5':778,'\xd6':778,'\xd7':570,'\xd8':778,'\xd9':722,'\xda':722,'\xdb':722, '\xdc':722,'\xdd':722,'\xde':611,'\xdf':556,'\xe0':500,'\xe1':500,'\xe2':500,'\xe3':500,'\xe4':500,'\xe5':500,'\xe6':722,'\xe7':444,'\xe8':444,'\xe9':444,'\xea':444,'\xeb':444,'\xec':278,'\xed':278,'\xee':278,'\xef':278,'\xf0':500,'\xf1':556, '\xf2':500,'\xf3':500,'\xf4':500,'\xf5':500,'\xf6':500,'\xf7':570,'\xf8':500,'\xf9':556,'\xfa':556,'\xfb':556,'\xfc':556,'\xfd':500,'\xfe':556,'\xff':500} - + fpdf_charwidths['timesBI']={ '\x00':250,'\x01':250,'\x02':250,'\x03':250,'\x04':250,'\x05':250,'\x06':250,'\x07':250,'\x08':250,'\t':250,'\n':250,'\x0b':250,'\x0c':250,'\r':250,'\x0e':250,'\x0f':250,'\x10':250,'\x11':250,'\x12':250,'\x13':250,'\x14':250,'\x15':250, '\x16':250,'\x17':250,'\x18':250,'\x19':250,'\x1a':250,'\x1b':250,'\x1c':250,'\x1d':250,'\x1e':250,'\x1f':250,' ':250,'!':389,'"':555,'#':500,'$':500,'%':833,'&':778,'\'':278,'(':333,')':333,'*':500,'+':570, @@ -154,3 +154,4 @@ fpdf_charwidths['zapfdingbats']={ '\xdc':927,'\xdd':928,'\xde':928,'\xdf':834,'\xe0':873,'\xe1':828,'\xe2':924,'\xe3':924,'\xe4':917,'\xe5':930,'\xe6':931,'\xe7':463,'\xe8':883,'\xe9':836,'\xea':836,'\xeb':867,'\xec':867,'\xed':696,'\xee':696,'\xef':874,'\xf0':0,'\xf1':874, '\xf2':760,'\xf3':946,'\xf4':771,'\xf5':865,'\xf6':771,'\xf7':888,'\xf8':967,'\xf9':888,'\xfa':831,'\xfb':873,'\xfc':927,'\xfd':970,'\xfe':918,'\xff':0} + diff --git a/gluon/contrib/fpdf/fpdf.py b/gluon/contrib/fpdf/fpdf.py index dd8d2a7f..4f9a3eb5 100644 --- a/gluon/contrib/fpdf/fpdf.py +++ b/gluon/contrib/fpdf/fpdf.py @@ -48,7 +48,7 @@ def set_global(var, val): class FPDF(object): "PDF Generation class" - + def __init__(self, orientation='P',unit='mm',format='A4'): # Some checks self._dochecks() @@ -352,7 +352,7 @@ class FPDF(object): elif (self.current_font['desc']['MissingWidth']) : w += self.current_font['desc']['MissingWidth'] #elif (isset($this->CurrentFont['MissingWidth'])) { $w += $this->CurrentFont['MissingWidth']; } - else: + else: w += 500 else: for i in xrange(0, l): @@ -397,10 +397,10 @@ class FPDF(object): global SYSTEM_TTFONTS if os.path.exists(fname): ttffilename = fname - elif (FPDF_FONT_DIR and + elif (FPDF_FONT_DIR and os.path.exists(os.path.join(FPDF_FONT_DIR, fname))): ttffilename = os.path.join(FPDF_FONT_DIR, fname) - elif (SYSTEM_TTFONTS and + elif (SYSTEM_TTFONTS and os.path.exists(os.path.join(SYSTEM_TTFONTS, fname))): ttffilename = os.path.join(SYSTEM_TTFONTS, fname) else: @@ -455,11 +455,11 @@ class FPDF(object): else: sbarr = range(0,32) self.fonts[fontkey] = { - 'i': len(self.fonts)+1, 'type': font_dict['type'], - 'name': font_dict['name'], 'desc': font_dict['desc'], - 'up': font_dict['up'], 'ut': font_dict['ut'], - 'cw': font_dict['cw'], - 'ttffile': font_dict['ttffile'], 'fontkey': fontkey, + 'i': len(self.fonts)+1, 'type': font_dict['type'], + 'name': font_dict['name'], 'desc': font_dict['desc'], + 'up': font_dict['up'], 'ut': font_dict['ut'], + 'cw': font_dict['cw'], + 'ttffile': font_dict['ttffile'], 'fontkey': fontkey, 'subset': sbarr, 'unifilename': unifilename, } self.font_files[fontkey] = {'length1': font_dict['originalsize'], @@ -490,7 +490,7 @@ class FPDF(object): if (type == 'TrueType'): self.font_files[filename]={'length1': originalsize} else: - self.font_files[filename]={'length1': size1, + self.font_files[filename]={'length1': size1, 'length2': size2} def set_font(self, family,style='',size=0): @@ -656,7 +656,7 @@ class FPDF(object): dx=self.c_margin if(self.color_flag): s+='q '+self.text_color+' ' - + # If multibyte, Tw has no effect - do word spacing using an adjustment before each space if (self.ws and self.unifontsubset): for uni in UTF8StringToArray(txt): @@ -680,9 +680,9 @@ class FPDF(object): for uni in UTF8StringToArray(txt): self.current_font['subset'].append(uni) else: - txt2 = txt.replace('\\','\\\\').replace(')','\\)').replace('(','\\(') + txt2 = txt.replace('\\','\\\\').replace(')','\\)').replace('(','\\(') s += sprintf('BT %.2f %.2f Td (%s) Tj ET',(self.x+dx)*k,(self.h-(self.y+.5*h+.3*self.font_size))*k,txt2) - + if(self.underline): s+=' '+self._dounderline(self.x+dx,self.y+.5*h+.3*self.font_size,txt) if(self.color_flag): @@ -760,7 +760,7 @@ class FPDF(object): sep=i ls=l ns+=1 - if self.unifontsubset: + if self.unifontsubset: l += self.get_string_width(c) / self.font_size*1000.0 else: l += cw.get(c,0) @@ -844,7 +844,7 @@ class FPDF(object): continue if(c==' '): sep=i - if self.unifontsubset: + if self.unifontsubset: l += self.get_string_width(c) / self.font_size*1000.0 else: l += cw.get(c,0) @@ -1198,7 +1198,7 @@ class FPDF(object): self._out('<>') @@ -1260,7 +1260,7 @@ class FPDF(object): for kd in ('Ascent', 'Descent', 'CapHeight', 'Flags', 'FontBBox', 'ItalicAngle', 'StemV', 'MissingWidth'): v = font['desc'][kd] if (kd == 'Flags'): - v = v | 4; + v = v | 4; v = v & ~32; # SYMBOLIC font flag self._out(' /%s %s' % (kd, v)) self._out('/FontFile2 ' + str(self.n + 2) + ' 0 R') @@ -1282,7 +1282,7 @@ class FPDF(object): self._putstream(cidtogidmap) self._out('endobj') - #Font file + #Font file self._newobj() self._out('< 255 and (cid not in font['subset']) or not cid): # + if (cid > 255 and (cid not in font['subset']) or not cid): # continue if ('dw' not in font or (font['dw'] and width != font['dw'])): if (cid == (prevcid + 1)): @@ -1396,7 +1396,7 @@ class FPDF(object): if (len(set(ws)) == 1): w.append(' %s %s %s' % (k, k + len(ws) - 1, ws[0])) else: - w.append(' %s [ %s ]\n' % (k, ' '.join([str(int(h)) for h in ws]))) ## + w.append(' %s [ %s ]\n' % (k, ' '.join([str(int(h)) for h in ws]))) ## self._out('/W [%s]' % ''.join(w)) def _putimages(self): @@ -1408,7 +1408,7 @@ class FPDF(object): del info['data'] if 'smask' in info: del info['smask'] - + def _putimage(self, info): if 'data' in info: self._newobj() @@ -1785,20 +1785,20 @@ class FPDF(object): def interleaved2of5(self, txt, x, y, w=1.0, h=10.0): "Barcode I2of5 (numeric), adds a 0 if odd lenght" - narrow = w / 3.0 + narrow = w / 3.0 wide = w - + # wide/narrow codes for the digits bar_char={'0': 'nnwwn', '1': 'wnnnw', '2': 'nwnnw', '3': 'wwnnn', '4': 'nnwnw', '5': 'wnwnn', '6': 'nwwnn', '7': 'nnnww', '8': 'wnnwn', '9': 'nwnwn', 'A': 'nn', 'Z': 'wn'} - + self.set_fill_color(0) code = txt # add leading zero if code-length is odd if len(code) % 2 != 0: code = '0' + code - + # add start and stop codes code = 'AA' + code.lower() + 'ZA' @@ -1837,7 +1837,7 @@ class FPDF(object): narrow = w / 3.0 gap = narrow - bar_char={'0': 'nnnwwnwnn', '1': 'wnnwnnnnw', '2': 'nnwwnnnnw', + bar_char={'0': 'nnnwwnwnn', '1': 'wnnwnnnnw', '2': 'nnwwnnnnw', '3': 'wnwwnnnnn', '4': 'nnnwwnnnw', '5': 'wnnwwnnnn', '6': 'nnwwwnnnn', '7': 'nnnwnnwnw', '8': 'wnnwnnwnn', '9': 'nnwwnnwnn', 'A': 'wnnnnwnnw', 'B': 'nnwnnwnnw', @@ -1854,8 +1854,8 @@ class FPDF(object): '+': 'nwnnnwnwn', '%': 'nnnwnwnwn'} self.set_fill_color(0) - code = txt - + code = txt + code = code.upper() for i in xrange (0, len(code), 2): char_bar = code[i] @@ -1865,7 +1865,7 @@ class FPDF(object): seq= '' for s in xrange(0, len(bar_char[char_bar])): - seq += bar_char[char_bar][s] + seq += bar_char[char_bar][s] for bar in xrange(0, len(seq)): if seq[bar] == 'n': @@ -1879,3 +1879,4 @@ class FPDF(object): x += gap + diff --git a/gluon/contrib/fpdf/html.py b/gluon/contrib/fpdf/html.py index bc1c53b7..95b7e8b3 100644 --- a/gluon/contrib/fpdf/html.py +++ b/gluon/contrib/fpdf/html.py @@ -35,7 +35,7 @@ class HTML2FPDF(HTMLParser): self.page_links = {} self.font_list = ("times","courier", "helvetica") self.font = None - self.font_stack = [] + self.font_stack = [] self.pdf = pdf self.r = self.g = self.b = 0 self.indent = 0 @@ -54,7 +54,7 @@ class HTML2FPDF(HTMLParser): self.thead = None self.tfoot = None self.theader_out = self.tfooter_out = False - + def width2mm(self, length): if length[-1]=='%': total = self.pdf.w - self.pdf.r_margin - self.pdf.l_margin @@ -101,13 +101,13 @@ class HTML2FPDF(HTMLParser): self.pdf.add_page() self.theader_out = self.tfooter_out = False if self.tfoot is None and self.thead is None: - if not self.theader_out: + if not self.theader_out: self.output_table_header() self.box_shadow(w, h, bgcolor) if DEBUG: print "td cell", self.pdf.x, w, txt, "*" self.pdf.cell(w,h,txt,border,0,align) elif self.table is not None: - # ignore anything else than td inside a table + # ignore anything else than td inside a table pass elif self.align: if DEBUG: print "cell", txt, "*" @@ -142,7 +142,7 @@ class HTML2FPDF(HTMLParser): self.pdf.set_x(self.table_offset) #self.pdf.set_x(x) self.theader_out = True - + def output_table_footer(self): if self.tfooter: x = self.pdf.x @@ -156,7 +156,7 @@ class HTML2FPDF(HTMLParser): if int(self.table.get('border', 0)): self.output_table_sep() self.tfooter_out = True - + def output_table_sep(self): self.pdf.set_x(self.table_offset) x1 = self.pdf.x @@ -335,7 +335,7 @@ class HTML2FPDF(HTMLParser): if face: self.pdf.set_text_color(0,0,0) self.color = None - self.set_font(face, size) + self.set_font(face, size) self.font = None if tag=='center': self.align = None @@ -352,7 +352,7 @@ class HTML2FPDF(HTMLParser): self.set_style('u', False) self.set_style('b', False) self.set_style('i', False) - self.set_text_color() + self.set_text_color() def set_style(self, tag=None, enable=None): #Modify style and select corresponding font @@ -374,7 +374,7 @@ class HTML2FPDF(HTMLParser): self.r = r self.g = g self.b = b - + def put_link(self, url, txt): #Put a hyperlink self.set_text_color(0,0,255) @@ -394,3 +394,4 @@ class HTMLMixin(object): h2p = HTML2FPDF(self) h2p.feed(text) + diff --git a/gluon/contrib/fpdf/php.py b/gluon/contrib/fpdf/php.py index 80a4622d..569bf9e0 100644 --- a/gluon/contrib/fpdf/php.py +++ b/gluon/contrib/fpdf/php.py @@ -15,12 +15,12 @@ def print_r(array): array = dict([(k, k) for k in array]) for k, v in array.items(): print "[%s] => %s" % (k, v), - + def UTF8ToUTF16BE(instr, setbom=True): "Converts UTF-8 strings to UTF16-BE." outstr = "" if (setbom): - outstr += "\xFE\xFF"; + outstr += "\xFE\xFF"; if not isinstance(instr, unicode): instr = instr.decode('UTF-8') outstr += instr.encode('UTF-16BE') @@ -30,14 +30,14 @@ def UTF8StringToArray(instr): "Converts UTF-8 strings to codepoints array" return [ord(c) for c in instr] -# ttfints php helpers: +# ttfints php helpers: def die(msg): raise RuntimeError(msg) - + def str_repeat(s, count): return s * count - + def str_pad(s, pad_length=0, pad_char= " ", pad_type= +1 ): if pad_type<0: # pad left return s.rjust(pad_length, pad_char) @@ -46,4 +46,4 @@ def str_pad(s, pad_length=0, pad_char= " ", pad_type= +1 ): else: # pad both return s.center(pad_length, pad_char) -strlen = count = lambda s: len(s) \ No newline at end of file +strlen = count = lambda s: len(s) diff --git a/gluon/contrib/fpdf/template.py b/gluon/contrib/fpdf/template.py index 2d38c9f9..651a1b83 100644 --- a/gluon/contrib/fpdf/template.py +++ b/gluon/contrib/fpdf/template.py @@ -18,7 +18,7 @@ class Template: if elements: self.elements = elements self.keys = [v['name'].lower() for v in self.elements] - self.handlers = {'T': self.text, 'L': self.line, 'I': self.image, + self.handlers = {'T': self.text, 'L': self.line, 'I': self.image, 'B': self.rect, 'BC': self.barcode, } self.pg_no = 0 self.texts = {} @@ -38,7 +38,7 @@ class Template: for row in csv.reader(open(infile, 'rb'), delimiter=delimiter): kargs = {} for i,v in enumerate(row): - if not v.startswith("'") and decimal_sep!=".": + if not v.startswith("'") and decimal_sep!=".": v = v.replace(decimal_sep,".") else: v = v @@ -53,7 +53,7 @@ class Template: def add_page(self): self.pg_no += 1 self.texts[self.pg_no] = {} - + def __setitem__(self, name, value): if self.has_key(name): if isinstance(value,unicode): @@ -69,7 +69,7 @@ class Template: def has_key(self, name): return name.lower() in self.keys - + def __getitem__(self, name): if self.has_key(name): key = name.lower() @@ -101,7 +101,7 @@ class Template: return pdf.multi_cell(w=element['x2']-element['x1'], h=element['y2']-element['y1'], txt=text,align=align,split_only=True) - + def render(self, outfile, dest="F"): pdf = self.pdf for pg in range(1, self.pg_no+1): @@ -118,11 +118,11 @@ class Template: self.handlers[element['type'].upper()](pdf, **element) if 'rotate' in element: pdf.rotate(0) - + return pdf.output(outfile, dest) - - def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10, - bold=False, italic=False, underline=False, align="", + + def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10, + bold=False, italic=False, underline=False, align="", foreground=0, backgroud=65535, multiline=None, *args, **kwargs): if text: @@ -201,7 +201,7 @@ if __name__ == "__main__": title="Sample Invoice", author="Sample Company", subject="Sample Customer", keywords="Electronic TAX Invoice") f.parse_csv(infile="invoice.csv", delimiter=";", decimal_sep=",") - + detail = "Lorem ipsum dolor sit amet, consectetur. " * 30 items = [] for i in range(1, 30): @@ -210,7 +210,7 @@ if __name__ == "__main__": price = round(random.random()*100,3) code = "%s%s%02d" % (chr(random.randint(65,90)), chr(random.randint(65,90)),i) items.append(dict(code=code, unit='u', - qty=qty, price=price, + qty=qty, price=price, amount=qty*price, ds="%s: %s" % (i,ds))) @@ -253,7 +253,7 @@ if __name__ == "__main__": f["company_name"] = "Sample Company" f["company_logo"] = "tutorial/logo.png" f["company_header1"] = "Some Address - somewhere -" - f["company_header2"] = "http://www.example.com" + f["company_header2"] = "http://www.example.com" f["company_footer1"] = "Tax Code ..." f["company_footer2"] = "Tax/VAT ID ..." f['number'] = '0001-00001234' @@ -261,9 +261,9 @@ if __name__ == "__main__": f['due_date'] = '2099-09-10' f['customer_name'] = "Sample Client" f['customer_address'] = "Siempreviva 1234" - + # print line item... - li = 0 + li = 0 k = 0 total = Decimal("0.00") for it in li_items: @@ -293,9 +293,10 @@ if __name__ == "__main__": else: f['total_label'] = 'SubTotal:' f['total'] = "%0.2f" % total - + f.render("./invoice.pdf") if sys.platform.startswith("linux"): os.system("evince ./invoice.pdf") else: os.system("./invoice.pdf") + diff --git a/gluon/contrib/fpdf/ttfonts.py b/gluon/contrib/fpdf/ttfonts.py index cdb280a3..ddab0798 100644 --- a/gluon/contrib/fpdf/ttfonts.py +++ b/gluon/contrib/fpdf/ttfonts.py @@ -1,19 +1,19 @@ #****************************************************************************** -# TTFontFile class -# -# This class is based on The ReportLab Open Source PDF library -# written in Python - http://www.reportlab.com/software/opensource/ -# together with ideas from the OpenOffice source code and others. -# -# Version: 1.04 -# Date: 2011-09-18 -# Author: Ian Back -# License: LGPL -# Copyright (c) Ian Back, 2010 -# Ported to Python 2.7 by Mariano Reingart (reingart@gmail.com) on 2012 -# This header must be retained in any redistribution or -# modification of the file. -# +# TTFontFile class +# +# This class is based on The ReportLab Open Source PDF library +# written in Python - http://www.reportlab.com/software/opensource/ +# together with ideas from the OpenOffice source code and others. +# +# Version: 1.04 +# Date: 2011-09-18 +# Author: Ian Back +# License: LGPL +# Copyright (c) Ian Back, 2010 +# Ported to Python 2.7 by Mariano Reingart (reingart@gmail.com) on 2012 +# This header must be retained in any redistribution or +# modification of the file. +# #****************************************************************************** from struct import pack, unpack, unpack_from @@ -43,22 +43,22 @@ def sub32(x, y): xhi = x[0] ylo = y[1] yhi = y[0] - if (ylo > xlo): - xlo += 1 << 16 - yhi += 1 + if (ylo > xlo): + xlo += 1 << 16 + yhi += 1 reslo = xlo-ylo - if (yhi > xhi): - xhi += 1 << 16 + if (yhi > xhi): + xhi += 1 << 16 reshi = xhi-yhi reshi = reshi & 0xFFFF return (reshi, reslo) -def calcChecksum(data): +def calcChecksum(data): if (strlen(data) % 4): data += str_repeat("\0", (4-(len(data) % 4))) hi=0x0000 lo=0x0000 - for i in range(0, len(data), 4): + for i in range(0, len(data), 4): hi += (ord(data[i])<<8) + ord(data[i+1]) lo += (ord(data[i+2])<<8) + ord(data[i+3]) hi += lo >> 16 @@ -94,34 +94,34 @@ class TTFontFile: self.readTableDirectory() self.extractInfo() self.fh.close() - + def readTableDirectory(self, ): self.numTables = self.read_ushort() self.searchRange = self.read_ushort() self.entrySelector = self.read_ushort() self.rangeShift = self.read_ushort() - self.tables = {} + self.tables = {} for i in range(self.numTables): record = {} record['tag'] = self.read_tag() record['checksum'] = (self.read_ushort(),self.read_ushort()) record['offset'] = self.read_ulong() record['length'] = self.read_ulong() - self.tables[record['tag']] = record + self.tables[record['tag']] = record def get_table_pos(self, tag): offset = self.tables[tag]['offset'] length = self.tables[tag]['length'] return (offset, length) - - def seek(self, pos): + + def seek(self, pos): self._pos = pos self.fh.seek(self._pos) - - def skip(self, delta): + + def skip(self, delta): self._pos = self._pos + delta self.fh.seek(self._pos) - + def seek_table(self, tag, offset_in_table = 0): tpos = self.get_table_pos(tag) self._pos = tpos[0] + offset_in_table @@ -132,32 +132,32 @@ class TTFontFile: self._pos += 4 return self.fh.read(4) - def read_short(self): + def read_short(self): self._pos += 2 s = self.fh.read(2) a = (ord(s[0])<<8) + ord(s[1]) if (a & (1 << 15) ): - a = (a - (1 << 16)) + a = (a - (1 << 16)) return a - + def unpack_short(self, s): a = (ord(s[0])<<8) + ord(s[1]) if (a & (1 << 15) ): - a = (a - (1 << 16)) + a = (a - (1 << 16)) return a - + def read_ushort(self): self._pos += 2 s = self.fh.read(2) return (ord(s[0])<<8) + ord(s[1]) - def read_ulong(self): + def read_ulong(self): self._pos += 4 s = self.fh.read(4) # if large uInt32 as an integer, PHP converts it to -ve return (ord(s[0])*16777216) + (ord(s[1])<<16) + (ord(s[2])<<8) + ord(s[3]) # 16777216 = 1<<24 - def get_ushort(self, pos): + def get_ushort(self, pos): self.fh.seek(pos) s = self.fh.read(2) return (ord(s[0])<<8) + ord(s[1]) @@ -166,45 +166,45 @@ class TTFontFile: self.fh.seek(pos) s = self.fh.read(4) # iF large uInt32 as an integer, PHP converts it to -ve - return (ord(s[0])*16777216) + (ord(s[1])<<16) + (ord(s[2])<<8) + ord(s[3]) # 16777216 = 1<<24 + return (ord(s[0])*16777216) + (ord(s[1])<<16) + (ord(s[2])<<8) + ord(s[3]) # 16777216 = 1<<24 def pack_short(self, val): if (val<0): val = abs(val) val = ~val val += 1 - return pack(">H",val) - + return pack(">H",val) + def splice(self, stream, offset, value): return substr(stream,0,offset) + value + substr(stream,offset+strlen(value)) - + def _set_ushort(self, stream, offset, value): up = pack(">H", value) - return self.splice(stream, offset, up) + return self.splice(stream, offset, up) def _set_short(self, stream, offset, val): if (val<0): val = abs(val) val = ~val val += 1 - up = pack(">H",val) + up = pack(">H",val) return self.splice(stream, offset, up) - def get_chunk(self, pos, length): + def get_chunk(self, pos, length): self.fh.seek(pos) - if (length <1): return '' + if (length <1): return '' return (self.fh.read(length)) def get_table(self, tag): (pos, length) = self.get_table_pos(tag) if (length == 0): - die('Truetype font (' + self.filename + '): error reading table: ' + tag) + die('Truetype font (' + self.filename + '): error reading table: ' + tag) self.fh.seek(pos) return (self.fh.read(length)) def add(self, tag, data): if (tag == 'head') : - data = self.splice(data, 8, "\0\0\0\0") + data = self.splice(data, 8, "\0\0\0\0") self.otables[tag] = data ############################################/ @@ -212,7 +212,7 @@ class TTFontFile: ############################################/ - def extractInfo(self): + def extractInfo(self): #################/ # name - Naming table #################/ @@ -228,7 +228,7 @@ class TTFontFile: names = {1:'',2:'',3:'',4:'',6:''} K = names.keys() nameCount = len(names) - for i in range(numRecords): + for i in range(numRecords): platformId = self.read_ushort() encodingId = self.read_ushort() languageId = self.read_ushort() @@ -250,19 +250,19 @@ class TTFontFile: length -= 1 self._pos = opos self.seek(opos) - + elif (platformId == 1 and encodingId == 0 and languageId == 0): # Macintosh, Roman, English, PS Name opos = self._pos N = self.get_chunk(string_data_offset + offset, length) self._pos = opos self.seek(opos) - + if (N and names[nameId]==''): names[nameId] = N nameCount -= 1 if (nameCount==0): break - - + + if (names[6]): psName = names[6] elif (names[4]): @@ -275,29 +275,29 @@ class TTFontFile: die("Could not find PostScript font name") self.name = psName if (names[1]): - self.familyName = names[1] - else: - self.familyName = psName + self.familyName = names[1] + else: + self.familyName = psName if (names[2]): self.styleName = names[2] else: - self.styleName = 'Regular' + self.styleName = 'Regular' if (names[4]): self.fullName = names[4] else: - self.fullName = psName + self.fullName = psName if (names[3]): self.uniqueFontID = names[3] else: - self.uniqueFontID = psName + self.uniqueFontID = psName if (names[6]): - self.fullName = names[6] + self.fullName = names[6] #################/ # head - Font header table #################/ self.seek_table("head") - self.skip(18) + self.skip(18) self.unitsPerEm = unitsPerEm = self.read_ushort() scale = 1000 / float(unitsPerEm) self.skip(16) @@ -323,22 +323,22 @@ class TTFontFile: hheaDescender = self.read_short() self.ascent = (hheaAscender *scale) self.descent = (hheaDescender *scale) - + #################/ # OS/2 - OS/2 and Windows metrics table #################/ - if ("OS/2" in self.tables): + if ("OS/2" in self.tables): self.seek_table("OS/2") version = self.read_ushort() self.skip(2) usWeightClass = self.read_ushort() self.skip(2) fsType = self.read_ushort() - if (fsType == 0x0002 or (fsType & 0x0300) != 0): + if (fsType == 0x0002 or (fsType & 0x0300) != 0): die('ERROR - Font file ' + self.filename + ' cannot be embedded due to copyright restrictions.') self.restrictedUse = True - + self.skip(20) sF = self.read_short() self.sFamilyClass = (sF >> 8) @@ -348,30 +348,30 @@ class TTFontFile: self.skip(26) sTypoAscender = self.read_short() sTypoDescender = self.read_short() - if (not self.ascent): + if (not self.ascent): self.ascent = (sTypoAscender*scale) - if (not self.descent): + if (not self.descent): self.descent = (sTypoDescender*scale) if (version > 1): self.skip(16) sCapHeight = self.read_short() self.capHeight = (sCapHeight*scale) else: - self.capHeight = self.ascent - + self.capHeight = self.ascent + else: usWeightClass = 500 if (not self.ascent): self.ascent = (yMax*scale) if (not self.descent): self.descent = (yMin*scale) self.capHeight = self.ascent - + self.stemV = 50 + int(pow((usWeightClass / 65.0),2)) #################/ # post - PostScript table #################/ self.seek_table("post") - self.skip(4) + self.skip(4) self.italicAngle = self.read_short() + self.read_ushort() / 65536.0 self.underlinePosition = self.read_short() * scale self.underlineThickness = self.read_short() * scale @@ -390,7 +390,7 @@ class TTFontFile: # hhea - Horizontal header table #################/ self.seek_table("hhea") - self.skip(32) + self.skip(32) metricDataFormat = self.read_ushort() if (metricDataFormat != 0): die('Unknown horizontal metric data format '.metricDataFormat) @@ -402,7 +402,7 @@ class TTFontFile: # maxp - Maximum profile table #################/ self.seek_table("maxp") - self.skip(4) + self.skip(4) numGlyphs = self.read_ushort() #################/ @@ -424,7 +424,7 @@ class TTFontFile: unicode_cmap_offset = cmap_offset + offset break self.seek(save_pos ) - + if (not unicode_cmap_offset): die('Font (' + self.filename + ') does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)') @@ -460,7 +460,7 @@ class TTFontFile: # head - Font header table #################/ self.seek_table("head") - self.skip(50) + self.skip(50) indexToLocFormat = self.read_ushort() glyphDataFormat = self.read_ushort() @@ -468,7 +468,7 @@ class TTFontFile: # hhea - Horizontal header table #################/ self.seek_table("hhea") - self.skip(32) + self.skip(32) metricDataFormat = self.read_ushort() orignHmetrics = numberOfHMetrics = self.read_ushort() @@ -496,9 +496,9 @@ class TTFontFile: if (format == 4): unicode_cmap_offset = cmap_offset + offset break - + self.seek(save_pos ) - + if (not unicode_cmap_offset): die('Font (' + self.filename + ') does not have cmap for Unicode (platform 3, encoding 1, format 4, or platform 0, any encoding, format 4)') @@ -521,7 +521,7 @@ class TTFontFile: subsetglyphs = [(0, 0)] # special "sorted dict"! subsetCharToGlyph = {} - for code in subset: + for code in subset: if (code in self.charToGlyph): if (self.charToGlyph[code], code) not in subsetglyphs: subsetglyphs.append((self.charToGlyph[code], code)) # Old Glyph ID => Unicode @@ -540,12 +540,12 @@ class TTFontFile: codeToGlyph = {} for uni, originalGlyphIdx in sorted(subsetCharToGlyph.items()): - codeToGlyph[uni] = glyphSet[originalGlyphIdx] - + codeToGlyph[uni] = glyphSet[originalGlyphIdx] + self.codeToGlyph = codeToGlyph - - for originalGlyphIdx, uni in subsetglyphs: - nonlocals = {'start': start, 'glyphSet': glyphSet, + + for originalGlyphIdx, uni in subsetglyphs: + nonlocals = {'start': start, 'glyphSet': glyphSet, 'subsetglyphs': subsetglyphs} self.getGlyphs(originalGlyphIdx, nonlocals) @@ -553,12 +553,12 @@ class TTFontFile: #tables copied from the original tags = ['name'] - for tag in tags: - self.add(tag, self.get_table(tag)) + for tag in tags: + self.add(tag, self.get_table(tag)) tags = ['cvt ', 'fpgm', 'prep', 'gasp'] for tag in tags: - if (tag in self.tables): - self.add(tag, self.get_table(tag)) + if (tag in self.tables): + self.add(tag, self.get_table(tag)) # post - PostScript opost = self.get_table('post') @@ -592,7 +592,7 @@ class TTFontFile: while (searchRange * 2 <= segCount ): searchRange = searchRange * 2 entrySelector = entrySelector + 1 - + searchRange = searchRange * 2 rangeShift = segCount * 2 - searchRange length = 16 + (8*segCount ) + (numGlyphs+1) @@ -606,46 +606,46 @@ class TTFontFile: rangeShift] range_ = sorted(range_.items()) - + # endCode(s) for start, subrange in range_: endCode = start + (len(subrange)-1) cmap.append(endCode) # endCode(s) - + cmap.append(0xFFFF) # endCode of last Segment cmap.append(0) # reservedPad # startCode(s) - for start, subrange in range_: + for start, subrange in range_: cmap.append(start) # startCode(s) - + cmap.append(0xFFFF) # startCode of last Segment - # idDelta(s) - for start, subrange in range_: + # idDelta(s) + for start, subrange in range_: idDelta = -(start-subrange[0]) n += count(subrange) cmap.append(idDelta) # idDelta(s) - + cmap.append(1) # idDelta of last Segment - # idRangeOffset(s) - for subrange in range_: + # idRangeOffset(s) + for subrange in range_: cmap.append(0) # idRangeOffset[segCount] Offset in bytes to glyph indexArray, or 0 - + cmap.append(0) # idRangeOffset of last Segment - for subrange, glidx in range_: + for subrange, glidx in range_: cmap.extend(glidx) - + cmap.append(0) # Mapping for last character cmapstr = '' for cm in cmap: if cm >= 0: - cmapstr += pack(">H", cm) + cmapstr += pack(">H", cm) else: try: - cmapstr += pack(">h", cm) + cmapstr += pack(">h", cm) except: warnings.warn("cmap value too big/small: %s" % cm) - cmapstr += pack(">H", -cm) + cmapstr += pack(">H", -cm) self.add('cmap', cmapstr) # glyf - Glyph data @@ -674,9 +674,9 @@ class TTFontFile: maxComponentDepth = 0 # levels of recursion, set to 0 if font has only simple glyphs self.glyphdata = {} - for originalGlyphIdx, uni in subsetglyphs: + for originalGlyphIdx, uni in subsetglyphs: # hmtx - Horizontal Metrics - hm = self.getHMetric(orignHmetrics, originalGlyphIdx) + hm = self.getHMetric(orignHmetrics, originalGlyphIdx) hmtxstr += hm offsets.append(pos) @@ -694,7 +694,7 @@ class TTFontFile: data = self.get_chunk(glyfOffset+glyphPos,glyphLen) else: data = '' - + if (glyphLen > 0): up = unpack(">H", substr(data,0,2))[0] if (glyphLen > 2 and (up & (1 << 15)) ): # If number of contours <= -1 i.e. composiste glyph @@ -714,22 +714,22 @@ class TTFontFile: data = 0 warnings.warn("missing glyph data %s" % glyphIdx) pos_in_glyph += 4 - if (flags & GF_WORDS): - pos_in_glyph += 4 - else: - pos_in_glyph += 2 + if (flags & GF_WORDS): + pos_in_glyph += 4 + else: + pos_in_glyph += 2 if (flags & GF_SCALE): - pos_in_glyph += 2 + pos_in_glyph += 2 elif (flags & GF_XYSCALE): - pos_in_glyph += 4 + pos_in_glyph += 4 elif (flags & GF_TWOBYTWO): - pos_in_glyph += 8 - + pos_in_glyph += 8 + maxComponentElements = max(maxComponentElements, nComponentElements) - + glyf += data pos += glyphLen - if (pos % 4 != 0): + if (pos % 4 != 0): padding = 4 - (pos % 4) glyf += str_repeat("\0",padding) pos += padding @@ -742,15 +742,15 @@ class TTFontFile: # loca - Index to location locastr = '' - if (((pos + 1) >> 1) > 0xFFFF): + if (((pos + 1) >> 1) > 0xFFFF): indexToLocFormat = 1 # long format for offset in offsets: - locastr += pack(">L",offset) + locastr += pack(">L",offset) else: indexToLocFormat = 0 # short format - for offset in offsets: - locastr += pack(">H",(offset/2)) - + for offset in offsets: + locastr += pack(">H",(offset/2)) + self.add('loca', locastr) # head - Font header @@ -776,8 +776,8 @@ class TTFontFile: # Put the TTF file together stm = self.endTTFile('') - return stm - + return stm + ######################################### # Recursively get composite glyph data @@ -786,21 +786,21 @@ class TTFontFile: nonlocals['depth'] += 1 nonlocals['maxdepth'] = max(nonlocals['maxdepth'], nonlocals['depth']) if (len(self.glyphdata[originalGlyphIdx]['compGlyphs'])): - for glyphIdx in self.glyphdata[originalGlyphIdx]['compGlyphs']: - self.getGlyphData(glyphIdx, nonlocals) - + for glyphIdx in self.glyphdata[originalGlyphIdx]['compGlyphs']: + self.getGlyphData(glyphIdx, nonlocals) + elif ((self.glyphdata[originalGlyphIdx]['nContours'] > 0) and nonlocals['depth'] > 0): # simple contours += self.glyphdata[originalGlyphIdx]['nContours'] points += self.glyphdata[originalGlyphIdx]['nPoints'] - + nonlocals['depth'] -= 1 ######################################### # Recursively get composite glyphs def getGlyphs(self, originalGlyphIdx, nonlocals): - # &start, &glyphSet, &subsetglyphs) - + # &start, &glyphSet, &subsetglyphs) + try: glyphPos = self.glyphPos[originalGlyphIdx] glyphLen = self.glyphPos[originalGlyphIdx + 1] - glyphPos @@ -808,21 +808,21 @@ class TTFontFile: warnings.warn("missing glyph %s" % (originalGlyphIdx)) return - if (not glyphLen): + if (not glyphLen): return - + self.seek(nonlocals['start'] + glyphPos) numberOfContours = self.read_short() if (numberOfContours < 0): self.skip(8) flags = GF_MORE - while (flags & GF_MORE): + while (flags & GF_MORE): flags = self.read_ushort() glyphIdx = self.read_ushort() if (glyphIdx not in nonlocals['glyphSet']): nonlocals['glyphSet'][glyphIdx] = len(nonlocals['subsetglyphs']) # old glyphID to new glyphID nonlocals['subsetglyphs'].append((glyphIdx, 1)) - + savepos = self.fh.tell() self.getGlyphs(glyphIdx, nonlocals) self.seek(savepos) @@ -844,56 +844,56 @@ class TTFontFile: aw = 0 self.charWidths = [0] * 256*256*2 nCharWidths = 0 - if ((numberOfHMetrics*4) < self.maxStrLenRead): + if ((numberOfHMetrics*4) < self.maxStrLenRead): data = self.get_chunk(start,(numberOfHMetrics*4)) arr = unpack(">" + "H" * (len(data)/2), data) else: - self.seek(start) - for glyph in range(numberOfHMetrics): + self.seek(start) + for glyph in range(numberOfHMetrics): if ((numberOfHMetrics*4) < self.maxStrLenRead): aw = arr[(glyph*2)] # PHP starts arrays from index 0!? +1 else: aw = self.read_ushort() lsb = self.read_ushort() - + if (glyph in glyphToChar or glyph == 0): if (aw >= (1 << 15) ): aw = 0 # 1.03 Some (arabic) fonts have -ve values for width # although should be unsigned value - comes out as e.g. 65108 (intended -50) - if (glyph == 0): + if (glyph == 0): self.defaultWidth = scale*aw continue - - for char in glyphToChar[glyph]: - if (char != 0 and char != 65535): + + for char in glyphToChar[glyph]: + if (char != 0 and char != 65535): w = int(round(scale*aw)) - if (w == 0): w = 65535 - if (char < 196608): - self.charWidths[char] = w + if (w == 0): w = 65535 + if (char < 196608): + self.charWidths[char] = w nCharWidths += 1 - - + + data = self.get_chunk((start+numberOfHMetrics*4),(numGlyphs*2)) arr = unpack(">" + "H" * (len(data)/2), data) diff = numGlyphs-numberOfHMetrics - for pos in range(diff): + for pos in range(diff): glyph = pos + numberOfHMetrics - if (glyph in glyphToChar): - for char in glyphToChar[glyph]: - if (char != 0 and char != 65535): + if (glyph in glyphToChar): + for char in glyphToChar[glyph]: + if (char != 0 and char != 65535): w = int(round(scale*aw)) - if (w == 0): w = 65535 + if (w == 0): w = 65535 if (char < 196608): self.charWidths[char] = w - nCharWidths += 1 - - + nCharWidths += 1 + + # NB 65535 is a set width of 0 # First bytes define number of chars in font - self.charWidths[0] = nCharWidths - + self.charWidths[0] = nCharWidths - def getHMetric(self, numberOfHMetrics, gid): + + def getHMetric(self, numberOfHMetrics, gid): start = self.seek_table("hmtx") if (gid < numberOfHMetrics): self.seek(start+(gid*4)) @@ -904,15 +904,15 @@ class TTFontFile: self.seek(start+(numberOfHMetrics*2)+(gid*2)) hm += self.fh.read(2) return hm - - def getLOCA(self, indexToLocFormat, numGlyphs): + + def getLOCA(self, indexToLocFormat, numGlyphs): start = self.seek_table('loca') self.glyphPos = [] if (indexToLocFormat == 0): data = self.get_chunk(start,(numGlyphs*2)+2) arr = unpack(">" + "H" * (len(data)/2), data) - for n in range(numGlyphs): + for n in range(numGlyphs): self.glyphPos.append((arr[n] * 2)) # n+1 !? elif (indexToLocFormat == 1): data = self.get_chunk(start,(numGlyphs*4)+4) @@ -938,18 +938,18 @@ class TTFontFile: self.skip(2) startCount = [] for i in range(segCount): - startCount.append(self.read_ushort()) + startCount.append(self.read_ushort()) idDelta = [] for i in range(segCount): idDelta.append(self.read_short()) # ???? was unsigned short idRangeOffset_start = self._pos idRangeOffset = [] for i in range(segCount): - idRangeOffset.append(self.read_ushort()) + idRangeOffset.append(self.read_ushort()) - for n in range(segCount): + for n in range(segCount): endpoint = (endCount[n] + 1) - for unichar in range(startCount[n], endpoint, 1): + for unichar in range(startCount[n], endpoint, 1): if (idRangeOffset[n] == 0): glyph = (unichar + idDelta[n]) & 0xFFFF else: @@ -961,33 +961,33 @@ class TTFontFile: glyph = self.get_ushort(offset) if (glyph != 0): glyph = (glyph + idDelta[n]) & 0xFFFF - + charToGlyph[unichar] = glyph if (unichar < 196608): - self.maxUniChar = max(unichar,self.maxUniChar) + self.maxUniChar = max(unichar,self.maxUniChar) glyphToChar.setdefault(glyph, []).append(unichar) # Put the TTF file together - def endTTFile(self, stm): + def endTTFile(self, stm): stm = '' numTables = count(self.otables) searchRange = 1 entrySelector = 0 - while (searchRange * 2 <= numTables): + while (searchRange * 2 <= numTables): searchRange = searchRange * 2 entrySelector = entrySelector + 1 - + searchRange = searchRange * 16 rangeShift = numTables * 16 - searchRange # Header - if (_TTF_MAC_HEADER): + if (_TTF_MAC_HEADER): stm += (pack(">LHHHH", 0x74727565, numTables, searchRange, entrySelector, rangeShift)) # Mac else: stm += (pack(">LHHHH", 0x00010000 , numTables, searchRange, entrySelector, rangeShift)) # Windows - + # Table directory tables = self.otables @@ -995,7 +995,7 @@ class TTFontFile: sorted_tables = sorted(tables.items()) for tag, data in sorted_tables: if (tag == 'head'): - head_start = offset + head_start = offset stm += tag checksum = calcChecksum(data) stm += pack(">HH", checksum[0],checksum[1]) @@ -1004,7 +1004,7 @@ class TTFontFile: offset = offset + paddedLength # Table data - for tag, data in sorted_tables: + for tag, data in sorted_tables: data += "\0\0\0" stm += substr(data,0,(strlen(data)&~3)) @@ -1012,8 +1012,8 @@ class TTFontFile: checksum = sub32((0xB1B0,0xAFBA), checksum) chk = pack(">HH", checksum[0],checksum[1]) stm = self.splice(stm,(head_start + 8),chk) - return stm - + return stm + if __name__ == '__main__': ttf = TTFontFile() ttffile = 'DejaVuSansCondensed.ttf'; @@ -1030,4 +1030,4 @@ if __name__ == '__main__': assert round(ttf.underlineThickness, 0) == 44 # test char widths 8(against binary file generated by tfpdf.php): assert ''.join(ttf.charWidths) == open("dejavusanscondensed.cw.dat").read() - \ No newline at end of file + From aad7aac1c7185de30cc3a0067519798f353342a8 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 08:37:55 -0500 Subject: [PATCH 04/53] fixed changelog typos, thanks Niphlod --- CHANGELOG | 40 +++++++++++++++++++++++++++------------- VERSION | 2 +- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index b28b148d..1e93192a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,15 +12,15 @@ - db(...).select(db.mytable.myfield.count(distinct=True)) - db(db.a)._update(name=db(db.b.a==db.a.id).nested_select(db.b.id)) - db.mytable.myfield.filter_in, filter_out -- db.mytable._enable_record_versioning(db) adds verining to this table +- db.mytable._enable_record_versioning(db) adds versioning to this table - teradata adapter, thanks Andrew Willimott - experimental Sybase Adapter - added db.table.field.avg() -- Suport for Google App Engine projections +- Support for Google App Engine projections ### Auth improvements -- auth.enable_record_versioning(db) adds full versining to all tables +- auth.enable_record_versioning(db) adds full versioning to all tables - @auth.requires_login(otherwise=URL(...)) - auth supports salt and compatible with third party data, thanks Dave Stoll - CRYPT now defaults to pbkdf2(1000,20,sha1) @@ -33,14 +33,14 @@ - FORM.confirm('Are you sure?',{'Back':URL(...)}) - SQLFORM.smartdictform(dict) - form.add_button(value,link) -- SQLFORM.grid(groupby=...') +- SQLFORM.grid(groupby='...') - fixed security issue with SQLFORM.grid and SQLFORM.smartgrid - more export options in SQLFORM.grid and SQLFORM.smartgrid (html, xml, csv, ...) ### Admin improvements - new admin pages: manage_students, bulk_regsiter, and progress reports -- increased secure admin against CSRF +- increased security in admin against CSRF - experimental Git integration - experimental OpenShift deployment - multi-language pluralization engine @@ -49,14 +49,28 @@ - Romanian translation for welcome, thanks ionel - support for mercurial 2.6, thanks Vlad -### Scheduler Inprovements +### Scheduler Improvements (thanks to niphlod, ykessler, dhx, toomim) - web2py.py -K myapp -X starts the myapp scheduler alongside the webserver +- tasks are marked EXPIRED (if stop_time passed) +- functions with no result don't end up in scheduler_run - more options: web2py.py -E -b -L -- scheduler can now handle 10k tasks with 20 concurrent workers and no known issues (thanks to niphlod, ykessler, dhx, toomim) -- tasks can be found in the environment (no need to define the tasks parameter) -- max_empty_runs kills the workers automatically if no new tasks are found in queue (nice for "spikes" of processing power), discard_results to completely discard the results (if you don't need the output of the task), utc_time enables datetime calculations with UTC time, task_name is no longer required (filled automatically with function_name if found empty), uuid makes easy to coordinate scheduler_task maintenance (filled automatically if not provided), stop_time has no default (previously was today+1), retry_failed to requeue automatically failed tasks, sync_output refreshes automatically the output (nice to report percentages) -- tasks can be DISABLED (put to sleep and do nothing if not sending the heartbeat every 30 seconds), TERMINATE (complete the current task and then die), KILL (kill ASAP), EXPIRED (if stop_time passed) +- scheduler can now handle 10k tasks with 20 concurrent workers and with no issues +- new params: + tasks can be found in the environment (no need to define the tasks parameter) + max_empty_runs kills the workers automatically if no new tasks are found in queue (nice for "spikes" of processing power) + discard_results to completely discard the results (if you don't need the output of the task) + utc_time enables datetime calculations with UTC time +- scheduler_task changes: + task_name is no longer required (filled automatically with function_name if found empty) + uuid makes easy to coordinate scheduler_task maintenance (filled automatically if not provided) + stop_time has no default (previously was today+1) + retry_failed to requeue automatically failed tasks + sync_output refreshes automatically the output (nice to report percentages) +- workers can be: + DISABLED (put to sleep and do nothing if not sending the heartbeat every 30 seconds) + TERMINATE (complete the current task and then die) + KILL (kill ASAP) ### Other Improvements @@ -67,12 +81,12 @@ - routes in can redirect outside with routes_in=[('/path','303->http://..')] - better memcache support - improved spreadsheet, thanks Alan -- new interantionalization engine, thanks Vladyslav +- new internationalization engine, thanks Vladyslav - pluralization engine, thanks Vladyslav -- new makrmin with supports for nested lists, , , autolinks, thanks Vladyslav +- new markmin with support for nested lists, , , autolinks, thanks Vladyslav - new syntax: {{=BR()*5}} - gluon.cache.lazy_cache decorator allows caching functions in modules -- .coffee and .less support in response.fields, thanks Sam Sheftel +- .coffee and .less support in response.files, thanks Sam Sheftel - ldap certificate support - pg8000 postgresql driver support (experimental) - @cache('%(name)s%(args)s%(vars)s',5) and cache.autokey diff --git a/VERSION b/VERSION index 03475297..580b29d0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 08:36:47) dev +Version 2.00.0 (2012-08-23 08:37:52) dev From cf51c40e8603b9d1432660e0cb0a500d1a7e0ca9 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 08:42:47 -0500 Subject: [PATCH 05/53] restoring Settings backward compatibility, thanks Dominic --- VERSION | 2 +- gluon/storage.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 580b29d0..5cdb6dba 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 08:37:52) dev +Version 2.00.0 (2012-08-23 08:42:44) dev diff --git a/gluon/storage.py b/gluon/storage.py index b1d36a8c..fa956703 100644 --- a/gluon/storage.py +++ b/gluon/storage.py @@ -35,7 +35,7 @@ class Storage(dict): 2 >>> del o.a - >>> print o.a + >>> print o.a None """ def __getattr__(self, key): @@ -100,7 +100,7 @@ class Storage(dict): def getlast(self,key,default=None): """ - Returns the last or only single value when + Returns the last or only single value when given a request.vars-style key. If the value is a list, the last item will be returned; @@ -155,9 +155,9 @@ def save_storage(storage, filename): class Settings(Storage): def __setattr__(self, key, value): - if key != 'lock_keys' and 'lock_keys' in self and not key in self: + if key != 'lock_keys' and self['lock_keys'] and key not in self: raise SyntaxError, 'setting key \'%s\' does not exist' % key - if key != 'lock_values' and 'lock_values' in self: + if key != 'lock_values' and self['lock_values']: raise SyntaxError, 'setting value cannot be changed: %s' % key self[key] = value From 089c0b33db5c3f5cb6c05dff7576a5778f5ad0d8 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 08:54:34 -0500 Subject: [PATCH 06/53] added DIV.add_class, DIV.remove_class, thanks Dulakian, fixed issue 952 --- VERSION | 2 +- gluon/html.py | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5cdb6dba..faceb93c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 08:42:44) dev +Version 2.00.0 (2012-08-23 08:54:31) dev diff --git a/gluon/html.py b/gluon/html.py index 7aa16ec6..e88d8604 100644 --- a/gluon/html.py +++ b/gluon/html.py @@ -484,6 +484,19 @@ class XmlComponent(object): components += [other] return CAT(*components) + def add_class(self, name): + """ add a class to _class attribute """ + classes = set(self['_class'].split())|set(name.split()) + self['_class'] = ' '.join(classes) if classes else None + return self + + def remove_class(self, name): + """ remove a class from _class attribute """ + classes = set(self['_class'].split())-set(name.split()) + self['_class'] = ' '.join(classes) if classes else None + return self + + class XML(XmlComponent): """ use it to wrap a string that contains XML/HTML so that it will not be From bd12fd4c7bb7159d1109011cea422e26da1ada33 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 09:00:56 -0500 Subject: [PATCH 07/53] added Killer Web Development link, thanks Anthony --- VERSION | 2 +- .../private/content/en/default/documentation/more.markmin | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index faceb93c..a6884d6d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 08:54:31) dev +Version 2.00.0 (2012-08-23 09:00:53) dev diff --git a/applications/examples/private/content/en/default/documentation/more.markmin b/applications/examples/private/content/en/default/documentation/more.markmin index 854e076d..fe803573 100644 --- a/applications/examples/private/content/en/default/documentation/more.markmin +++ b/applications/examples/private/content/en/default/documentation/more.markmin @@ -7,6 +7,7 @@ - [[User Voice http://web2py.uservoice.com/ popup]] #### Learning and Demos +- [[Killer Web Development Tutorial http://killer-web-development.com/]] - [[Admin Demo http://www.web2py.com/demo_admin popup]] (web-based IDE) - [[Welcome App Demo http://www.web2py.com/welcome]] (scaffolding application) - [[Videos http://www.web2py.com/examples/default/videos/]] From 09dc27faed2cc7678e3261196497bc98cfb46c58 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 09:20:25 -0500 Subject: [PATCH 08/53] db.define_table('person',Field('name'),on_define=lambda table: [table.name.set_attributes(writable=False)]), thanks Jonathan --- VERSION | 2 +- gluon/dal.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index a6884d6d..0b20db7d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 09:00:53) dev +Version 2.00.0 (2012-08-23 09:20:22) dev diff --git a/gluon/dal.py b/gluon/dal.py index 8d313931..30be93cc 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -174,7 +174,7 @@ import platform CALLABLETYPES = (types.LambdaType, types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.BuiltinMethodType) -TABLE_ARGS = ('migrate','primarykey','fake_migrate','format','singular','plural','trigger_name','sequence_name','common_filter','polymodel','table_class') +TABLE_ARGS = ('migrate','primarykey','fake_migrate','format','singular','plural','trigger_name','sequence_name','common_filter','polymodel','table_class','on_define') ################################################################################### # following checks allow the use of dal without web2py, as a standalone module @@ -6977,6 +6977,8 @@ def index(): sql_locker.release() else: table._dbt = None + on_define = args.get('on_define',None) + if on_define: on_define(table) return table def __iter__(self): @@ -8149,6 +8151,9 @@ class Field(Expression): self.label = label if label!=None else fieldname.replace('_',' ').title() self.requires = requires if requires!=None else [] + def set_attributes(self,*args,**attributes): + self.__dict__.update(*args,**attributes) + def clone(self,point_self_references_to=False,**args): field = copy.copy(self) if point_self_references_to and \ From 87a7d2e4239e9e99656c021ecf33d09c624f22c5 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 10:08:00 -0500 Subject: [PATCH 09/53] fixed problem with on_define --- CHANGELOG | 2 + VERSION | 2 +- gluon/tools.py | 107 ++++++++++++++++++++++++++++++------------------- 3 files changed, 68 insertions(+), 43 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1e93192a..41b5f636 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ ### DAL Improvements +- Support for DAL(lazy_tables=True) and db.define_table(on_define=lambda table:), thanks Jonathan - MongoDB support in DAL (experimental) - geodal and spatialite, thanks Denes and Fran (experimental) - db.mytable._before_insert, _after_insert, _before_update, _after_update, _before_delete. _after_delete (list of callbacks) @@ -17,6 +18,7 @@ - experimental Sybase Adapter - added db.table.field.avg() - Support for Google App Engine projections +- Field(... 'upload', default=path) now accepts a path to a local file as default value, if user does not upload a file. Relative path looks inside current application folder, thanks Marin ### Auth improvements diff --git a/VERSION b/VERSION index 0b20db7d..4888417d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 09:20:22) dev +Version 2.00.0 (2012-08-23 10:07:57) dev diff --git a/gluon/tools.py b/gluon/tools.py index e67d5e4c..d2c8a46c 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1460,7 +1460,7 @@ class Auth(object): if not settings.email_case_sensitive: table.email.requires.insert(1,IS_LOWER()) table.registration_key.default = '' - settings.table_user = db[settings.table_user_name] + reference_table_user = 'reference %s' % settings.table_user_name if not settings.table_group_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_group_name,[])+signature_list @@ -1475,37 +1475,41 @@ class Auth(object): migrate=self.__get_migrate( settings.table_group_name, migrate), fake_migrate=fake_migrate, - format = '%(role)s (%(id)s)')) - table.role.requires = IS_NOT_IN_DB(db, '%s.role' - % settings.table_group_name) - settings.table_group = db[settings.table_group_name] + format = '%(role)s (%(id)s)', + on_define = lambda table: + table.role.set_attributes( + requires = IS_NOT_IN_DB( + db, '%s.role'% settings.table_group_name)))) + reference_table_group = 'reference %s' % settings.table_group_name if not settings.table_membership_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_membership_name,[])+signature_list table = db.define_table( settings.table_membership_name, - Field('user_id', settings.table_user, + Field('user_id', reference_table_user, label=self.messages.label_user_id), - Field('group_id', settings.table_group, + Field('group_id', reference_table_group, label=self.messages.label_group_id), *extra_fields, **dict( migrate=self.__get_migrate( settings.table_membership_name, migrate), - fake_migrate=fake_migrate)) - table.user_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_user_name, - settings.table_user._format) - table.group_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_group_name, - '%(role)s (%(id)s)') - settings.table_membership = db[settings.table_membership_name] + fake_migrate=fake_migrate, + on_define = lambda table: ( + table.user_id.set_attributes( + requires = IS_IN_DB( + db, '%s.id' % settings.table_user_name, + settings.table_user._format)). + table.group_id.set_attributes( + requires = IS_IN_DB( + db, '%s.id' % settings.table_group_name, + '%(role)s (%(id)s)'))))) if not settings.table_permission_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_permission_name,[])+signature_list table = db.define_table( settings.table_permission_name, - Field('group_id', settings.table_group, + Field('group_id', reference_table_group, label=self.messages.label_group_id), Field('name', default='default', length=512, label=self.messages.label_name), @@ -1517,14 +1521,17 @@ class Auth(object): **dict( migrate=self.__get_migrate( settings.table_permission_name, migrate), - fake_migrate=fake_migrate)) - table.group_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_group_name, - '%(role)s (%(id)s)') - table.name.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) - #table.table_name.requires = IS_EMPTY_OR(IS_IN_SET(self.db.tables)) - table.record_id.requires = IS_INT_IN_RANGE(0, 10 ** 9) - settings.table_permission = db[settings.table_permission_name] + fake_migrate=fake_migrate, + on_define = lambda table: ( + table.group_id.set_attributes( + requires = IS_IN_DB( + db, '%s.id' % settings.table_group_name, + '%(role)s (%(id)s)')), + table.name.set_attributes( + requires = IS_NOT_EMPTY( + error_message=self.messages.is_empty)), + table.record_id.set_attributes( + requires = IS_INT_IN_RANGE(0, 10 ** 9))))) if not settings.table_event_name in db.tables: table = db.define_table( settings.table_event_name, @@ -1534,7 +1541,7 @@ class Auth(object): Field('client_ip', default=current.request.client, label=self.messages.label_client_ip), - Field('user_id', settings.table_user, default=None, + Field('user_id', reference_table_user, default=None, label=self.messages.label_user_id), Field('origin', default='auth', length=512, label=self.messages.label_origin), @@ -1544,19 +1551,24 @@ class Auth(object): **dict( migrate=self.__get_migrate( settings.table_event_name, migrate), - fake_migrate=fake_migrate)) - table.user_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_user_name, - settings.table_user._format) - table.origin.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) - table.description.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) - settings.table_event = db[settings.table_event_name] + fake_migrate=fake_migrate, + on_define = lambda table: ( + table.user_id.set_attributes( + requires = IS_IN_DB( + db, '%s.id' % settings.table_user_name, + settings.table_user._format)), + table.origin.set_attributes( + requires = IS_NOT_EMPTY( + error_message=self.messages.is_empty)), + table.description.set_attributes( + requires = IS_NOT_EMPTY( + error_message=self.messages.is_empty))))) now = current.request.now if settings.cas_domains: if not settings.table_cas_name in db.tables: table = db.define_table( settings.table_cas_name, - Field('user_id', settings.table_user, default=None, + Field('user_id', reference_table_user, default=None, label=self.messages.label_user_id), Field('created_on','datetime',default=now), Field('service',requires=IS_URL()), @@ -1566,18 +1578,29 @@ class Auth(object): **dict( migrate=self.__get_migrate( settings.table_cas_name, migrate), - fake_migrate=fake_migrate)) - table.user_id.requires = IS_IN_DB(db, '%s.id' % \ - settings.table_user_name, - settings.table_user._format) - settings.table_cas = db[settings.table_cas_name] - db._lazy_tables = lazy_tables - if settings.cas_provider: + fake_migrate=fake_migrate, + on_define = lambda table: ( + table.user_id.set_attributes( + requires = IS_IN_DB( + db, '%s.id' % settings.table_user_name, + settings.table_user._format))))) + + if not db._lazy_tables: + settings.table_user = db[settings.table_user_name] + settings.table_group = db[settings.table_group_name] + settings.table_membership = db[settings.table_membership_name] + settings.table_permission = db[settings.table_permission_name] + settings.table_event = db[settings.table_event_name] + if settings.cas_domains: + settings.table_cas = db[settings.table_cas_name] + + if settings.cas_provider: ### THIS IS NOT LAZY settings.actions_disabled = \ - ['profile','register','change_password','request_reset_password'] + ['profile','register','change_password', + 'request_reset_password'] from gluon.contrib.login_methods.cas_auth import CasAuth maps = settings.cas_maps - if not maps: + if not maps: maps = dict((name,lambda v,n=name:v.get(n,None)) for name in \ settings.table_user.fields if name!='id' \ and settings.table_user[name].readable) From f6e89cc80487113b874088688b690fa06cd29a5e Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 10:09:49 -0500 Subject: [PATCH 10/53] reverted accidental tools change --- VERSION | 2 +- gluon/tools.py | 107 +++++++++++++++++++------------------------------ 2 files changed, 43 insertions(+), 66 deletions(-) diff --git a/VERSION b/VERSION index 4888417d..a6d46fcb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 10:07:57) dev +Version 2.00.0 (2012-08-23 10:09:46) dev diff --git a/gluon/tools.py b/gluon/tools.py index d2c8a46c..e67d5e4c 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1460,7 +1460,7 @@ class Auth(object): if not settings.email_case_sensitive: table.email.requires.insert(1,IS_LOWER()) table.registration_key.default = '' - reference_table_user = 'reference %s' % settings.table_user_name + settings.table_user = db[settings.table_user_name] if not settings.table_group_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_group_name,[])+signature_list @@ -1475,41 +1475,37 @@ class Auth(object): migrate=self.__get_migrate( settings.table_group_name, migrate), fake_migrate=fake_migrate, - format = '%(role)s (%(id)s)', - on_define = lambda table: - table.role.set_attributes( - requires = IS_NOT_IN_DB( - db, '%s.role'% settings.table_group_name)))) - reference_table_group = 'reference %s' % settings.table_group_name + format = '%(role)s (%(id)s)')) + table.role.requires = IS_NOT_IN_DB(db, '%s.role' + % settings.table_group_name) + settings.table_group = db[settings.table_group_name] if not settings.table_membership_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_membership_name,[])+signature_list table = db.define_table( settings.table_membership_name, - Field('user_id', reference_table_user, + Field('user_id', settings.table_user, label=self.messages.label_user_id), - Field('group_id', reference_table_group, + Field('group_id', settings.table_group, label=self.messages.label_group_id), *extra_fields, **dict( migrate=self.__get_migrate( settings.table_membership_name, migrate), - fake_migrate=fake_migrate, - on_define = lambda table: ( - table.user_id.set_attributes( - requires = IS_IN_DB( - db, '%s.id' % settings.table_user_name, - settings.table_user._format)). - table.group_id.set_attributes( - requires = IS_IN_DB( - db, '%s.id' % settings.table_group_name, - '%(role)s (%(id)s)'))))) + fake_migrate=fake_migrate)) + table.user_id.requires = IS_IN_DB(db, '%s.id' % + settings.table_user_name, + settings.table_user._format) + table.group_id.requires = IS_IN_DB(db, '%s.id' % + settings.table_group_name, + '%(role)s (%(id)s)') + settings.table_membership = db[settings.table_membership_name] if not settings.table_permission_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_permission_name,[])+signature_list table = db.define_table( settings.table_permission_name, - Field('group_id', reference_table_group, + Field('group_id', settings.table_group, label=self.messages.label_group_id), Field('name', default='default', length=512, label=self.messages.label_name), @@ -1521,17 +1517,14 @@ class Auth(object): **dict( migrate=self.__get_migrate( settings.table_permission_name, migrate), - fake_migrate=fake_migrate, - on_define = lambda table: ( - table.group_id.set_attributes( - requires = IS_IN_DB( - db, '%s.id' % settings.table_group_name, - '%(role)s (%(id)s)')), - table.name.set_attributes( - requires = IS_NOT_EMPTY( - error_message=self.messages.is_empty)), - table.record_id.set_attributes( - requires = IS_INT_IN_RANGE(0, 10 ** 9))))) + fake_migrate=fake_migrate)) + table.group_id.requires = IS_IN_DB(db, '%s.id' % + settings.table_group_name, + '%(role)s (%(id)s)') + table.name.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) + #table.table_name.requires = IS_EMPTY_OR(IS_IN_SET(self.db.tables)) + table.record_id.requires = IS_INT_IN_RANGE(0, 10 ** 9) + settings.table_permission = db[settings.table_permission_name] if not settings.table_event_name in db.tables: table = db.define_table( settings.table_event_name, @@ -1541,7 +1534,7 @@ class Auth(object): Field('client_ip', default=current.request.client, label=self.messages.label_client_ip), - Field('user_id', reference_table_user, default=None, + Field('user_id', settings.table_user, default=None, label=self.messages.label_user_id), Field('origin', default='auth', length=512, label=self.messages.label_origin), @@ -1551,24 +1544,19 @@ class Auth(object): **dict( migrate=self.__get_migrate( settings.table_event_name, migrate), - fake_migrate=fake_migrate, - on_define = lambda table: ( - table.user_id.set_attributes( - requires = IS_IN_DB( - db, '%s.id' % settings.table_user_name, - settings.table_user._format)), - table.origin.set_attributes( - requires = IS_NOT_EMPTY( - error_message=self.messages.is_empty)), - table.description.set_attributes( - requires = IS_NOT_EMPTY( - error_message=self.messages.is_empty))))) + fake_migrate=fake_migrate)) + table.user_id.requires = IS_IN_DB(db, '%s.id' % + settings.table_user_name, + settings.table_user._format) + table.origin.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) + table.description.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) + settings.table_event = db[settings.table_event_name] now = current.request.now if settings.cas_domains: if not settings.table_cas_name in db.tables: table = db.define_table( settings.table_cas_name, - Field('user_id', reference_table_user, default=None, + Field('user_id', settings.table_user, default=None, label=self.messages.label_user_id), Field('created_on','datetime',default=now), Field('service',requires=IS_URL()), @@ -1578,29 +1566,18 @@ class Auth(object): **dict( migrate=self.__get_migrate( settings.table_cas_name, migrate), - fake_migrate=fake_migrate, - on_define = lambda table: ( - table.user_id.set_attributes( - requires = IS_IN_DB( - db, '%s.id' % settings.table_user_name, - settings.table_user._format))))) - - if not db._lazy_tables: - settings.table_user = db[settings.table_user_name] - settings.table_group = db[settings.table_group_name] - settings.table_membership = db[settings.table_membership_name] - settings.table_permission = db[settings.table_permission_name] - settings.table_event = db[settings.table_event_name] - if settings.cas_domains: - settings.table_cas = db[settings.table_cas_name] - - if settings.cas_provider: ### THIS IS NOT LAZY + fake_migrate=fake_migrate)) + table.user_id.requires = IS_IN_DB(db, '%s.id' % \ + settings.table_user_name, + settings.table_user._format) + settings.table_cas = db[settings.table_cas_name] + db._lazy_tables = lazy_tables + if settings.cas_provider: settings.actions_disabled = \ - ['profile','register','change_password', - 'request_reset_password'] + ['profile','register','change_password','request_reset_password'] from gluon.contrib.login_methods.cas_auth import CasAuth maps = settings.cas_maps - if not maps: + if not maps: maps = dict((name,lambda v,n=name:v.get(n,None)) for name in \ settings.table_user.fields if name!='id' \ and settings.table_user[name].readable) From 417495e164e54fa38a44732fd536f2fdbac34ec9 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 10:48:36 -0500 Subject: [PATCH 11/53] lazy auth? --- VERSION | 2 +- gluon/tools.py | 251 +++++++++++++++++++++++++------------------------ 2 files changed, 130 insertions(+), 123 deletions(-) diff --git a/VERSION b/VERSION index a6d46fcb..ff874f51 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 10:09:46) dev +Version 2.00.0 (2012-08-23 10:48:33) dev diff --git a/gluon/tools.py b/gluon/tools.py index e67d5e4c..c5fdab89 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -997,7 +997,7 @@ class Auth(object): settings.table_event_name = 'auth_event' settings.table_cas_name = 'auth_cas' - # ## if none, they will be created + # ## if none, they will be created, unless DAL(lazy_tables=True)!!! settings.table_user = None settings.table_group = None @@ -1167,6 +1167,17 @@ class Auth(object): user_id = property(_get_user_id, doc="user.id or None") + def table_user(self): + return self.db[self.settings.table_user_name] + def table_group(self): + return self.db[self.settings.table_group_name] + def table_memberhsip(self): + return self.db[self.settings.table_membership_name] + def table_event(self): + return self.db[self.settings.table_event_name] + def table_cas(self): + return self.db[self.settings.table_cas_name] + def _HTTP(self, *a, **b): """ only used in lambda: self._HTTP(404) @@ -1261,7 +1272,7 @@ class Auth(object): if not 'register' in self.settings.actions_disabled: bar.insert(-1, s2) bar.insert(-1, register) - if 'username' in self.settings.table_user.fields() and \ + if 'username' in self.user_username and \ not 'retrieve_username' in self.settings.actions_disabled: bar.insert(-1, s2) bar.insert(-1, retrieve_username) @@ -1373,6 +1384,7 @@ class Auth(object): db = self.db settings = self.settings + self.use_username = username if not self.signature: self.define_signature() if signature==True: @@ -1384,23 +1396,40 @@ class Auth(object): else: signature_list = signature lazy_tables, db._lazy_tables = db._lazy_tables, False + is_not_empty = IS_NOT_EMPTY(error_message=self.messages.is_empty) + is_crypted = CRYPT(key=settings.hmac_key, + min_length=settings.password_min_length) + is_unique_email = [ + IS_EMAIL(error_message=self.messages.invalid_email), + IS_NOT_IN_DB(db, 'email.id')] + if not settings.email_case_sensitive: + is_unique_email.insert(1,IS_LOWER()) if not settings.table_user_name in db.tables: passfield = settings.password_field extra_fields = settings.extra_fields.get( settings.table_user_name,[])+signature_list - if username or settings.cas_provider: + if username or settings.cas_provider: + is_unique_username = \ + [IS_MATCH('[\w\.\-]+'), IS_NOT_IN_DB(db, table.username)] + if not settings.username_case_sensitive: + is_unique_username.insert(1,IS_LOWER()) table = db.define_table( settings.table_user_name, Field('first_name', length=128, default='', - label=self.messages.label_first_name), + label=self.messages.label_first_name, + requires = is_not_empty), Field('last_name', length=128, default='', - label=self.messages.label_last_name), + label=self.messages.label_last_name, + requires = is_not_empty), Field('email', length=512, default='', - label=self.messages.label_email), + label=self.messages.label_email, + requires = is_unique_email), Field('username', length=128, default='', - label=self.messages.label_username), + label=self.messages.label_username, + requires=is_unique_username), Field(passfield, 'password', length=512, - readable=False, label=self.messages.label_password), + readable=False, label=self.messages.label_password, + requires = [is_crypted]), Field('registration_key', length=512, writable=False, readable=False, default='', label=self.messages.label_registration_key), @@ -1416,22 +1445,21 @@ class Auth(object): migrate), fake_migrate=fake_migrate, format='%(username)s')) - table.username.requires = \ - [IS_MATCH('[\w\.\-]+'), - IS_NOT_IN_DB(db, table.username)] - if not settings.username_case_sensitive: - table.username.requires.insert(1,IS_LOWER()) else: table = db.define_table( settings.table_user_name, Field('first_name', length=128, default='', - label=self.messages.label_first_name), + label=self.messages.label_first_name, + requires = is_not_empty), Field('last_name', length=128, default='', - label=self.messages.label_last_name), + label=self.messages.label_last_name, + requires = is_not_empty), Field('email', length=512, default='', - label=self.messages.label_email), + label=self.messages.label_email, + requires = is_unique_email), Field(passfield, 'password', length=512, - readable=False, label=self.messages.label_password), + readable=False, label=self.messages.label_password, + requires = [is_crypted]), Field('registration_key', length=512, writable=False, readable=False, default='', label=self.messages.label_registration_key), @@ -1447,27 +1475,16 @@ class Auth(object): migrate), fake_migrate=fake_migrate, format='%(first_name)s %(last_name)s (%(id)s)')) - table.first_name.requires = \ - IS_NOT_EMPTY(error_message=self.messages.is_empty) - table.last_name.requires = \ - IS_NOT_EMPTY(error_message=self.messages.is_empty) - table[passfield].requires = [ - CRYPT(key=settings.hmac_key, - min_length=settings.password_min_length)] - table.email.requires = \ - [IS_EMAIL(error_message=self.messages.invalid_email), - IS_NOT_IN_DB(db, table.email)] - if not settings.email_case_sensitive: - table.email.requires.insert(1,IS_LOWER()) - table.registration_key.default = '' - settings.table_user = db[settings.table_user_name] + reference_table_user = 'reference %s' % settings.table_user_name if not settings.table_group_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_group_name,[])+signature_list table = db.define_table( settings.table_group_name, Field('role', length=512, default='', - label=self.messages.label_role), + label=self.messages.label_role, + requires = IS_NOT_IN_DB( + db, '%s.role'% settings.table_group_name)), Field('description', 'text', label=self.messages.label_description), *extra_fields, @@ -1476,55 +1493,41 @@ class Auth(object): settings.table_group_name, migrate), fake_migrate=fake_migrate, format = '%(role)s (%(id)s)')) - table.role.requires = IS_NOT_IN_DB(db, '%s.role' - % settings.table_group_name) - settings.table_group = db[settings.table_group_name] + reference_table_group = 'reference %s' % settings.table_group_name if not settings.table_membership_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_membership_name,[])+signature_list table = db.define_table( settings.table_membership_name, - Field('user_id', settings.table_user, + Field('user_id', reference_table_user, label=self.messages.label_user_id), - Field('group_id', settings.table_group, + Field('group_id', reference_table_group, label=self.messages.label_group_id), *extra_fields, **dict( migrate=self.__get_migrate( settings.table_membership_name, migrate), fake_migrate=fake_migrate)) - table.user_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_user_name, - settings.table_user._format) - table.group_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_group_name, - '%(role)s (%(id)s)') - settings.table_membership = db[settings.table_membership_name] if not settings.table_permission_name in db.tables: extra_fields = settings.extra_fields.get( settings.table_permission_name,[])+signature_list table = db.define_table( settings.table_permission_name, - Field('group_id', settings.table_group, - label=self.messages.label_group_id), + Field('group_id', reference_table_group, + label=self.messages.label_group_id), Field('name', default='default', length=512, - label=self.messages.label_name), + label=self.messages.label_name, + requires=is_not_empty), Field('table_name', length=512, - label=self.messages.label_table_name), + label=self.messages.label_table_name), Field('record_id', 'integer',default=0, - label=self.messages.label_record_id), + label=self.messages.label_record_id, + requires = IS_INT_IN_RANGE(0, 10 ** 9)), *extra_fields, **dict( migrate=self.__get_migrate( settings.table_permission_name, migrate), fake_migrate=fake_migrate)) - table.group_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_group_name, - '%(role)s (%(id)s)') - table.name.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) - #table.table_name.requires = IS_EMPTY_OR(IS_IN_SET(self.db.tables)) - table.record_id.requires = IS_INT_IN_RANGE(0, 10 ** 9) - settings.table_permission = db[settings.table_permission_name] if not settings.table_event_name in db.tables: table = db.define_table( settings.table_event_name, @@ -1534,29 +1537,25 @@ class Auth(object): Field('client_ip', default=current.request.client, label=self.messages.label_client_ip), - Field('user_id', settings.table_user, default=None, - label=self.messages.label_user_id), + Field('user_id', reference_table_user, default=None, + label=self.messages.label_user_id), Field('origin', default='auth', length=512, - label=self.messages.label_origin), + label=self.messages.label_origin, + requires=is_not_empty), Field('description', 'text', default='', - label=self.messages.label_description), + label=self.messages.label_description, + requires=is_not_empty), *settings.extra_fields.get(settings.table_event_name,[]), **dict( migrate=self.__get_migrate( settings.table_event_name, migrate), fake_migrate=fake_migrate)) - table.user_id.requires = IS_IN_DB(db, '%s.id' % - settings.table_user_name, - settings.table_user._format) - table.origin.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) - table.description.requires = IS_NOT_EMPTY(error_message=self.messages.is_empty) - settings.table_event = db[settings.table_event_name] now = current.request.now if settings.cas_domains: if not settings.table_cas_name in db.tables: table = db.define_table( settings.table_cas_name, - Field('user_id', settings.table_user, default=None, + Field('user_id', reference_table_user, default=None, label=self.messages.label_user_id), Field('created_on','datetime',default=now), Field('service',requires=IS_URL()), @@ -1567,20 +1566,26 @@ class Auth(object): migrate=self.__get_migrate( settings.table_cas_name, migrate), fake_migrate=fake_migrate)) - table.user_id.requires = IS_IN_DB(db, '%s.id' % \ - settings.table_user_name, - settings.table_user._format) - settings.table_cas = db[settings.table_cas_name] - db._lazy_tables = lazy_tables - if settings.cas_provider: + if not db._lazy_tables: + settings.table_user = db[settings.table_user_name] + settings.table_group = db[settings.table_group_name] + settings.table_membership = db[settings.table_membership_name] + settings.table_permission = db[settings.table_permission_name] + settings.table_event = db[settings.table_event_name] + if settings.cas_domains: + settings.table_cas = db[settings.table_cas_name] + + if settings.cas_provider: ### THIS IS NOT LAZY settings.actions_disabled = \ - ['profile','register','change_password','request_reset_password'] + ['profile','register','change_password', + 'request_reset_password'] from gluon.contrib.login_methods.cas_auth import CasAuth maps = settings.cas_maps - if not maps: + if not maps: + table_user = self.table_user() maps = dict((name,lambda v,n=name:v.get(n,None)) for name in \ - settings.table_user.fields if name!='id' \ - and settings.table_user[name].readable) + table_user.fields if name!='id' \ + and table_user[name].readable) maps['registration_id'] = \ lambda v,p=settings.cas_provider:'%s/%s' % (p,v['user']) actions = [settings.cas_actions['login'], @@ -1606,8 +1611,9 @@ class Auth(object): else: user_id = None # user unknown vars = vars or {} - self.settings.table_event.insert(description=description % vars, - origin=origin, user_id=user_id) + self.table_event().insert( + description=description % vars, + origin=origin, user_id=user_id) def get_or_create_user(self, keys, update_fields=['email']): """ @@ -1615,7 +1621,7 @@ class Auth(object): If the user exists already then password is updated. If the user doesn't yet exist, then they are created. """ - table_user = self.settings.table_user + table_user = self.table_user() user = None checks = [] # make a guess about who this user is @@ -1673,7 +1679,7 @@ class Auth(object): request = current.request session = current.session - table_user = self.settings.table_user + table_user = self.table_user() if self.settings.login_userfield: userfield = self.settings.login_userfield elif 'username' in table_user.fields: @@ -1711,7 +1717,7 @@ class Auth(object): request = current.request response = current.response session = current.session - db, table = self.db, self.settings.table_cas + db, table = self.db, self.table_cas() session._cas_service = request.vars.service or session._cas_service if not request.env.http_host in self.settings.cas_domains or \ not session._cas_service: @@ -1747,7 +1753,7 @@ class Auth(object): def cas_validate(self, version=2, proxy=False): request = current.request - db, table = self.db, self.settings.table_cas + db, table = self.db, self.table_cas() current.response.headers['Content-Type']='text' ticket = request.vars.ticket renew = True if request.vars.has_key('renew') else False @@ -1763,7 +1769,7 @@ class Auth(object): # If ticket is a service Ticket and RENEW flag respected if ticket[0:3] == 'ST-' and \ not ((row.renew and renew) ^ renew): - user = self.settings.table_user(row.user_id) + user = self.table_user()(row.user_id) row.delete_record() success = True def build_response(body): @@ -1779,7 +1785,7 @@ class Auth(object): TAG['cas:authenticationSuccess']( TAG['cas:user'](username), *[TAG['cas:'+field.name](user[field.name]) \ - for field in self.settings.table_user \ + for field in self.table_user() \ if field.readable])) else: if version == 1: @@ -1808,7 +1814,7 @@ class Auth(object): """ - table_user = self.settings.table_user + table_user = self.table_user() if self.settings.login_userfield: username = self.settings.login_userfield elif 'username' in table_user.fields: @@ -2043,7 +2049,7 @@ class Auth(object): """ - table_user = self.settings.table_user + table_user = self.table_user() request = current.request response = current.response session = current.session @@ -2058,7 +2064,7 @@ class Auth(object): if log is DEFAULT: log = self.messages.register_log - table_user = self.settings.table_user + table_user = self.table_user() if 'username' in table_user.fields: username = 'username' else: @@ -2182,7 +2188,7 @@ class Auth(object): """ key = getarg(-1) - table_user = self.settings.table_user + table_user = self.table_user() user = self.db(table_user.registration_key == key).select().first() if not user: redirect(self.settings.login_url) @@ -2221,7 +2227,7 @@ class Auth(object): """ - table_user = self.settings.table_user + table_user = self.table_user() if not 'username' in table_user.fields: raise HTTP(404) request = current.request @@ -2306,7 +2312,7 @@ class Auth(object): """ - table_user = self.settings.table_user + table_user = self.table_user() request = current.request response = current.response session = current.session @@ -2383,7 +2389,7 @@ class Auth(object): """ - table_user = self.settings.table_user + table_user = self.table_user() request = current.request # response = current.response session = current.session @@ -2403,7 +2409,7 @@ class Auth(object): form = SQLFORM.factory( Field('new_password', 'password', label=self.messages.new_password, - requires=self.settings.table_user[passfield].requires), + requires=self.table_user()[passfield].requires), Field('new_password2', 'password', label=self.messages.verify_password, requires=[IS_EXPR('value==%s' % repr(request.vars.new_password), @@ -2435,7 +2441,7 @@ class Auth(object): [, onvalidation=DEFAULT [, onaccept=DEFAULT [, log=DEFAULT]]]]) """ - table_user = self.settings.table_user + table_user = self.table_user() request = current.request response = current.response session = current.session @@ -2533,7 +2539,7 @@ class Auth(object): if not self.is_logged_in(): redirect(self.settings.login_url) db = self.db - table_user = self.settings.table_user + table_user = self.table_user() usern = self.settings.table_user_name s = db(table_user.id == self.user.id) @@ -2599,11 +2605,11 @@ class Auth(object): """ - table_user = self.settings.table_user + table_user = self.table_user() if not self.is_logged_in(): redirect(self.settings.login_url) passfield = self.settings.password_field - self.settings.table_user[passfield].writable = False + table_user[passfield].writable = False request = current.request session = current.session if next is DEFAULT: @@ -2654,6 +2660,7 @@ class Auth(object): request = current.request session = current.session auth = session.auth + table_user = self.table_user() if not self.is_logged_in(): raise HTTP(401, "Not Authorized") current_id = auth.user.id @@ -2665,12 +2672,12 @@ class Auth(object): self.settings.table_user_name, user_id): raise HTTP(403, "Forbidden") - user = self.settings.table_user(user_id) + user = table_user(user_id) if not user: raise HTTP(401, "Not Authorized") auth.impersonator = cPickle.dumps(session) auth.user.update( - self.settings.table_user._filter_fields(user, True)) + table_user._filter_fields(user, True)) self.user = auth.user if self.settings.login_onaccept: form = Storage(dict(vars=self.user)) @@ -2691,10 +2698,11 @@ class Auth(object): user_groups = self.user_groups = {} if current.session.auth: current.session.auth.user_groups = self.user_groups - memberships = self.db(self.settings.table_membership.user_id - == self.user.id).select() + table_group = self.table_group() + table_membership = self.table_membership() + memberships = self.db(table_membership.user_id==self.user.id).select() for membership in memberships: - group = self.settings.table_group(membership.group_id) + group = table_group(membership.group_id) if group: user_groups[membership.group_id] = group.role @@ -2705,12 +2713,12 @@ class Auth(object): if not self.is_logged_in(): redirect(self.settings.login_url) - memberships = self.db(self.settings.table_membership.user_id - == self.user.id).select() + table_membership = self.table_membership() + memberships = self.db(table_membership.user_id==self.user.id).select() table = TABLE() for membership in memberships: - groups = self.db(self.settings.table_group.id - == membership.group_id).select() + table_group = self.db[self.settings.table_group_name] + groups = self.db(table_group.id==membership.group_id).select() if groups: group = groups[0] table.append(TR(H3(group.role, '(%s)' % group.id))) @@ -2814,7 +2822,7 @@ class Auth(object): creates a group associated to a role """ - group_id = self.settings.table_group.insert( + group_id = self.table_group().insert( role=role, description=description) self.log_event(self.messages.add_group_log, dict(group_id=group_id, role=role)) @@ -2824,10 +2832,9 @@ class Auth(object): """ deletes a group """ - - self.db(self.settings.table_group.id == group_id).delete() - self.db(self.settings.table_membership.group_id == group_id).delete() - self.db(self.settings.table_permission.group_id == group_id).delete() + self.db(self.table_group().id == group_id).delete() + self.db(self.table_membership().group_id == group_id).delete() + self.db(self.table_permission().group_id == group_id).delete() self.update_groups() self.log_event(self.messages.del_group_log,dict(group_id=group_id)) @@ -2835,7 +2842,7 @@ class Auth(object): """ returns the group_id of the group specified by the role """ - rows = self.db(self.settings.table_group.role == role).select() + rows = self.db(self.table_group().role == role).select() if not rows: return None return rows[0].id @@ -2849,7 +2856,7 @@ class Auth(object): def user_group_role(self, user_id=None): if user_id: - user = self.settings.table_user[user_id] + user = self.table_user()[user_id] else: user = self.user return self.settings.create_user_groups % user @@ -2867,7 +2874,7 @@ class Auth(object): group_id = self.id_group(group_id) # interpret group_id as a role if not user_id and self.user: user_id = self.user.id - membership = self.settings.table_membership + membership = self.table_membership() if self.db((membership.user_id == user_id) & (membership.group_id == group_id)).select(): r = True @@ -2890,7 +2897,7 @@ class Auth(object): group_id = self.id_group(group_id) # interpret group_id as a role if not user_id and self.user: user_id = self.user.id - membership = self.settings.table_membership + membership = self.table_membership() record = membership(user_id = user_id,group_id = group_id) if record: return record.id @@ -2910,7 +2917,7 @@ class Auth(object): group_id = group_id or self.id_group(role) if not user_id and self.user: user_id = self.user.id - membership = self.settings.table_membership + membership = self.table_membership() self.log_event(self.messages.del_membership_log, dict(user_id=user_id,group_id=group_id)) ret = self.db(membership.user_id @@ -2941,7 +2948,7 @@ class Auth(object): if not user_id and not group_id and self.user: user_id = self.user.id if user_id: - membership = self.settings.table_membership + membership = self.table_membership() rows = self.db(membership.user_id == user_id).select(membership.group_id) groups = set([row.group_id for row in rows]) @@ -2949,7 +2956,7 @@ class Auth(object): return False else: groups = set([group_id]) - permission = self.settings.table_permission + permission = self.table_permission() rows = self.db(permission.name == name)(permission.table_name == str(table_name))(permission.record_id == record_id).select(permission.group_id) @@ -2982,7 +2989,7 @@ class Auth(object): gives group_id 'name' access to 'table_name' and 'record_id' """ - permission = self.settings.table_permission + permission = self.table_permission() if group_id == 0: group_id = self.user_group() record = self.db(permission.group_id==group_id)(permission.name==name)\ @@ -3011,7 +3018,7 @@ class Auth(object): revokes group_id 'name' access to 'table_name' and 'record_id' """ - permission = self.settings.table_permission + permission = self.table_permission() self.log_event(self.messages.del_permission_log, dict(group_id=group_id, name=name, table_name=table_name, record_id=record_id)) @@ -3039,8 +3046,8 @@ class Auth(object): self.has_permission(name, table, 0, user_id): return table.id > 0 db = self.db - membership = self.settings.table_membership - permission = self.settings.table_permission + membership = self.table_membership() + permission = self.table_permission() query = table.id.belongs( db(membership.user_id == user_id)\ (membership.group_id == permission.group_id)\ From b8dbb8a5dd567e30d02804cf765eaea68ba563e2 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 10:56:40 -0500 Subject: [PATCH 12/53] fixed auth with lazy auth --- VERSION | 2 +- gluon/tools.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index ff874f51..c687f9a9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 10:48:33) dev +Version 2.00.0 (2012-08-23 10:56:37) dev diff --git a/gluon/tools.py b/gluon/tools.py index c5fdab89..10736178 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1171,7 +1171,7 @@ class Auth(object): return self.db[self.settings.table_user_name] def table_group(self): return self.db[self.settings.table_group_name] - def table_memberhsip(self): + def table_membership(self): return self.db[self.settings.table_membership_name] def table_event(self): return self.db[self.settings.table_event_name] @@ -1272,7 +1272,7 @@ class Auth(object): if not 'register' in self.settings.actions_disabled: bar.insert(-1, s2) bar.insert(-1, register) - if 'username' in self.user_username and \ + if self.use_username and \ not 'retrieve_username' in self.settings.actions_disabled: bar.insert(-1, s2) bar.insert(-1, retrieve_username) @@ -1401,7 +1401,7 @@ class Auth(object): min_length=settings.password_min_length) is_unique_email = [ IS_EMAIL(error_message=self.messages.invalid_email), - IS_NOT_IN_DB(db, 'email.id')] + IS_NOT_IN_DB(db, '%s.email' % settings.table_user_name)] if not settings.email_case_sensitive: is_unique_email.insert(1,IS_LOWER()) if not settings.table_user_name in db.tables: From dcb4a92bc4f60302050420ec66210ef40fa7160f Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 11:11:41 -0500 Subject: [PATCH 13/53] R-2.0.1-rc2 --- VERSION | 2 +- gluon/storage.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c687f9a9..e2ad51cb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 10:56:37) dev +Version 2.00.0 (2012-08-23 11:11:38) dev diff --git a/gluon/storage.py b/gluon/storage.py index fa956703..1b6da5c1 100644 --- a/gluon/storage.py +++ b/gluon/storage.py @@ -170,6 +170,64 @@ class Messages(Settings): return str(self.T(value)) return value +class FastStorage(dict): + """ + Eventually this should replace class Storage but causes memory leak + because of http://bugs.python.org/issue1469629 + + >>> s = FastStorage() + >>> s.a = 1 + >>> s.a + 1 + >>> s['a'] + 1 + >>> s.b + >>> s['b'] + >>> s['b']=2 + >>> s['b'] + 2 + >>> s.b + 2 + >>> isinstance(s,dict) + True + >>> dict(s) + {'a': 1, 'b': 2} + >>> dict(FastStorage(s)) + {'a': 1, 'b': 2} + >>> import pickle + >>> s = pickle.loads(pickle.dumps(s)) + >>> dict(s) + {'a': 1, 'b': 2} + >>> del s.b + >>> del s.a + >>> s.a + >>> s.b + >>> s['a'] + >>> s['b'] + """ + def __init__(self, *args, **kwargs): + dict.__init__(self, *args, **kwargs) + self.__dict__ = self + def __getattr__(self,key): + return getattr(self,key) if key in self else None + def __getitem__(self,key): + return dict.get(self,key,None) + def copy(self): + self.__dict__ = {} + s = FastStorage(self) + self.__dict__ = self + return s + def __repr__(self): + return '' % dict.__repr__(self) + def __getstate__(self): + return dict(self) + def __setstate__(self, sdict): + dict.__init__(self, sdict) + self.__dict__=self + def update(self, *args, **kwargs): + dict.__init__(self, *args, **kwargs) + self.__dict__=self + class List(list): """ Like a regular python list but a[i] if i is out of bounds return None From 807045e8b30da740748e096812b51e1c34e6bd83 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 12:44:31 -0500 Subject: [PATCH 14/53] edited makefile --- Makefile | 8 ++++---- VERSION | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 472d89b5..864d37ec 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,7 @@ +all: + echo "The Makefile is used to build the distribution." + echo "In order to run web2py you do not need to make anything." + echo "just run web2py.py" clean: rm -f httpserver.log rm -f parameters*.py @@ -13,10 +17,6 @@ clean: find ./applications/examples/ -name '.*' -exec rm -f {} \; find ./applications/welcome/ -name '.*' -exec rm -f {} \; find ./ -name '*.pyc' -exec rm -f {} \; -all: - echo "The Makefile is used to build the distribution." - echo "In order to run web2py you do not need to make anything." - echo "just run web2py.py" epydoc: ### build epydoc rm -f -r applications/examples/static/epydoc/ diff --git a/VERSION b/VERSION index e2ad51cb..26abe865 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 11:11:38) dev +Version 2.00.0 (2012-08-23 12:44:28) dev From 00f9292e0667065cb13d931ee843265f9541439a Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 13:19:19 -0500 Subject: [PATCH 15/53] smarter index.html for wiki --- VERSION | 2 +- applications/welcome/views/default/index.html | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 26abe865..fd7fc765 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 12:44:28) dev +Version 2.00.0 (2012-08-23 13:19:16) dev diff --git a/applications/welcome/views/default/index.html b/applications/welcome/views/default/index.html index 50e64114..6e9ab1ff 100644 --- a/applications/welcome/views/default/index.html +++ b/applications/welcome/views/default/index.html @@ -1,4 +1,4 @@ -{{left_sidebar_enabled,right_sidebar_enabled=False,True}} +{{left_sidebar_enabled,right_sidebar_enabled=False,('message' in globals())}} {{extend 'layout.html'}} {{if 'message' in globals():}} @@ -17,6 +17,8 @@ _href=URL('admin','default','peek',args=(request.application,'views',request.controller,'index.html')))))}}
  • {{=T('You can modify this application and adapt it to your needs')}}
  • +{{elif 'content' in globals():}} +{{=content}} {{else:}} {{=BEAUTIFY(response._vars)}} {{pass}} @@ -31,4 +33,3 @@
  • {{=T('Documentation')}}
  • {{end}} - From 33ce161e202150594aa2c418559430120f4f8717 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 14:33:43 -0500 Subject: [PATCH 16/53] T bug in tools --- VERSION | 2 +- gluon/sqlhtml.py | 2 +- gluon/tools.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/VERSION b/VERSION index fd7fc765..dd19eb63 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 13:19:16) dev +Version 2.00.0 (2012-08-23 14:33:39) dev diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index a8a709c3..02314221 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -2067,7 +2067,7 @@ class SQLFORM(FORM): selectable(records) redirect(referrer) else: - htmltable = DIV(T('No records found')) + htmltable = DIV(current.T('No records found')) if csv and nrows: export_links =[] diff --git a/gluon/tools.py b/gluon/tools.py index 10736178..15776aca 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -4587,7 +4587,6 @@ class Wiki(object): elif zero=='_cloud': return self.cloud() - def first_paragraph(self,page): if not self.can_read(page): mm = page.body.replace('\r','') @@ -4600,8 +4599,8 @@ class Wiki(object): return body.replace('://HOSTNAME','://%s' % self.host) def read(self,slug): - if slug in '_cloud': - return self.cloud() + if slug in '_cloud': return self.cloud() + elif slug in '_search': return self.search() page = self.auth.db.wiki_page(slug=slug) if not page: redirect(URL(args=('_create',slug))) @@ -4806,7 +4805,8 @@ class Wiki(object): limitby=limitby)) if request.extension in ('html','load'): if not pages: - content.append(DIV(T("No results",_class='w2p_wiki_form'))) + content.append(DIV(current.T("No results"), + _class='w2p_wiki_form')) def link(t): return A(t,_href=URL(args='_search',vars=dict(tags=t))) items = [DIV(H3(A(p.title,_href=URL(args=p.slug))), From b400d3844dbf350f4e0553bf978941f400fcf142 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 14:52:45 -0500 Subject: [PATCH 17/53] better style in wiki search and tagcloud --- VERSION | 2 +- applications/welcome/static/css/web2py.css | 2 +- gluon/tools.py | 30 ++++++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/VERSION b/VERSION index dd19eb63..2ed84402 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 14:33:39) dev +Version 2.00.0 (2012-08-23 14:52:42) dev diff --git a/applications/welcome/static/css/web2py.css b/applications/welcome/static/css/web2py.css index 2ac5c115..d6f06391 100644 --- a/applications/welcome/static/css/web2py.css +++ b/applications/welcome/static/css/web2py.css @@ -84,7 +84,7 @@ td.w2p_fl {text-align:right} td.w2p_fl, td.w2p_fw {padding-right:7px} td.w2p_fl,td.w2p_fc {padding-top:4px} div.w2p_export_menu {margin:5px 0} -div.w2p_export_menu a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;} +div.w2p_export_menu a, div.w2p_wiki_tags a, div.w2p_cloud a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;} /* tr#submit_record__row {border-top:1px solid #E5E5E5} */ #submit_record__row td {padding-top:.5em} diff --git a/gluon/tools.py b/gluon/tools.py index 15776aca..59ff9e64 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -4684,10 +4684,11 @@ class Wiki(object): def create(self): if not self.can_edit(): return self.not_authorized() db = self.auth.db - form = SQLFORM.factory( - Field('slug',default=current.request.args(1), - label = 'New Page', - requires=(IS_SLUG(),IS_NOT_IN_DB(db,db.wiki_page.slug)))) + form = FORM(INPUT(_name='slug',value=current.request.args(1), + requires=(IS_SLUG(), + IS_NOT_IN_DB(db,db.wiki_page.slug))), + INPUT(_type='submit', + _value=current.T('Create Page from Slug'))) if form.process().accepted: redirect(URL(args=('_edit',form.vars.slug))) return dict(content=form) @@ -4781,9 +4782,10 @@ class Wiki(object): request = current.request content = CAT() if tags is None and query is None: - form = SQLFORM.factory(Field('tags',requires=IS_NOT_EMPTY(), - default=request.vars.tags, - label=current.T('Search'))) + form = FORM(INPUT(_name='tags',requires=IS_NOT_EMPTY(), + value=request.vars.tags), + INPUT(_type="submit",_value=current.T('Search')), + _method='GET') content.append(DIV(form,_class='w2p_wiki_form')) if request.vars: tags = [v.strip() for v in request.vars.tags.split(',')] @@ -4799,6 +4801,7 @@ class Wiki(object): if query is None: query = (db.wiki_page.id==db.wiki_tag.wiki_page)&\ (db.wiki_tag.name.belongs(tags)) + query = query|db.wiki_page.title.startswith(request.vars.tags) pages = db(query).select( *fields,**dict(orderby=orderby or ~count, groupby=db.wiki_page.id, @@ -4812,9 +4815,10 @@ class Wiki(object): items = [DIV(H3(A(p.title,_href=URL(args=p.slug))), MARKMIN(self.first_paragraph(p)) \ if preview else '', - SPAN(*[link(t.strip()) for t in \ - p.tags or [] if t.strip()]), - _class='w2p_wiki_tags') + DIV(_class='w2p_wiki_tags', + *[link(t.strip()) for t in \ + p.tags or [] if t.strip()]), + _class='w2p_wiki_search_item') for p in pages] content.append(DIV(_class='w2p_wiki_pages',*items)) else: @@ -4836,9 +4840,9 @@ class Wiki(object): a,b = ids[0](count), ids[-1](count) def scale(c): return '%.2f' % (3.0*(c-b)/max(a-b,1)+1) - items = [A(item.wiki_tag.name,_class='w2p_cloud_tag', - _style='padding-right:0.2em;font-size:%sem' \ - % scale(item(count)), + items = [A(item.wiki_tag.name, + _style='padding:0.2em;font-size:%sem' \ + % scale(item(count)), _href=URL(args='_search', vars=dict(tags=item.wiki_tag.name))) for item in ids] From 2c866c68e4ebb92e3508ad3131774bf7afc90db2 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 15:04:08 -0500 Subject: [PATCH 18/53] fixed tag rendering end edit menu permissions --- VERSION | 2 +- gluon/tools.py | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/VERSION b/VERSION index 2ed84402..47d1167d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 14:52:42) dev +Version 2.00.0 (2012-08-23 15:04:04) dev diff --git a/gluon/tools.py b/gluon/tools.py index 59ff9e64..0fe875d4 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -4463,8 +4463,12 @@ class Wiki(object): rows_page = 25 regex_redirect = re.compile('redirect\s+(\w+\://\S+)\s*') def markmin_render(self,page): - return MARKMIN(page.body,url=True,environment=self.env, + html = MARKMIN(page.body,url=True,environment=self.env, autolinks=lambda link: expand_one(link,{})).xml() + html += DIV(_class='w2p_wiki_tags', + *[A(t.strip(),_href=URL(args='_search',vars=dict(q=t))) + for t in page.tags or [] if t.strip()]).xml() + return html @staticmethod def component(text): """ @@ -4767,7 +4771,7 @@ class Wiki(object): submenu.append((current.T('Create New Page'),None, URL(controller,function,args=('_create')))) - # if self.can_manage(): + if self.can_manage(): submenu.append((current.T('Manage Pages'),None, URL(controller,function,args=('_pages')))) submenu.append((current.T('Edit Menu'),None, @@ -4782,13 +4786,13 @@ class Wiki(object): request = current.request content = CAT() if tags is None and query is None: - form = FORM(INPUT(_name='tags',requires=IS_NOT_EMPTY(), - value=request.vars.tags), + form = FORM(INPUT(_name='q',requires=IS_NOT_EMPTY(), + value=request.vars.q), INPUT(_type="submit",_value=current.T('Search')), _method='GET') content.append(DIV(form,_class='w2p_wiki_form')) - if request.vars: - tags = [v.strip() for v in request.vars.tags.split(',')] + if request.vars.q: + tags = [v.strip() for v in request.vars.q.split(',')] tags = [v for v in tags if v] if tags or not query is None: db = self.auth.db @@ -4801,7 +4805,7 @@ class Wiki(object): if query is None: query = (db.wiki_page.id==db.wiki_tag.wiki_page)&\ (db.wiki_tag.name.belongs(tags)) - query = query|db.wiki_page.title.startswith(request.vars.tags) + query = query|db.wiki_page.title.startswith(request.vars.q) pages = db(query).select( *fields,**dict(orderby=orderby or ~count, groupby=db.wiki_page.id, @@ -4811,7 +4815,7 @@ class Wiki(object): content.append(DIV(current.T("No results"), _class='w2p_wiki_form')) def link(t): - return A(t,_href=URL(args='_search',vars=dict(tags=t))) + return A(t,_href=URL(args='_search',vars=dict(q=t))) items = [DIV(H3(A(p.title,_href=URL(args=p.slug))), MARKMIN(self.first_paragraph(p)) \ if preview else '', @@ -4844,7 +4848,7 @@ class Wiki(object): _style='padding:0.2em;font-size:%sem' \ % scale(item(count)), _href=URL(args='_search', - vars=dict(tags=item.wiki_tag.name))) + vars=dict(q=item.wiki_tag.name))) for item in ids] return dict(content=DIV(_class='w2p_cloud',*items)) From a4651eeee1835c94117928a6d2457f2cb0f2798f Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 16:56:26 -0500 Subject: [PATCH 19/53] fixed problem with fpdf import in generics, thanks Adrew --- VERSION | 2 +- gluon/contrib/generics.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 47d1167d..a99d2c37 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 15:04:04) dev +Version 2.00.0 (2012-08-23 16:56:22) dev diff --git a/gluon/contrib/generics.py b/gluon/contrib/generics.py index a5f89dd7..d50137c0 100644 --- a/gluon/contrib/generics.py +++ b/gluon/contrib/generics.py @@ -7,7 +7,7 @@ import gluon.serializers from gluon import current, HTTP from gluon.html import markmin_serializer, TAG, HTML, BODY, UL, XML, H1 from gluon.contenttype import contenttype -from gluon.contrib.pyfpdf import FPDF, HTMLMixin +from gluon.contrib.fpdf import FPDF, HTMLMixin from gluon.sanitizer import sanitize from gluon.contrib.markmin.markmin2latex import markmin2latex from gluon.contrib.markmin.markmin2pdf import markmin2pdf From fefac4b7287ec24de958c70da91dbc969b376ea9 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Thu, 23 Aug 2012 18:59:32 -0500 Subject: [PATCH 20/53] added contrib test, thanks Mariano --- VERSION | 2 +- gluon/tests/test_contribs.py | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 gluon/tests/test_contribs.py diff --git a/VERSION b/VERSION index a99d2c37..f2314820 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 16:56:22) dev +Version 2.00.0 (2012-08-23 18:59:28) dev diff --git a/gluon/tests/test_contribs.py b/gluon/tests/test_contribs.py new file mode 100644 index 00000000..6af457ad --- /dev/null +++ b/gluon/tests/test_contribs.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" Unit tests for contribs """ + +import sys +import os +import unittest +if os.path.isdir('gluon'): + sys.path.append(os.path.realpath('gluon')) +else: + sys.path.append(os.path.realpath('../')) + +from utils import md5_hash +import contrib.fpdf as fpdf +import contrib.pyfpdf as pyfpdf + + +class TestContribs(unittest.TestCase): + """ Tests the contrib package """ + + def test_fpdf(self): + """ Basic PDF test and sanity checks """ + + self.assertEqual(fpdf.FPDF_VERSION, pyfpdf.FPDF_VERSION, 'version mistmatch') + self.assertEqual(fpdf.FPDF, pyfpdf.FPDF, 'class mistmatch') + + pdf = fpdf.FPDF() + pdf.add_page() + pdf.compress = False + pdf.set_font('Arial', '',14) + pdf.ln(10) + pdf.write(5, 'hello world') + pdf_out = pdf.output('', 'S') + + self.assertTrue(fpdf.FPDF_VERSION in pdf_out, 'version string') + self.assertTrue('hello world' in pdf_out, 'sample message') + + +if __name__ == '__main__': + unittest.main() From 470ddde0013d6f3b023ef28fb908435a002d69bb Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 08:57:14 -0500 Subject: [PATCH 21/53] added missing table permission, thanks Daniel --- VERSION | 2 +- gluon/tools.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f2314820..c67bbfcc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-23 18:59:28) dev +Version 2.00.0 (2012-08-24 08:56:41) dev diff --git a/gluon/tools.py b/gluon/tools.py index 0fe875d4..4752f1c8 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1173,6 +1173,8 @@ class Auth(object): return self.db[self.settings.table_group_name] def table_membership(self): return self.db[self.settings.table_membership_name] + def table_permission(self): + return self.db[self.settings.table_membership_name] def table_event(self): return self.db[self.settings.table_event_name] def table_cas(self): From 449e2332911d664a94ac0d8b249181f8828b5012 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 09:15:34 -0500 Subject: [PATCH 22/53] fixed problem with _listify, thanks Daniel --- VERSION | 2 +- gluon/dal.py | 37 +++++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/VERSION b/VERSION index c67bbfcc..97245b88 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 08:56:41) dev +Version 2.00.0 (2012-08-24 09:15:19) dev diff --git a/gluon/dal.py b/gluon/dal.py index 30be93cc..c6bc6e1d 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -7501,33 +7501,38 @@ class Table(dict): return self._db._adapter.drop(self,mode) def _listify(self,fields,update=False): - new_fields = [] - new_fields_names = [] + new_fields = {} # format: new_fields[name] = (field,value) + # store all fields passed as input in new_fields for name in fields: if not name in self.fields: if name != 'id': - raise SyntaxError, 'Field %s does not belong to the table' % name + raise SyntaxError, \ + 'Field %s does not belong to the table' % name else: field = self[name] value = fields[name] - if field.filter_in: value = field.filter_in(value) - new_fields.append((field,value)) - new_fields_names.append(name) - for ofield in self: - if not ofield.name in new_fields_names: - if not update and not ofield.default is None: - new_fields.append((ofield,ofield.default)) - elif update and not ofield.update is None: - new_fields.append((ofield,ofield.update)) + if field.filter_in: + value = field.filter_in(value) + new_fields[name] = (field,value) + # check all fields that should be in the self table for ofield in self: + name = ofield.name + # if field is supposed to be computed, compute it! if ofield.compute: try: - new_fields.append((ofield,ofield.compute(Row(fields)))) + new_fields[name] = (ofield,ofield.compute(Row(fields))) except KeyError: pass - if not update and ofield.required and not ofield.name in new_fields_names: - raise SyntaxError,'Table: missing required field: %s' % ofield.name - return new_fields + # if field is required, check its default value + elif not name in new_fields: + if not update and not ofield.default is None: + new_fields[name] = (ofield,ofield.default) + elif update and not ofield.update is None: + new_fields[name] = (ofield,ofield.update) + # error if field if required, record to be create and field missing + if not update and ofield.required and not name in new_fields: + raise SyntaxError, 'Table: missing required field: %s' % name + return new_fields.values() def _attempt_upload(self, fields): for field in self: From ea2e737ced4b976f68a3cfba9e0f5e010d2cd9a7 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 09:23:20 -0500 Subject: [PATCH 23/53] improved oparsing of CLOB in Oracle, thanks Daniel --- VERSION | 2 +- gluon/dal.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 97245b88..cca4a5d3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 09:15:19) dev +Version 2.00.0 (2012-08-24 09:23:07) dev diff --git a/gluon/dal.py b/gluon/dal.py index c6bc6e1d..62d1ca80 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -2735,6 +2735,14 @@ class OracleAdapter(BaseAdapter): self.execute('SELECT %s.currval FROM dual;' % sequence_name) return int(self.cursor.fetchone()[0]) + def parse_value(self, value, field_type, blob_decode=True): + if blob_decode and isinstance(value, cx_Oracle.LOB): + try: + value = value.read() + except cx_Oracle.ProgrammingError: + # After a subsequent fetch the LOB value is not valid anymore + pass + return BaseAdapter.parse_value(self, value, field_type, blob_decode) class MSSQLAdapter(BaseAdapter): From cd44545b7460f42499bd463c75b3d7ae35fb5269 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 09:24:50 -0500 Subject: [PATCH 24/53] fixed app_cleanup of cache, thanks Spiffytech --- VERSION | 2 +- gluon/admin.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index cca4a5d3..672bc5b2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 09:23:07) dev +Version 2.00.0 (2012-08-24 09:24:38) dev diff --git a/gluon/admin.py b/gluon/admin.py index ce7bdaab..b5037bd8 100644 --- a/gluon/admin.py +++ b/gluon/admin.py @@ -126,7 +126,7 @@ def app_cleanup(app, request): r = False # Remove cache files - path = apath('%s/sessions/' % app, request) + path = apath('%s/cache/' % app, request) if os.path.exists(path): for f in os.listdir(path): try: From 718544322b8c25ccd5a7a4c95095ec5f08a31981 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 09:26:48 -0500 Subject: [PATCH 25/53] better generation of link in rpx_account, thanks Michele --- VERSION | 2 +- gluon/contrib/login_methods/rpx_account.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 672bc5b2..3505cad3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 09:24:38) dev +Version 2.00.0 (2012-08-24 09:26:31) dev diff --git a/gluon/contrib/login_methods/rpx_account.py b/gluon/contrib/login_methods/rpx_account.py index da6b4251..46837cf5 100644 --- a/gluon/contrib/login_methods/rpx_account.py +++ b/gluon/contrib/login_methods/rpx_account.py @@ -120,7 +120,7 @@ def use_janrain(auth,filename='private/janrain.key',**kwargs): request = current.request domain,key = open(path,'r').read().strip().split(':') host = current.request.env.http_host - url = "http://%s/%s/default/user/login" % (host,request.application) + url = URL('default', 'user', args='login', scheme=True) auth.settings.actions_disabled = \ ['register','change_password','request_reset_password'] auth.settings.login_form = RPXAccount( From b351f1515fc84b417e58706fb76321e2f7f4eced Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 09:44:13 -0500 Subject: [PATCH 26/53] upgraded to Bootstrap 2.1.0 thanks Alec Taylor --- VERSION | 2 +- applications/welcome/models/menu.py | 2 +- .../static/css/bootstrap-responsive.min.css | 4 +- .../welcome/static/css/bootstrap.min.css | 4 +- .../welcome/static/css/bootswatch.css | 271 ++++++++++++------ applications/welcome/views/layout.html | 1 - 6 files changed, 184 insertions(+), 100 deletions(-) diff --git a/VERSION b/VERSION index 3505cad3..f5f172a6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 09:26:31) dev +Version 2.00.0 (2012-08-24 09:43:38) dev diff --git a/applications/welcome/models/menu.py b/applications/welcome/models/menu.py index 784f4a4a..6b325cdc 100644 --- a/applications/welcome/models/menu.py +++ b/applications/welcome/models/menu.py @@ -35,7 +35,7 @@ def _(): ctr = request.controller # useful links to internal and external resources response.menu+=[ - (SPAN('web2py',_style='color:yellow'),False, 'http://web2py.com', [ + ('web2py',False, 'http://web2py.com', [ (T('My Sites'),False,URL('admin','default','site')), (T('This App'),False,URL('admin','default','design/%s' % app), [ (T('Controller'),False, diff --git a/applications/welcome/static/css/bootstrap-responsive.min.css b/applications/welcome/static/css/bootstrap-responsive.min.css index 1f55036a..ab59da34 100644 --- a/applications/welcome/static/css/bootstrap-responsive.min.css +++ b/applications/welcome/static/css/bootstrap-responsive.min.css @@ -1,9 +1,9 @@ /*! - * Bootstrap Responsive v2.0.4 + * Bootstrap Responsive v2.1.0 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. - */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}@media(max-width:767px){.visible-phone{display:inherit!important}.hidden-phone{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(min-width:768px) and (max-width:979px){.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:18px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{position:absolute;top:10px;right:10px;left:10px;width:auto;margin:0}.modal.fade.in{top:auto}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:auto;margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.762430939%;*margin-left:2.709239449638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:99.999999993%;*width:99.9468085036383%}.row-fluid .span11{width:91.436464082%;*width:91.38327259263829%}.row-fluid .span10{width:82.87292817100001%;*width:82.8197366816383%}.row-fluid .span9{width:74.30939226%;*width:74.25620077063829%}.row-fluid .span8{width:65.74585634900001%;*width:65.6926648596383%}.row-fluid .span7{width:57.182320438000005%;*width:57.129128948638304%}.row-fluid .span6{width:48.618784527%;*width:48.5655930376383%}.row-fluid .span5{width:40.055248616%;*width:40.0020571266383%}.row-fluid .span4{width:31.491712705%;*width:31.4385212156383%}.row-fluid .span3{width:22.928176794%;*width:22.874985304638297%}.row-fluid .span2{width:14.364640883%;*width:14.311449393638298%}.row-fluid .span1{width:5.801104972%;*width:5.747913482638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:714px}input.span11,textarea.span11,.uneditable-input.span11{width:652px}input.span10,textarea.span10,.uneditable-input.span10{width:590px}input.span9,textarea.span9,.uneditable-input.span9{width:528px}input.span8,textarea.span8,.uneditable-input.span8{width:466px}input.span7,textarea.span7,.uneditable-input.span7{width:404px}input.span6,textarea.span6,.uneditable-input.span6{width:342px}input.span5,textarea.span5,.uneditable-input.span5{width:280px}input.span4,textarea.span4,.uneditable-input.span4{width:218px}input.span3,textarea.span3,.uneditable-input.span3{width:156px}input.span2,textarea.span2,.uneditable-input.span2{width:94px}input.span1,textarea.span1,.uneditable-input.span1{width:32px}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:30px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.564102564%;*margin-left:2.510911074638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145300001%;*width:91.3997999636383%}.row-fluid .span10{width:82.905982906%;*width:82.8527914166383%}.row-fluid .span9{width:74.358974359%;*width:74.30578286963829%}.row-fluid .span8{width:65.81196581200001%;*width:65.7587743226383%}.row-fluid .span7{width:57.264957265%;*width:57.2117657756383%}.row-fluid .span6{width:48.717948718%;*width:48.6647572286383%}.row-fluid .span5{width:40.170940171000005%;*width:40.117748681638304%}.row-fluid .span4{width:31.623931624%;*width:31.5707401346383%}.row-fluid .span3{width:23.076923077%;*width:23.0237315876383%}.row-fluid .span2{width:14.529914530000001%;*width:14.4767230406383%}.row-fluid .span1{width:5.982905983%;*width:5.929714493638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:1160px}input.span11,textarea.span11,.uneditable-input.span11{width:1060px}input.span10,textarea.span10,.uneditable-input.span10{width:960px}input.span9,textarea.span9,.uneditable-input.span9{width:860px}input.span8,textarea.span8,.uneditable-input.span8{width:760px}input.span7,textarea.span7,.uneditable-input.span7{width:660px}input.span6,textarea.span6,.uneditable-input.span6{width:560px}input.span5,textarea.span5,.uneditable-input.span5{width:460px}input.span4,textarea.span4,.uneditable-input.span4{width:360px}input.span3,textarea.span3,.uneditable-input.span3{width:260px}input.span2,textarea.span2,.uneditable-input.span2{width:160px}input.span1,textarea.span1,.uneditable-input.span1{width:60px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:18px}.navbar-fixed-bottom{margin-top:18px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 9px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#999;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#222}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222;border-bottom:1px solid #222;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:auto;margin-left:0}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade.in{top:auto}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#555;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#555;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/applications/welcome/static/css/bootstrap.min.css b/applications/welcome/static/css/bootstrap.min.css index eca5261d..3119038a 100755 --- a/applications/welcome/static/css/bootstrap.min.css +++ b/applications/welcome/static/css/bootstrap.min.css @@ -1,9 +1,9 @@ /*! - * Bootstrap v2.0.4 + * Bootstrap v2.1.0 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. - */article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.127659574%;*margin-left:2.0744680846382977%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:99.99999998999999%;*width:99.94680850063828%}.row-fluid .span11{width:91.489361693%;*width:91.4361702036383%}.row-fluid .span10{width:82.97872339599999%;*width:82.92553190663828%}.row-fluid .span9{width:74.468085099%;*width:74.4148936096383%}.row-fluid .span8{width:65.95744680199999%;*width:65.90425531263828%}.row-fluid .span7{width:57.446808505%;*width:57.3936170156383%}.row-fluid .span6{width:48.93617020799999%;*width:48.88297871863829%}.row-fluid .span5{width:40.425531911%;*width:40.3723404216383%}.row-fluid .span4{width:31.914893614%;*width:31.8617021246383%}.row-fluid .span3{width:23.404255317%;*width:23.3510638276383%}.row-fluid .span2{width:14.89361702%;*width:14.8404255306383%}.row-fluid .span1{width:6.382978723%;*width:6.329787233638298%}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:""}.container-fluid:after{clear:both}p{margin:0 0 9px}p small{font-size:11px;color:#999}.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px}h1,h2,h3,h4,h5,h6{margin:0;font-family:inherit;font-weight:bold;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999}h1{font-size:30px;line-height:36px}h1 small{font-size:18px}h2{font-size:24px;line-height:36px}h2 small{font-size:18px}h3{font-size:18px;line-height:27px}h3 small{font-size:14px}h4,h5,h6{line-height:18px}h4{font-size:14px}h4 small{font-size:12px}h5{font-size:12px}h6{font-size:11px;color:#999;text-transform:uppercase}.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eee}.page-header h1{line-height:1}ul,ol{padding:0;margin:0 0 9px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}ul{list-style:disc}ol{list-style:decimal}li{line-height:18px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}dl{margin-bottom:18px}dt,dd{line-height:18px}dt{font-weight:bold;line-height:17px}dd{margin-left:9px}.dl-horizontal dt{float:left;width:120px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:130px}hr{margin:18px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}strong{font-weight:bold}em{font-style:italic}.muted{color:#999}abbr[title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px}blockquote small{display:block;line-height:18px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:18px;font-style:normal;line-height:18px}small{font-size:100%}cite{font-style:normal}code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12.025px;line-height:18px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:18px}pre code{padding:0;color:inherit;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 18px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:13.5px;color:#999}label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:18px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555}input,textarea{width:210px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-ms-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer}input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}.uneditable-textarea{width:auto;height:auto}select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px}select{width:220px;border:1px solid #bbb}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.radio,.checkbox{min-height:18px;padding-left:18px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:930px}input.span11,textarea.span11,.uneditable-input.span11{width:850px}input.span10,textarea.span10,.uneditable-input.span10{width:770px}input.span9,textarea.span9,.uneditable-input.span9{width:690px}input.span8,textarea.span8,.uneditable-input.span8{width:610px}input.span7,textarea.span7,.uneditable-input.span7{width:530px}input.span6,textarea.span6,.uneditable-input.span6{width:450px}input.span5,textarea.span5,.uneditable-input.span5{width:370px}input.span4,textarea.span4,.uneditable-input.span4{width:290px}input.span3,textarea.span3,.uneditable-input.span3{width:210px}input.span2,textarea.span2,.uneditable-input.span2{width:130px}input.span1,textarea.span1,.uneditable-input.span1{width:50px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee;border-color:#ddd}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853}.control-group.warning .checkbox:focus,.control-group.warning .radio:focus,.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48}.control-group.error .checkbox:focus,.control-group.error .radio:focus,.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847}.control-group.success .checkbox:focus,.control-group.success .radio:focus,.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;content:""}.form-actions:after{clear:both}.uneditable-input{overflow:hidden;white-space:nowrap;cursor:not-allowed;background-color:#fff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}:-moz-placeholder{color:#999}:-ms-input-placeholder{color:#999}::-webkit-input-placeholder{color:#999}.help-block,.help-inline{color:#555}.help-block{display:block;margin-bottom:9px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-prepend,.input-append{margin-bottom:5px}.input-prepend input,.input-append input,.input-prepend select,.input-append select,.input-prepend .uneditable-input,.input-append .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:middle;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-prepend input:focus,.input-append input:focus,.input-prepend select:focus,.input-append select:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{z-index:2}.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc}.input-prepend .add-on,.input-append .add-on{display:inline-block;width:auto;height:18px;min-width:16px;padding:4px 5px;font-weight:normal;line-height:18px;text-align:center;text-shadow:0 1px 0 #fff;vertical-align:middle;background-color:#eee;border:1px solid #ccc}.input-prepend .add-on,.input-append .add-on,.input-prepend .btn,.input-append .btn{margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append .uneditable-input{border-right-color:#ccc;border-left-color:#eee}.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:9px}legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:18px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:160px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:160px}.form-horizontal .help-block{margin-top:9px;margin-bottom:0}.form-horizontal .form-actions{padding-left:160px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:18px}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapsed;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9}.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5}table .span1{float:none;width:44px;margin-left:0}table .span2{float:none;width:124px;margin-left:0}table .span3{float:none;width:204px;margin-left:0}table .span4{float:none;width:284px;margin-left:0}table .span5{float:none;width:364px;margin-left:0}table .span6{float:none;width:444px;margin-left:0}table .span7{float:none;width:524px;margin-left:0}table .span8{float:none;width:604px;margin-left:0}table .span9{float:none;width:684px;margin-left:0}table .span10{float:none;width:764px;margin-left:0}table .span11{float:none;width:844px;margin-left:0}table .span12{float:none;width:924px;margin-left:0}table .span13{float:none;width:1004px;margin-left:0}table .span14{float:none;width:1084px;margin-left:0}table .span15{float:none;width:1164px;margin-left:0}table .span16{float:none;width:1244px;margin-left:0}table .span17{float:none;width:1324px;margin-left:0}table .span18{float:none;width:1404px;margin-left:0}table .span19{float:none;width:1484px;margin-left:0}table .span20{float:none;width:1564px;margin-left:0}table .span21{float:none;width:1644px;margin-left:0}table .span22{float:none;width:1724px;margin-left:0}table .span23{float:none;width:1804px;margin-left:0}table .span24{float:none;width:1884px;margin-left:0}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../images/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0}.icon-white{background-image:url("../images/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";opacity:.3;filter:alpha(opacity=30)}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown:hover .caret,.open .caret{opacity:1;filter:alpha(opacity=100)}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:4px 0;margin:1px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#333;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;background-color:#08c}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:"\2191"}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0,0,0,0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-ms-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-ms-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 10px 4px;margin-bottom:0;*margin-left:.3em;font-size:13px;line-height:18px;*line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(top,#fff,#e6e6e6);background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff',endColorstr='#e6e6e6',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover{color:#333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-ms-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.btn-large [class^="icon-"]{margin-top:1px}.btn-small{padding:5px 9px;font-size:11px;line-height:16px}.btn-small [class^="icon-"]{margin-top:-1px}.btn-mini{padding:2px 6px;font-size:11px;line-height:14px}.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#ccc;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.btn-primary{background-color:#0074cc;*background-color:#05c;background-image:-ms-linear-gradient(top,#08c,#05c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#05c));background-image:-webkit-linear-gradient(top,#08c,#05c);background-image:-o-linear-gradient(top,#08c,#05c);background-image:-moz-linear-gradient(top,#08c,#05c);background-image:linear-gradient(top,#08c,#05c);background-repeat:repeat-x;border-color:#05c #05c #003580;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#0088cc',endColorstr='#0055cc',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#05c;*background-color:#004ab3}.btn-primary:active,.btn-primary.active{background-color:#004099 \9}.btn-warning{background-color:#faa732;*background-color:#f89406;background-image:-ms-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(top,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450',endColorstr='#f89406',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{background-color:#da4f49;*background-color:#bd362f;background-image:-ms-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(top,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#bd362f',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{background-color:#5bb75b;*background-color:#51a351;background-image:-ms-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(top,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#62c462',endColorstr='#51a351',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{background-color:#49afcd;*background-color:#2f96b4;background-image:-ms-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(top,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de',endColorstr='#2f96b4',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{background-color:#414141;*background-color:#222;background-image:-ms-linear-gradient(top,#555,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#555),to(#222));background-image:-webkit-linear-gradient(top,#555,#222);background-image:-o-linear-gradient(top,#555,#222);background-image:-moz-linear-gradient(top,#555,#222);background-image:linear-gradient(top,#555,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#555555',endColorstr='#222222',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-group{position:relative;*margin-left:.3em;*zoom:1}.btn-group:before,.btn-group:after{display:table;content:""}.btn-group:after{clear:both}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:9px;margin-bottom:9px}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1}.btn-group>.btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.dropdown-toggle{*padding-top:4px;padding-right:8px;*padding-bottom:4px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini.dropdown-toggle{padding-right:5px;padding-left:5px}.btn-group>.btn-small.dropdown-toggle{*padding-top:4px;*padding-bottom:4px}.btn-group>.btn-large.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#05c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:7px;margin-left:0}.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100)}.btn-mini .caret{margin-top:5px}.btn-small .caret{margin-top:6px}.btn-large .caret{margin-top:6px;border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-top:0;border-bottom:5px solid #000}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:.75;filter:alpha(opacity=75)}.alert{padding:8px 35px 8px 14px;margin-bottom:18px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert-heading{color:inherit}.alert .close{position:relative;top:-2px;right:-21px;line-height:18px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:18px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>.pull-right{float:right}.nav .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:18px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px}.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333;border-bottom-color:#333}.nav>.dropdown.active>a:hover{color:#000;cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.navbar{*position:relative;*z-index:2;margin-bottom:18px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top,#333,#222);background-image:-ms-linear-gradient(top,#333,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#333),to(#222));background-image:-webkit-linear-gradient(top,#333,#222);background-image:-o-linear-gradient(top,#333,#222);background-image:linear-gradient(top,#333,#222);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1)}.navbar .container{width:auto}.nav-collapse.collapse{height:auto}.navbar{color:#999}.navbar .brand:hover{text-decoration:none}.navbar .brand{display:block;float:left;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#999}.navbar .navbar-text{margin-bottom:0;line-height:40px}.navbar .navbar-link{color:#999}.navbar .navbar-link:hover{color:#fff}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn{margin:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#fff;background-color:#626262;border:1px solid #151515;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-bottom{bottom:0}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right}.navbar .nav>li{display:block;float:left}.navbar .nav>li>a{float:none;padding:9px 10px 11px;line-height:19px;color:#999;text-decoration:none;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar .btn{display:inline-block;padding:4px 10px 4px;margin:5px 5px 6px;line-height:18px}.navbar .btn-group{padding:5px 5px 6px;margin:0}.navbar .nav>li>a:hover{color:#fff;text-decoration:none;background-color:transparent}.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#fff;text-decoration:none;background-color:#222}.navbar .divider-vertical{width:1px;height:40px;margin:0 9px;overflow:hidden;background-color:#222;border-right:1px solid #333}.navbar .nav.pull-right{margin-right:0;margin-left:10px}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;background-color:#2c2c2c;*background-color:#222;background-image:-ms-linear-gradient(top,#333,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#333),to(#222));background-image:-webkit-linear-gradient(top,#333,#222);background-image:-o-linear-gradient(top,#333,#222);background-image:linear-gradient(top,#333,#222);background-image:-moz-linear-gradient(top,#333,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{background-color:#222;*background-color:#151515}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#080808 \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown .dropdown-toggle .caret,.navbar .nav li.dropdown.open .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .nav li.dropdown.active .caret{opacity:1;filter:alpha(opacity=100)}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:transparent}.navbar .nav li.dropdown.active>.dropdown-toggle:hover{color:#fff}.navbar .pull-right .dropdown-menu,.navbar .dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right .dropdown-menu:before,.navbar .dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right .dropdown-menu:after,.navbar .dropdown-menu.pull-right:after{right:13px;left:auto}.breadcrumb{padding:7px 14px;margin:0 0 18px;list-style:none;background-color:#fbfbfb;background-image:-moz-linear-gradient(top,#fff,#f5f5f5);background-image:-ms-linear-gradient(top,#fff,#f5f5f5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#fff,#f5f5f5);background-image:-o-linear-gradient(top,#fff,#f5f5f5);background-image:linear-gradient(top,#fff,#f5f5f5);background-repeat:repeat-x;border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff',endColorstr='#f5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.breadcrumb li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb .divider{padding:0 5px;color:#999}.breadcrumb .active a{color:#333}.pagination{height:36px;margin:18px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination li{display:inline}.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0}.pagination a:hover,.pagination .active a{background-color:#f5f5f5}.pagination .active a{color:#999;cursor:default}.pagination .disabled span,.pagination .disabled a,.pagination .disabled a:hover{color:#999;cursor:default;background-color:transparent}.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pager{margin-bottom:18px;margin-left:0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;content:""}.pager:after{clear:both}.pager li{display:inline}.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager a:hover{text-decoration:none;background-color:#f5f5f5}.pager .next a{float:right}.pager .previous a{float:left}.pager .disabled a,.pager .disabled a:hover{color:#999;cursor:default;background-color:#fff}.modal-open .dropdown-menu{z-index:2050}.modal-open .dropdown.open{*z-index:2050}.modal-open .popover{z-index:2060}.modal-open .tooltip{z-index:2070}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;overflow:auto;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-ms-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:50%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-body{max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.tooltip{position:absolute;z-index:1020;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-2px}.tooltip.right{margin-left:2px}.tooltip.bottom{margin-top:2px}.tooltip.left{margin-left:-2px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top:5px solid #000;border-right:5px solid transparent;border-left:5px solid transparent}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-right:5px solid transparent;border-bottom:5px solid #000;border-left:5px solid transparent}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-right:5px solid #000;border-bottom:5px solid transparent}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px}.popover.top{margin-top:-5px}.popover.right{margin-left:5px}.popover.bottom{margin-top:5px}.popover.left{margin-left:-5px}.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-top:5px solid #000;border-right:5px solid transparent;border-left:5px solid transparent}.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-right:5px solid #000;border-bottom:5px solid transparent}.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-right:5px solid transparent;border-bottom:5px solid #000;border-left:5px solid transparent}.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000}.popover .arrow{position:absolute;width:0;height:0}.popover-inner{width:280px;padding:3px;overflow:hidden;background:#000;background:rgba(0,0,0,0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3)}.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.popover-content{padding:14px;background-color:#fff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:18px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:0 1px 1px rgba(0,0,0,0.075);box-shadow:0 1px 1px rgba(0,0,0,0.075)}a.thumbnail:hover{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px}.label,.badge{font-size:10.998px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{padding:1px 4px 2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding:1px 9px 2px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:18px;margin-bottom:18px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-ms-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(top,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#f5f5f5',endColorstr='#f9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{width:0;height:18px;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(top,#149bdf,#0480be);background-image:-ms-linear-gradient(top,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#149bdf',endColorstr='#0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-ms-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .bar{background-color:#149bdf;background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-ms-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(top,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35',GradientType=0)}.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-ms-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(top,#62c462,#57a957);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#62c462',endColorstr='#57a957',GradientType=0)}.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-ms-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(top,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de',endColorstr='#339bb9',GradientType=0)}.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-ms-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(top,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450',endColorstr='#f89406',GradientType=0)}.progress-warning.progress-striped .bar{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:18px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:18px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel .item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-ms-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel .item>img{display:block;line-height:1}.carousel .active,.carousel .next,.carousel .prev{display:block}.carousel .active{left:0}.carousel .next,.carousel .prev{position:absolute;top:0;width:100%}.carousel .next{left:100%}.carousel .prev{left:-100%}.carousel .next.left,.carousel .prev.right{left:0}.carousel .active.left{left:-100%}.carousel .active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:10px 15px 5px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{color:#fff}.hero-unit{padding:60px;margin-bottom:30px;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit p{font-size:18px;font-weight:200;line-height:27px;color:inherit}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden} + */article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:20px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:1;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1{font-size:36px;line-height:40px}h2{font-size:30px;line-height:40px}h3{font-size:24px;line-height:40px}h4{font-size:18px;line-height:20px}h5{font-size:14px;line-height:20px}h6{font-size:12px;line-height:20px}h1 small{font-size:24px}h2 small{font-size:18px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal dt{float:left;width:120px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:130px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:9px;font-size:14px;line-height:20px;color:#555;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}input,textarea{width:210px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal;cursor:pointer}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #bbb}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:18px;padding-left:18px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"]{float:left}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning .checkbox:focus,.control-group.warning .radio:focus,.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error .checkbox:focus,.control-group.error .radio:focus,.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success .checkbox:focus,.control-group.success .radio:focus,.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;font-size:14px;vertical-align:top;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{margin-left:-1px;vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:160px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:160px}.form-horizontal .help-block{margin-top:10px;margin-bottom:0}.form-horizontal .form-actions{padding-left:160px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child,.table-bordered tfoot:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child,.table-bordered tfoot:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-right-topleft:4px}.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9}.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5}table [class*=span],.row-fluid table [class*=span]{display:table-cell;float:none;margin-left:0}table .span1{float:none;width:44px;margin-left:0}table .span2{float:none;width:124px;margin-left:0}table .span3{float:none;width:204px;margin-left:0}table .span4{float:none;width:284px;margin-left:0}table .span5{float:none;width:364px;margin-left:0}table .span6{float:none;width:444px;margin-left:0}table .span7{float:none;width:524px;margin-left:0}table .span8{float:none;width:604px;margin-left:0}table .span9{float:none;width:684px;margin-left:0}table .span10{float:none;width:764px;margin-left:0}table .span11{float:none;width:844px;margin-left:0}table .span12{float:none;width:924px;margin-left:0}table .span13{float:none;width:1004px;margin-left:0}table .span14{float:none;width:1084px;margin-left:0}table .span15{float:none;width:1164px;margin-left:0}table .span16{float:none;width:1244px;margin-left:0}table .span17{float:none;width:1324px;margin-left:0}table .span18{float:none;width:1404px;margin-left:0}table .span19{float:none;width:1484px;margin-left:0}table .span20{float:none;width:1564px;margin-left:0}table .span21{float:none;width:1644px;margin-left:0}table .span22{float:none;width:1724px;margin-left:0}table .span23{float:none;width:1804px;margin-left:0}table .span24{float:none;width:1884px;margin-left:0}.table tbody tr.success td{background-color:#dff0d8}.table tbody tr.error td{background-color:#f2dede}.table tbody tr.info td{background-color:#d9edf7}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav>.active>a>[class^="icon-"],.nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{color:#fff;text-decoration:none;background-color:#08c;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;background-color:#08c;background-color:#0081c2;background-image:linear-gradient(to bottom,#08c,#0077b3);background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999}.dropdown-menu .disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:"\2191"}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover .dropdown-menu{display:block}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;overflow:visible \9;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 14px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;*line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #bbb;*border:0;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover{color:#333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.btn-large [class^="icon-"]{margin-top:2px}.btn-small{padding:3px 9px;font-size:12px;line-height:18px}.btn-small [class^="icon-"]{margin-top:0}.btn-mini{padding:2px 6px;font-size:11px;line-height:16px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#c5c5c5;border-color:rgba(0,0,0,0.15) rgba(0,0,0,0.15) rgba(0,0,0,0.25)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-image:-moz-linear-gradient(top,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-image:-moz-linear-gradient(top,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-image:-moz-linear-gradient(top,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-group{position:relative;*margin-left:.3em;font-size:0;white-space:nowrap}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1}.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px}.btn-group>.btn-mini{font-size:11px}.btn-group>.btn-small{font-size:12px}.btn-group>.btn-large{font-size:16px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-top:0;border-bottom:5px solid #000}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical .btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible;color:#555}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar .container{width:auto}.nav-collapse.collapse{height:auto}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#555;text-shadow:0 1px 0 #fff}.navbar .brand:hover{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px}.navbar-link{color:#555}.navbar-link:hover{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:6px}.navbar .btn-group .btn{margin:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;width:100%;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner,.navbar-static-top .navbar-inner{border:0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.1),0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.1),0 1px 10px rgba(0,0,0,0.1);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.1),0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:inset 0 1px 0 rgba(0,0,0,0.1),0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 0 rgba(0,0,0,0.1),0 -1px 10px rgba(0,0,0,0.1);box-shadow:inset 0 1px 0 rgba(0,0,0,0.1),0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#555;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse{color:#999}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#fff}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-image:-moz-linear-gradient(top,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb .divider{padding:0 5px;color:#ccc}.breadcrumb .active{color:#999}.pagination{height:40px;margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination li{display:inline}.pagination a,.pagination span{float:left;padding:0 14px;line-height:38px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination a:hover,.pagination .active a,.pagination .active span{background-color:#f5f5f5}.pagination .active a,.pagination .active span{color:#999;cursor:default}.pagination .disabled span,.pagination .disabled a,.pagination .disabled a:hover{color:#999;cursor:default;background-color:transparent}.pagination li:first-child a,.pagination li:first-child span{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.pagination li:last-child a,.pagination li:last-child span{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager a:hover{text-decoration:none;background-color:#f5f5f5}.pager .next a{float:right}.pager .previous a{float:left}.pager .disabled a,.pager .disabled a:hover{color:#999;cursor:default;background-color:#fff}.modal-open .dropdown-menu{z-index:2050}.modal-open .dropdown.open{*z-index:2050}.modal-open .popover{z-index:2060}.modal-open .tooltip{z-index:2080}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;overflow:auto;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:50%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.tooltip{position:absolute;z-index:1030;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px}.tooltip.right{margin-left:3px}.tooltip.bottom{margin-top:3px}.tooltip.left{margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-bottom:10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-right:10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0}.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow:after{z-index:-1;content:""}.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-top-color:#fff;border-width:10px 10px 0}.popover.top .arrow:after{bottom:-1px;left:-11px;border-top-color:rgba(0,0,0,0.25);border-width:11px 11px 0}.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-right-color:#fff;border-width:10px 10px 10px 0}.popover.right .arrow:after{bottom:-11px;left:-1px;border-right-color:rgba(0,0,0,0.25);border-width:11px 11px 11px 0}.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-bottom-color:#fff;border-width:0 10px 10px}.popover.bottom .arrow:after{top:-1px;left:-11px;border-bottom-color:rgba(0,0,0,0.25);border-width:0 11px 11px}.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-left-color:#fff;border-width:10px 0 10px 10px}.popover.left .arrow:after{right:-1px;bottom:-11px;border-left-color:rgba(0,0,0,0.25);border-width:11px 0 11px 11px}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.label,.badge{font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{padding:1px 4px 2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding:1px 9px 2px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel .item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel .item>img{display:block;line-height:1}.carousel .active,.carousel .next,.carousel .prev{display:block}.carousel .active{left:0}.carousel .next,.carousel .prev{position:absolute;top:0;width:100%}.carousel .next{left:100%}.carousel .prev{left:-100%}.carousel .next.left,.carousel .prev.right{left:0}.carousel .active.left{left:-100%}.carousel .active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit p{font-size:18px;font-weight:200;line-height:30px;color:inherit}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} diff --git a/applications/welcome/static/css/bootswatch.css b/applications/welcome/static/css/bootswatch.css index de65e658..650f9b48 100644 --- a/applications/welcome/static/css/bootswatch.css +++ b/applications/welcome/static/css/bootswatch.css @@ -1,9 +1,7 @@ body { - padding-top: 60px; + padding-top: 50px; } -#navbar .auth_navbar, #navbar .auth_navbar a {color:inherit;} - /* bootstrap dropdown */ .dropdown-menu ul { @@ -12,119 +10,206 @@ body { top: 0; visibility: hidden; margin-top: -1px; -} - + } + .dropdown-menu li:hover ul { visibility: visible; + +.nav i { + opacity: 0.7; } -.mastheader h1 { - margin-bottom: 9px; - font-size: 81px; - font-weight: bold; - letter-spacing: -1px; - line-height: 1; +.nav a:hover i { + opacity: 1; } -.mastheader h1 { - font-size: 54px; +.tooltip-inner { + max-width: 500px; } -.mastheader small { - font-size: 20px; - font-weight: 300; +.alert a { + font-weight: bold; + text-decoration: underline; } -.navbar .dropdown-menu ul:before { - border-bottom: 7px solid transparent; - border-left: none; - border-right: 7px solid rgba(0, 0, 0, 0.2); - border-top: 7px solid transparent; - left: -7px; - top: 5px; +.alert p { + margin: 0; } -.navbar .dropdown-menu ul:after { - border-top: 6px solid transparent; - border-left: none; - border-right: 6px solid #fff; - border-bottom: 6px solid transparent; - left: 10px; - top: 6px; - left: -6px; +.hero-unit { + margin-top: 60px; + margin-bottom: 60px; } -.dropdown-menu span{ - display:inline-block; +.hero-unit h1, .hero-unit p { + text-align: center; + margin-bottom: 15px; } -.chevron-right { - border-left: 4px solid #000; - border-right: 4px solid transparent; - border-bottom: 4px solid transparent; - border-top: 4px solid transparent; - content: ""; - display: inline-block; - height: 0; +#social { + margin-top: 45px; +} + +.twitter-follow-button { + width: 150px !important; +} + +.rss-button { + width: 40px; + height: 14px; + font-size: 11px; + line-height: 14px; + font-weight: bold; + margin: 0; + padding: 2px 5px 2px 4px; +} + +.icon-rss { + background: url(../img/rss-icons.png) no-repeat 0 0; + opacity: .65; + width: 16px; +} + +.icon-envelope { + opacity: .65; +} + +.about { + margin-top: 20px; +} + +.about .span4 { + margin-bottom: 20px; +} + +.about h3 { + margin: 0 0 5px 35px; +} + +.about img { + float: left; + margin-top: 5px; opacity: 0.7; - vertical-align: top; - width: 0; - margin-right:-13px; - margin-top: 7px; - float:right; } -.open > .dropdown-menu ul { /* fix menu issue when BS2.0.4 is applied */ - display: block; +#gallery { + margin: 45px 0 30px 0; + padding-right: 20px; + text-align: center; } -.ie-lte7 #navbar .auth_navbar, #navbar .auth_navbar a {color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */} - -#navbar .auth_navbar a:hover {color:white;text-decoration:none;} /* this overwrite bootswatch */ - -body { - height:auto; /*to avoid vertical scroll bar*/ +.thumbnail { + margin-bottom: 20px; + background-color: rgba(0, 0, 0, 0.05); } -h1,h2,h3,h4,h5,h6 {font-family: inherit;} - -li {margin-bottom: 0;} /*bootswatch*/ - -.auth_navbar, .navbar .btn-group { padding:0; } - -[class^="icon-"],[class*=" icon-"]{background-image:url("../images/glyphicons-halflings.png")} /* right folder for bootstrap black images/icons */ -.icon-white{background-image:url("../images/glyphicons-halflings-white.png");} /* right folder for bootstrap white images/icons */ - -@media only screen and (max-width: 979px) { - body { - padding-top: 0px; - } - - .navbar-inner{position:relative;} - #navbar{bottom:-10px;left:4px;} - - div.flash { - right: 5px; - } - - .dropdown-menu ul { - visibility: visible; - } - +.thumbnail img { + width: 100%; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; + border-radius: 7px; } -@media only screen and (max-width: 479px) { - body { - padding-left: 10px; - padding-right: 10px; - } - - .navbar-fixed-top, .navbar-fixed-bottom { - margin-left: -10px; - margin-right: -10px; - } - - input[type="text"], input[type="password"], select { - width: 95%; - } +.thumbnail .label { + vertical-align: top; } + +.thumbnail .btn-toolbar { + text-align: right; +} + +.modal .label { + vertical-align: text-top; +} + +.links { + margin-bottom: 20px; +} + +.links > a { + margin-right: 10px; +} + +/* Landscape phones and down */ +@media (max-width: 480px) { + + .hero-unit { + padding: 40px 20px 10px; + margin: 0 0 20px; + } + + .hero-unit h1 { + font-size: 36px; + } + + .hero-unit p { + font-size: 13px; + line-height: 18px; + } + + #social { + margin-top: 0px; + margin-bottom: 40px; + } + + .about { + margin-top: 0; + } + + .about h3 { + margin-top: 20px; + } + + .about p { + margin-bottom: 0; + } + + .modal { + position: fixed !important; + top: 25% !important; + } +} + +div.one .bsa_it_ad { + padding: 25px 25px 15px 25px; +} + +div.one .bsa_it_p { + display: none; +} + +#bsap_aplink { + float: right; + margin-bottom: 20px; + font-size: 12px; +} + +/* Landscape phone to portrait tablet */ +@media (min-width: 481px) and (max-width: 767px) { + + .hero-unit { + margin-top: 0; + padding-bottom: 60px; + } + + .about { + margin-top: 0; + } +} + +/* Portrait tablet to landscape and desktop */ +@media (min-width: 768px) and (max-width: 980px) { + + .hero-unit { + margin-top: 0; + } + + .thumbnail .btn { + font-size: 11px; + } +} + +/* Large desktop */ +@media (min-width: 1200px) { + +} \ No newline at end of file diff --git a/applications/welcome/views/layout.html b/applications/welcome/views/layout.html index 7d5349e1..9fa54881 100644 --- a/applications/welcome/views/layout.html +++ b/applications/welcome/views/layout.html @@ -160,7 +160,6 @@ if(jQuery(this).find('ul').length) jQuery(this).children('a').contents().before(''); }); - if(jQuery(document).width()>=980) { jQuery('ul.nav li.dropdown').hover(function() { jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(); From d2c94933f57e782a54b5bec5dde113f7602475b3 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 09:53:57 -0500 Subject: [PATCH 27/53] renamed bootswatch*.css as web2py_bootstrap*.css --- VERSION | 2 +- .../static/css/{bootswatch.css => web2py_bootstrap.css} | 0 .../css/{bootswatch_nojs.css => web2py_bootstrap_nojs.css} | 0 applications/welcome/views/layout.html | 6 +++--- 4 files changed, 4 insertions(+), 4 deletions(-) rename applications/welcome/static/css/{bootswatch.css => web2py_bootstrap.css} (100%) rename applications/welcome/static/css/{bootswatch_nojs.css => web2py_bootstrap_nojs.css} (100%) diff --git a/VERSION b/VERSION index f5f172a6..d1747118 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 09:43:38) dev +Version 2.00.0 (2012-08-24 09:53:17) dev diff --git a/applications/welcome/static/css/bootswatch.css b/applications/welcome/static/css/web2py_bootstrap.css similarity index 100% rename from applications/welcome/static/css/bootswatch.css rename to applications/welcome/static/css/web2py_bootstrap.css diff --git a/applications/welcome/static/css/bootswatch_nojs.css b/applications/welcome/static/css/web2py_bootstrap_nojs.css similarity index 100% rename from applications/welcome/static/css/bootswatch_nojs.css rename to applications/welcome/static/css/web2py_bootstrap_nojs.css diff --git a/applications/welcome/views/layout.html b/applications/welcome/views/layout.html index 9fa54881..c072d804 100644 --- a/applications/welcome/views/layout.html +++ b/applications/welcome/views/layout.html @@ -43,11 +43,11 @@ response.files.append(URL('static','css/bootstrap.min.css')) response.files.append(URL('static','css/bootstrap-responsive.min.css')) response.files.append(URL('static','css/web2py.css')) - response.files.append(URL('static','css/bootswatch.css')) + response.files.append(URL('static','css/web2py_bootsrap.css')) }} {{include 'web2py_ajax.html'}} @@ -64,7 +64,7 @@ uncomment to load jquery-ui //--> - + {{block head}}{{end}} From ca17863d7e0f5eb15e636fc7c48f741a1e1ab2d7 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 10:05:07 -0500 Subject: [PATCH 28/53] fixed problem with dal expressions being parenthesized, thanks Daniel --- VERSION | 2 +- gluon/dal.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index d1747118..665274b2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 09:53:17) dev +Version 2.00.0 (2012-08-24 10:04:14) dev diff --git a/gluon/dal.py b/gluon/dal.py index 62d1ca80..d29fa676 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -1317,7 +1317,7 @@ class BaseAdapter(ConnectionPool): tablename,fieldname = item.split('.') new_fields.append(self.db[tablename][fieldname]) else: - new_fields.append(Expression(self.db,item)) + new_fields.append(Expression(self.db,lambda:item)) else: new_fields.append(item) # ## if no fields specified take them all from the requested tables From 0d96a57db7785a0b6829143030950c8359222a90 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 10:14:12 -0500 Subject: [PATCH 29/53] fixed bug in lazy auth, thanks Villas --- VERSION | 2 +- gluon/tools.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 665274b2..ee02a8ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 10:04:14) dev +Version 2.00.0 (2012-08-24 10:13:35) dev diff --git a/gluon/tools.py b/gluon/tools.py index 4752f1c8..56a0c4a1 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1412,7 +1412,8 @@ class Auth(object): settings.table_user_name,[])+signature_list if username or settings.cas_provider: is_unique_username = \ - [IS_MATCH('[\w\.\-]+'), IS_NOT_IN_DB(db, table.username)] + [IS_MATCH('[\w\.\-]+'), + IS_NOT_IN_DB(db,'%s.username' % settings.table_user_name)] if not settings.username_case_sensitive: is_unique_username.insert(1,IS_LOWER()) table = db.define_table( From 61d4a99181ec8512593bcee87d8fe6a22c49afa0 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 11:04:24 -0500 Subject: [PATCH 30/53] fixed typos in recent commit, thanks Angelo and Villas --- VERSION | 2 +- applications/admin/controllers/default.py | 10 +++++----- applications/welcome/views/layout.html | 6 +----- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/VERSION b/VERSION index ee02a8ca..c382678f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 10:13:35) dev +Version 2.00.0 (2012-08-24 11:04:01) dev diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index cec8bef9..f1f4e9db 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -336,7 +336,7 @@ def pack_plugin(): redirect(URL('plugin',args=request.args)) def upgrade_web2py(): - dialog = FORM.confim(T('Upgrade'), + dialog = FORM.confirm(T('Upgrade'), {T('Cancel'):URL('site')}) if dialog.accepted: (success, error) = upgrade(request) @@ -350,7 +350,7 @@ def upgrade_web2py(): def uninstall(): app = get_app() - dialog = FORM.confim(T('Uninstall'), + dialog = FORM.confirm(T('Uninstall'), {T('Cancel'):URL('site')}) if dialog.accepted: @@ -433,7 +433,7 @@ def delete(): if isinstance(sender, list): # ## fix a problem with Vista sender = sender[0] - dialog = FORM.confim(T('Delete'), + dialog = FORM.confirm(T('Delete'), {T('Cancel'):URL(sender, anchor=request.vars.id)}) if dialog.accepted: @@ -1003,7 +1003,7 @@ def delete_plugin(): plugin = request.args(1) plugin_name='plugin_'+plugin - dialog = FORM.confim( + dialog = FORM.confirm( T('Delete'), {T('Cancel'):URL('design', args=app)}) @@ -1652,7 +1652,7 @@ def git_pull(): if not have_git: session.flash = GIT_MISSING redirect(URL('site')) - dialog = FORM.confim(T('Pull'), + dialog = FORM.confirm(T('Pull'), {T('Cancel'):URL('site')}) if dialog.accepted: try: diff --git a/applications/welcome/views/layout.html b/applications/welcome/views/layout.html index c072d804..addb3682 100644 --- a/applications/welcome/views/layout.html +++ b/applications/welcome/views/layout.html @@ -43,12 +43,8 @@ response.files.append(URL('static','css/bootstrap.min.css')) response.files.append(URL('static','css/bootstrap-responsive.min.css')) response.files.append(URL('static','css/web2py.css')) - response.files.append(URL('static','css/web2py_bootsrap.css')) + response.files.append(URL('static','css/web2py_bootstrap.css')) }} - - {{include 'web2py_ajax.html'}} From 5c5cead73c6feccb4c5b8c5521dc209953647307 Mon Sep 17 00:00:00 2001 From: Massimo Di Pierro Date: Fri, 24 Aug 2012 13:45:13 -0500 Subject: [PATCH 31/53] fixed another bug in lazy Auth, thanks Villas --- VERSION | 2 +- gluon/tools.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index c382678f..e0dbb455 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 11:04:01) dev +Version 2.00.0 (2012-08-24 13:44:42) dev diff --git a/gluon/tools.py b/gluon/tools.py index 56a0c4a1..edc1fb6a 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1174,7 +1174,7 @@ class Auth(object): def table_membership(self): return self.db[self.settings.table_membership_name] def table_permission(self): - return self.db[self.settings.table_membership_name] + return self.db[self.settings.table_permission_name] def table_event(self): return self.db[self.settings.table_event_name] def table_cas(self): From 22f47e3618700c765a4764fd0356cdd1906328dc Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 15:34:03 -0500 Subject: [PATCH 32/53] reverted to bootstrap 2.0 because of problems --- VERSION | 2 +- applications/welcome/models/menu.py | 2 +- .../static/css/bootstrap-responsive.min.css | 4 +- .../welcome/static/css/bootstrap.min.css | 4 +- .../welcome/static/css/web2py_bootstrap.css | 271 ++++++------------ 5 files changed, 99 insertions(+), 184 deletions(-) diff --git a/VERSION b/VERSION index e0dbb455..0554668f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 13:44:42) dev +Version 2.00.0 (2012-08-24 15:33:59) dev diff --git a/applications/welcome/models/menu.py b/applications/welcome/models/menu.py index 6b325cdc..784f4a4a 100644 --- a/applications/welcome/models/menu.py +++ b/applications/welcome/models/menu.py @@ -35,7 +35,7 @@ def _(): ctr = request.controller # useful links to internal and external resources response.menu+=[ - ('web2py',False, 'http://web2py.com', [ + (SPAN('web2py',_style='color:yellow'),False, 'http://web2py.com', [ (T('My Sites'),False,URL('admin','default','site')), (T('This App'),False,URL('admin','default','design/%s' % app), [ (T('Controller'),False, diff --git a/applications/welcome/static/css/bootstrap-responsive.min.css b/applications/welcome/static/css/bootstrap-responsive.min.css index ab59da34..1f55036a 100644 --- a/applications/welcome/static/css/bootstrap-responsive.min.css +++ b/applications/welcome/static/css/bootstrap-responsive.min.css @@ -1,9 +1,9 @@ /*! - * Bootstrap Responsive v2.1.0 + * Bootstrap Responsive v2.0.4 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. - */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:auto;margin-left:0}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade.in{top:auto}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#555;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#555;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} + */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}@media(max-width:767px){.visible-phone{display:inherit!important}.hidden-phone{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(min-width:768px) and (max-width:979px){.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:18px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{position:absolute;top:10px;right:10px;left:10px;width:auto;margin:0}.modal.fade.in{top:auto}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:auto;margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.762430939%;*margin-left:2.709239449638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:99.999999993%;*width:99.9468085036383%}.row-fluid .span11{width:91.436464082%;*width:91.38327259263829%}.row-fluid .span10{width:82.87292817100001%;*width:82.8197366816383%}.row-fluid .span9{width:74.30939226%;*width:74.25620077063829%}.row-fluid .span8{width:65.74585634900001%;*width:65.6926648596383%}.row-fluid .span7{width:57.182320438000005%;*width:57.129128948638304%}.row-fluid .span6{width:48.618784527%;*width:48.5655930376383%}.row-fluid .span5{width:40.055248616%;*width:40.0020571266383%}.row-fluid .span4{width:31.491712705%;*width:31.4385212156383%}.row-fluid .span3{width:22.928176794%;*width:22.874985304638297%}.row-fluid .span2{width:14.364640883%;*width:14.311449393638298%}.row-fluid .span1{width:5.801104972%;*width:5.747913482638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:714px}input.span11,textarea.span11,.uneditable-input.span11{width:652px}input.span10,textarea.span10,.uneditable-input.span10{width:590px}input.span9,textarea.span9,.uneditable-input.span9{width:528px}input.span8,textarea.span8,.uneditable-input.span8{width:466px}input.span7,textarea.span7,.uneditable-input.span7{width:404px}input.span6,textarea.span6,.uneditable-input.span6{width:342px}input.span5,textarea.span5,.uneditable-input.span5{width:280px}input.span4,textarea.span4,.uneditable-input.span4{width:218px}input.span3,textarea.span3,.uneditable-input.span3{width:156px}input.span2,textarea.span2,.uneditable-input.span2{width:94px}input.span1,textarea.span1,.uneditable-input.span1{width:32px}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:30px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.564102564%;*margin-left:2.510911074638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145300001%;*width:91.3997999636383%}.row-fluid .span10{width:82.905982906%;*width:82.8527914166383%}.row-fluid .span9{width:74.358974359%;*width:74.30578286963829%}.row-fluid .span8{width:65.81196581200001%;*width:65.7587743226383%}.row-fluid .span7{width:57.264957265%;*width:57.2117657756383%}.row-fluid .span6{width:48.717948718%;*width:48.6647572286383%}.row-fluid .span5{width:40.170940171000005%;*width:40.117748681638304%}.row-fluid .span4{width:31.623931624%;*width:31.5707401346383%}.row-fluid .span3{width:23.076923077%;*width:23.0237315876383%}.row-fluid .span2{width:14.529914530000001%;*width:14.4767230406383%}.row-fluid .span1{width:5.982905983%;*width:5.929714493638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:1160px}input.span11,textarea.span11,.uneditable-input.span11{width:1060px}input.span10,textarea.span10,.uneditable-input.span10{width:960px}input.span9,textarea.span9,.uneditable-input.span9{width:860px}input.span8,textarea.span8,.uneditable-input.span8{width:760px}input.span7,textarea.span7,.uneditable-input.span7{width:660px}input.span6,textarea.span6,.uneditable-input.span6{width:560px}input.span5,textarea.span5,.uneditable-input.span5{width:460px}input.span4,textarea.span4,.uneditable-input.span4{width:360px}input.span3,textarea.span3,.uneditable-input.span3{width:260px}input.span2,textarea.span2,.uneditable-input.span2{width:160px}input.span1,textarea.span1,.uneditable-input.span1{width:60px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:18px}.navbar-fixed-bottom{margin-top:18px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 9px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#999;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#222}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222;border-bottom:1px solid #222;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} diff --git a/applications/welcome/static/css/bootstrap.min.css b/applications/welcome/static/css/bootstrap.min.css index 3119038a..eca5261d 100755 --- a/applications/welcome/static/css/bootstrap.min.css +++ b/applications/welcome/static/css/bootstrap.min.css @@ -1,9 +1,9 @@ /*! - * Bootstrap v2.1.0 + * Bootstrap v2.0.4 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. - */article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:20px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:1;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1{font-size:36px;line-height:40px}h2{font-size:30px;line-height:40px}h3{font-size:24px;line-height:40px}h4{font-size:18px;line-height:20px}h5{font-size:14px;line-height:20px}h6{font-size:12px;line-height:20px}h1 small{font-size:24px}h2 small{font-size:18px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal dt{float:left;width:120px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:130px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:9px;font-size:14px;line-height:20px;color:#555;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}input,textarea{width:210px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal;cursor:pointer}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #bbb}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:18px;padding-left:18px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"]{float:left}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning .checkbox:focus,.control-group.warning .radio:focus,.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error .checkbox:focus,.control-group.error .radio:focus,.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success .checkbox:focus,.control-group.success .radio:focus,.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;font-size:14px;vertical-align:top;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{margin-left:-1px;vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:160px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:160px}.form-horizontal .help-block{margin-top:10px;margin-bottom:0}.form-horizontal .form-actions{padding-left:160px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child,.table-bordered tfoot:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child,.table-bordered tfoot:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-right-topleft:4px}.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9}.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5}table [class*=span],.row-fluid table [class*=span]{display:table-cell;float:none;margin-left:0}table .span1{float:none;width:44px;margin-left:0}table .span2{float:none;width:124px;margin-left:0}table .span3{float:none;width:204px;margin-left:0}table .span4{float:none;width:284px;margin-left:0}table .span5{float:none;width:364px;margin-left:0}table .span6{float:none;width:444px;margin-left:0}table .span7{float:none;width:524px;margin-left:0}table .span8{float:none;width:604px;margin-left:0}table .span9{float:none;width:684px;margin-left:0}table .span10{float:none;width:764px;margin-left:0}table .span11{float:none;width:844px;margin-left:0}table .span12{float:none;width:924px;margin-left:0}table .span13{float:none;width:1004px;margin-left:0}table .span14{float:none;width:1084px;margin-left:0}table .span15{float:none;width:1164px;margin-left:0}table .span16{float:none;width:1244px;margin-left:0}table .span17{float:none;width:1324px;margin-left:0}table .span18{float:none;width:1404px;margin-left:0}table .span19{float:none;width:1484px;margin-left:0}table .span20{float:none;width:1564px;margin-left:0}table .span21{float:none;width:1644px;margin-left:0}table .span22{float:none;width:1724px;margin-left:0}table .span23{float:none;width:1804px;margin-left:0}table .span24{float:none;width:1884px;margin-left:0}.table tbody tr.success td{background-color:#dff0d8}.table tbody tr.error td{background-color:#f2dede}.table tbody tr.info td{background-color:#d9edf7}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav>.active>a>[class^="icon-"],.nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{color:#fff;text-decoration:none;background-color:#08c;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;background-color:#08c;background-color:#0081c2;background-image:linear-gradient(to bottom,#08c,#0077b3);background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999}.dropdown-menu .disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:"\2191"}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover .dropdown-menu{display:block}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;overflow:visible \9;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 14px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;*line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #bbb;*border:0;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover{color:#333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.btn-large [class^="icon-"]{margin-top:2px}.btn-small{padding:3px 9px;font-size:12px;line-height:18px}.btn-small [class^="icon-"]{margin-top:0}.btn-mini{padding:2px 6px;font-size:11px;line-height:16px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#c5c5c5;border-color:rgba(0,0,0,0.15) rgba(0,0,0,0.15) rgba(0,0,0,0.25)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-image:-moz-linear-gradient(top,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-image:-moz-linear-gradient(top,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-image:-moz-linear-gradient(top,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent}.btn-group{position:relative;*margin-left:.3em;font-size:0;white-space:nowrap}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1}.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px}.btn-group>.btn-mini{font-size:11px}.btn-group>.btn-small{font-size:12px}.btn-group>.btn-large{font-size:16px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-top:0;border-bottom:5px solid #000}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical .btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible;color:#555}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar .container{width:auto}.nav-collapse.collapse{height:auto}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#555;text-shadow:0 1px 0 #fff}.navbar .brand:hover{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px}.navbar-link{color:#555}.navbar-link:hover{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:6px}.navbar .btn-group .btn{margin:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;width:100%;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner,.navbar-static-top .navbar-inner{border:0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.1),0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.1),0 1px 10px rgba(0,0,0,0.1);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.1),0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:inset 0 1px 0 rgba(0,0,0,0.1),0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 0 rgba(0,0,0,0.1),0 -1px 10px rgba(0,0,0,0.1);box-shadow:inset 0 1px 0 rgba(0,0,0,0.1),0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#555;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse{color:#999}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#fff}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-image:-moz-linear-gradient(top,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb .divider{padding:0 5px;color:#ccc}.breadcrumb .active{color:#999}.pagination{height:40px;margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination li{display:inline}.pagination a,.pagination span{float:left;padding:0 14px;line-height:38px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination a:hover,.pagination .active a,.pagination .active span{background-color:#f5f5f5}.pagination .active a,.pagination .active span{color:#999;cursor:default}.pagination .disabled span,.pagination .disabled a,.pagination .disabled a:hover{color:#999;cursor:default;background-color:transparent}.pagination li:first-child a,.pagination li:first-child span{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.pagination li:last-child a,.pagination li:last-child span{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager a:hover{text-decoration:none;background-color:#f5f5f5}.pager .next a{float:right}.pager .previous a{float:left}.pager .disabled a,.pager .disabled a:hover{color:#999;cursor:default;background-color:#fff}.modal-open .dropdown-menu{z-index:2050}.modal-open .dropdown.open{*z-index:2050}.modal-open .popover{z-index:2060}.modal-open .tooltip{z-index:2080}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;overflow:auto;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:50%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.tooltip{position:absolute;z-index:1030;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px}.tooltip.right{margin-left:3px}.tooltip.bottom{margin-top:3px}.tooltip.left{margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-bottom:10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-right:10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0}.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow:after{z-index:-1;content:""}.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-top-color:#fff;border-width:10px 10px 0}.popover.top .arrow:after{bottom:-1px;left:-11px;border-top-color:rgba(0,0,0,0.25);border-width:11px 11px 0}.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-right-color:#fff;border-width:10px 10px 10px 0}.popover.right .arrow:after{bottom:-11px;left:-1px;border-right-color:rgba(0,0,0,0.25);border-width:11px 11px 11px 0}.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-bottom-color:#fff;border-width:0 10px 10px}.popover.bottom .arrow:after{top:-1px;left:-11px;border-bottom-color:rgba(0,0,0,0.25);border-width:0 11px 11px}.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-left-color:#fff;border-width:10px 0 10px 10px}.popover.left .arrow:after{right:-1px;bottom:-11px;border-left-color:rgba(0,0,0,0.25);border-width:11px 0 11px 11px}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.label,.badge{font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{padding:1px 4px 2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding:1px 9px 2px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel .item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel .item>img{display:block;line-height:1}.carousel .active,.carousel .next,.carousel .prev{display:block}.carousel .active{left:0}.carousel .next,.carousel .prev{position:absolute;top:0;width:100%}.carousel .next{left:100%}.carousel .prev{left:-100%}.carousel .next.left,.carousel .prev.right{left:0}.carousel .active.left{left:-100%}.carousel .active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit p{font-size:18px;font-weight:200;line-height:30px;color:inherit}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed} + */article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover{color:#005580;text-decoration:underline}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.127659574%;*margin-left:2.0744680846382977%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:99.99999998999999%;*width:99.94680850063828%}.row-fluid .span11{width:91.489361693%;*width:91.4361702036383%}.row-fluid .span10{width:82.97872339599999%;*width:82.92553190663828%}.row-fluid .span9{width:74.468085099%;*width:74.4148936096383%}.row-fluid .span8{width:65.95744680199999%;*width:65.90425531263828%}.row-fluid .span7{width:57.446808505%;*width:57.3936170156383%}.row-fluid .span6{width:48.93617020799999%;*width:48.88297871863829%}.row-fluid .span5{width:40.425531911%;*width:40.3723404216383%}.row-fluid .span4{width:31.914893614%;*width:31.8617021246383%}.row-fluid .span3{width:23.404255317%;*width:23.3510638276383%}.row-fluid .span2{width:14.89361702%;*width:14.8404255306383%}.row-fluid .span1{width:6.382978723%;*width:6.329787233638298%}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:""}.container-fluid:after{clear:both}p{margin:0 0 9px}p small{font-size:11px;color:#999}.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px}h1,h2,h3,h4,h5,h6{margin:0;font-family:inherit;font-weight:bold;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999}h1{font-size:30px;line-height:36px}h1 small{font-size:18px}h2{font-size:24px;line-height:36px}h2 small{font-size:18px}h3{font-size:18px;line-height:27px}h3 small{font-size:14px}h4,h5,h6{line-height:18px}h4{font-size:14px}h4 small{font-size:12px}h5{font-size:12px}h6{font-size:11px;color:#999;text-transform:uppercase}.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eee}.page-header h1{line-height:1}ul,ol{padding:0;margin:0 0 9px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}ul{list-style:disc}ol{list-style:decimal}li{line-height:18px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}dl{margin-bottom:18px}dt,dd{line-height:18px}dt{font-weight:bold;line-height:17px}dd{margin-left:9px}.dl-horizontal dt{float:left;width:120px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:130px}hr{margin:18px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}strong{font-weight:bold}em{font-style:italic}.muted{color:#999}abbr[title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px}blockquote small{display:block;line-height:18px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:18px;font-style:normal;line-height:18px}small{font-size:100%}cite{font-style:normal}code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12.025px;line-height:18px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:18px}pre code{padding:0;color:inherit;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 18px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:13.5px;color:#999}label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:18px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555}input,textarea{width:210px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-ms-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer}input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}.uneditable-textarea{width:auto;height:auto}select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px}select{width:220px;border:1px solid #bbb}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.radio,.checkbox{min-height:18px;padding-left:18px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:930px}input.span11,textarea.span11,.uneditable-input.span11{width:850px}input.span10,textarea.span10,.uneditable-input.span10{width:770px}input.span9,textarea.span9,.uneditable-input.span9{width:690px}input.span8,textarea.span8,.uneditable-input.span8{width:610px}input.span7,textarea.span7,.uneditable-input.span7{width:530px}input.span6,textarea.span6,.uneditable-input.span6{width:450px}input.span5,textarea.span5,.uneditable-input.span5{width:370px}input.span4,textarea.span4,.uneditable-input.span4{width:290px}input.span3,textarea.span3,.uneditable-input.span3{width:210px}input.span2,textarea.span2,.uneditable-input.span2{width:130px}input.span1,textarea.span1,.uneditable-input.span1{width:50px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee;border-color:#ddd}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853}.control-group.warning .checkbox:focus,.control-group.warning .radio:focus,.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48}.control-group.error .checkbox:focus,.control-group.error .radio:focus,.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847}.control-group.success .checkbox:focus,.control-group.success .radio:focus,.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;content:""}.form-actions:after{clear:both}.uneditable-input{overflow:hidden;white-space:nowrap;cursor:not-allowed;background-color:#fff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}:-moz-placeholder{color:#999}:-ms-input-placeholder{color:#999}::-webkit-input-placeholder{color:#999}.help-block,.help-inline{color:#555}.help-block{display:block;margin-bottom:9px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-prepend,.input-append{margin-bottom:5px}.input-prepend input,.input-append input,.input-prepend select,.input-append select,.input-prepend .uneditable-input,.input-append .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:middle;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-prepend input:focus,.input-append input:focus,.input-prepend select:focus,.input-append select:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{z-index:2}.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc}.input-prepend .add-on,.input-append .add-on{display:inline-block;width:auto;height:18px;min-width:16px;padding:4px 5px;font-weight:normal;line-height:18px;text-align:center;text-shadow:0 1px 0 #fff;vertical-align:middle;background-color:#eee;border:1px solid #ccc}.input-prepend .add-on,.input-append .add-on,.input-prepend .btn,.input-append .btn{margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-append .uneditable-input{border-right-color:#ccc;border-left-color:#eee}.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:9px}legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:18px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:160px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:160px}.form-horizontal .help-block{margin-top:9px;margin-bottom:0}.form-horizontal .form-actions{padding-left:160px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:18px}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapsed;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9}.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5}table .span1{float:none;width:44px;margin-left:0}table .span2{float:none;width:124px;margin-left:0}table .span3{float:none;width:204px;margin-left:0}table .span4{float:none;width:284px;margin-left:0}table .span5{float:none;width:364px;margin-left:0}table .span6{float:none;width:444px;margin-left:0}table .span7{float:none;width:524px;margin-left:0}table .span8{float:none;width:604px;margin-left:0}table .span9{float:none;width:684px;margin-left:0}table .span10{float:none;width:764px;margin-left:0}table .span11{float:none;width:844px;margin-left:0}table .span12{float:none;width:924px;margin-left:0}table .span13{float:none;width:1004px;margin-left:0}table .span14{float:none;width:1084px;margin-left:0}table .span15{float:none;width:1164px;margin-left:0}table .span16{float:none;width:1244px;margin-left:0}table .span17{float:none;width:1324px;margin-left:0}table .span18{float:none;width:1404px;margin-left:0}table .span19{float:none;width:1484px;margin-left:0}table .span20{float:none;width:1564px;margin-left:0}table .span21{float:none;width:1644px;margin-left:0}table .span22{float:none;width:1724px;margin-left:0}table .span23{float:none;width:1804px;margin-left:0}table .span24{float:none;width:1884px;margin-left:0}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../images/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0}.icon-white{background-image:url("../images/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";opacity:.3;filter:alpha(opacity=30)}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown:hover .caret,.open .caret{opacity:1;filter:alpha(opacity=100)}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:4px 0;margin:1px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#333;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;background-color:#08c}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:"\2191"}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0,0,0,0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-ms-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-ms-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 10px 4px;margin-bottom:0;*margin-left:.3em;font-size:13px;line-height:18px;*line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-ms-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(top,#fff,#e6e6e6);background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff',endColorstr='#e6e6e6',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover{color:#333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-ms-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.btn-large [class^="icon-"]{margin-top:1px}.btn-small{padding:5px 9px;font-size:11px;line-height:16px}.btn-small [class^="icon-"]{margin-top:-1px}.btn-mini{padding:2px 6px;font-size:11px;line-height:14px}.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#ccc;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.btn-primary{background-color:#0074cc;*background-color:#05c;background-image:-ms-linear-gradient(top,#08c,#05c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#05c));background-image:-webkit-linear-gradient(top,#08c,#05c);background-image:-o-linear-gradient(top,#08c,#05c);background-image:-moz-linear-gradient(top,#08c,#05c);background-image:linear-gradient(top,#08c,#05c);background-repeat:repeat-x;border-color:#05c #05c #003580;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#0088cc',endColorstr='#0055cc',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#05c;*background-color:#004ab3}.btn-primary:active,.btn-primary.active{background-color:#004099 \9}.btn-warning{background-color:#faa732;*background-color:#f89406;background-image:-ms-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(top,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450',endColorstr='#f89406',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{background-color:#da4f49;*background-color:#bd362f;background-image:-ms-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(top,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#bd362f',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{background-color:#5bb75b;*background-color:#51a351;background-image:-ms-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(top,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#62c462',endColorstr='#51a351',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{background-color:#49afcd;*background-color:#2f96b4;background-image:-ms-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(top,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de',endColorstr='#2f96b4',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{background-color:#414141;*background-color:#222;background-image:-ms-linear-gradient(top,#555,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#555),to(#222));background-image:-webkit-linear-gradient(top,#555,#222);background-image:-o-linear-gradient(top,#555,#222);background-image:-moz-linear-gradient(top,#555,#222);background-image:linear-gradient(top,#555,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#555555',endColorstr='#222222',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-group{position:relative;*margin-left:.3em;*zoom:1}.btn-group:before,.btn-group:after{display:table;content:""}.btn-group:after{clear:both}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:9px;margin-bottom:9px}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1}.btn-group>.btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.dropdown-toggle{*padding-top:4px;padding-right:8px;*padding-bottom:4px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini.dropdown-toggle{padding-right:5px;padding-left:5px}.btn-group>.btn-small.dropdown-toggle{*padding-top:4px;*padding-bottom:4px}.btn-group>.btn-large.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#05c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:7px;margin-left:0}.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100)}.btn-mini .caret{margin-top:5px}.btn-small .caret{margin-top:6px}.btn-large .caret{margin-top:6px;border-top-width:5px;border-right-width:5px;border-left-width:5px}.dropup .btn-large .caret{border-top:0;border-bottom:5px solid #000}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:.75;filter:alpha(opacity=75)}.alert{padding:8px 35px 8px 14px;margin-bottom:18px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert-heading{color:inherit}.alert .close{position:relative;top:-2px;right:-21px;line-height:18px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:18px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>.pull-right{float:right}.nav .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:18px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.nav-tabs.nav-stacked>li>a:hover{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px}.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333;border-bottom-color:#333}.nav>.dropdown.active>a:hover{color:#000;cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.navbar{*position:relative;*z-index:2;margin-bottom:18px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top,#333,#222);background-image:-ms-linear-gradient(top,#333,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#333),to(#222));background-image:-webkit-linear-gradient(top,#333,#222);background-image:-o-linear-gradient(top,#333,#222);background-image:linear-gradient(top,#333,#222);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.25),inset 0 -1px 0 rgba(0,0,0,0.1)}.navbar .container{width:auto}.nav-collapse.collapse{height:auto}.navbar{color:#999}.navbar .brand:hover{text-decoration:none}.navbar .brand{display:block;float:left;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#999}.navbar .navbar-text{margin-bottom:0;line-height:40px}.navbar .navbar-link{color:#999}.navbar .navbar-link:hover{color:#fff}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn{margin:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#fff;background-color:#626262;border:1px solid #151515;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}.navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-bottom{bottom:0}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right}.navbar .nav>li{display:block;float:left}.navbar .nav>li>a{float:none;padding:9px 10px 11px;line-height:19px;color:#999;text-decoration:none;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar .btn{display:inline-block;padding:4px 10px 4px;margin:5px 5px 6px;line-height:18px}.navbar .btn-group{padding:5px 5px 6px;margin:0}.navbar .nav>li>a:hover{color:#fff;text-decoration:none;background-color:transparent}.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#fff;text-decoration:none;background-color:#222}.navbar .divider-vertical{width:1px;height:40px;margin:0 9px;overflow:hidden;background-color:#222;border-right:1px solid #333}.navbar .nav.pull-right{margin-right:0;margin-left:10px}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;background-color:#2c2c2c;*background-color:#222;background-image:-ms-linear-gradient(top,#333,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#333),to(#222));background-image:-webkit-linear-gradient(top,#333,#222);background-image:-o-linear-gradient(top,#333,#222);background-image:linear-gradient(top,#333,#222);background-image:-moz-linear-gradient(top,#333,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:dximagetransform.microsoft.gradient(startColorstr='#333333',endColorstr='#222222',GradientType=0);filter:progid:dximagetransform.microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{background-color:#222;*background-color:#151515}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#080808 \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown .dropdown-toggle .caret,.navbar .nav li.dropdown.open .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .nav li.dropdown.active .caret{opacity:1;filter:alpha(opacity=100)}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:transparent}.navbar .nav li.dropdown.active>.dropdown-toggle:hover{color:#fff}.navbar .pull-right .dropdown-menu,.navbar .dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right .dropdown-menu:before,.navbar .dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right .dropdown-menu:after,.navbar .dropdown-menu.pull-right:after{right:13px;left:auto}.breadcrumb{padding:7px 14px;margin:0 0 18px;list-style:none;background-color:#fbfbfb;background-image:-moz-linear-gradient(top,#fff,#f5f5f5);background-image:-ms-linear-gradient(top,#fff,#f5f5f5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f5f5f5));background-image:-webkit-linear-gradient(top,#fff,#f5f5f5);background-image:-o-linear-gradient(top,#fff,#f5f5f5);background-image:linear-gradient(top,#fff,#f5f5f5);background-repeat:repeat-x;border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff',endColorstr='#f5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.breadcrumb li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb .divider{padding:0 5px;color:#999}.breadcrumb .active a{color:#333}.pagination{height:36px;margin:18px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination li{display:inline}.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0}.pagination a:hover,.pagination .active a{background-color:#f5f5f5}.pagination .active a{color:#999;cursor:default}.pagination .disabled span,.pagination .disabled a,.pagination .disabled a:hover{color:#999;cursor:default;background-color:transparent}.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pager{margin-bottom:18px;margin-left:0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;content:""}.pager:after{clear:both}.pager li{display:inline}.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager a:hover{text-decoration:none;background-color:#f5f5f5}.pager .next a{float:right}.pager .previous a{float:left}.pager .disabled a,.pager .disabled a:hover{color:#999;cursor:default;background-color:#fff}.modal-open .dropdown-menu{z-index:2050}.modal-open .dropdown.open{*z-index:2050}.modal-open .popover{z-index:2060}.modal-open .tooltip{z-index:2070}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;overflow:auto;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-ms-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:50%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-body{max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.tooltip{position:absolute;z-index:1020;display:block;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-2px}.tooltip.right{margin-left:2px}.tooltip.bottom{margin-top:2px}.tooltip.left{margin-left:-2px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top:5px solid #000;border-right:5px solid transparent;border-left:5px solid transparent}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-right:5px solid transparent;border-bottom:5px solid #000;border-left:5px solid transparent}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-right:5px solid #000;border-bottom:5px solid transparent}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px}.popover.top{margin-top:-5px}.popover.right{margin-left:5px}.popover.bottom{margin-top:5px}.popover.left{margin-left:-5px}.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-top:5px solid #000;border-right:5px solid transparent;border-left:5px solid transparent}.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-right:5px solid #000;border-bottom:5px solid transparent}.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-right:5px solid transparent;border-bottom:5px solid #000;border-left:5px solid transparent}.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000}.popover .arrow{position:absolute;width:0;height:0}.popover-inner{width:280px;padding:3px;overflow:hidden;background:#000;background:rgba(0,0,0,0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3)}.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.popover-content{padding:14px;background-color:#fff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:18px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:0 1px 1px rgba(0,0,0,0.075);box-shadow:0 1px 1px rgba(0,0,0,0.075)}a.thumbnail:hover{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px}.label,.badge{font-size:10.998px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{padding:1px 4px 2px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding:1px 9px 2px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:18px;margin-bottom:18px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-ms-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(top,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#f5f5f5',endColorstr='#f9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{width:0;height:18px;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(top,#149bdf,#0480be);background-image:-ms-linear-gradient(top,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#149bdf',endColorstr='#0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-ms-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .bar{background-color:#149bdf;background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-ms-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(top,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b',endColorstr='#c43c35',GradientType=0)}.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-ms-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(top,#62c462,#57a957);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#62c462',endColorstr='#57a957',GradientType=0)}.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-ms-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(top,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de',endColorstr='#339bb9',GradientType=0)}.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-ms-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(top,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450',endColorstr='#f89406',GradientType=0)}.progress-warning.progress-striped .bar{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-ms-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(-45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:18px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:18px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel .item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-ms-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel .item>img{display:block;line-height:1}.carousel .active,.carousel .next,.carousel .prev{display:block}.carousel .active{left:0}.carousel .next,.carousel .prev{position:absolute;top:0;width:100%}.carousel .next{left:100%}.carousel .prev{left:-100%}.carousel .next.left,.carousel .prev.right{left:0}.carousel .active.left{left:-100%}.carousel .active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:10px 15px 5px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{color:#fff}.hero-unit{padding:60px;margin-bottom:30px;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit p{font-size:18px;font-weight:200;line-height:27px;color:inherit}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden} diff --git a/applications/welcome/static/css/web2py_bootstrap.css b/applications/welcome/static/css/web2py_bootstrap.css index 650f9b48..de65e658 100644 --- a/applications/welcome/static/css/web2py_bootstrap.css +++ b/applications/welcome/static/css/web2py_bootstrap.css @@ -1,7 +1,9 @@ body { - padding-top: 50px; + padding-top: 60px; } +#navbar .auth_navbar, #navbar .auth_navbar a {color:inherit;} + /* bootstrap dropdown */ .dropdown-menu ul { @@ -10,206 +12,119 @@ body { top: 0; visibility: hidden; margin-top: -1px; - } - +} + .dropdown-menu li:hover ul { visibility: visible; - -.nav i { - opacity: 0.7; } -.nav a:hover i { - opacity: 1; +.mastheader h1 { + margin-bottom: 9px; + font-size: 81px; + font-weight: bold; + letter-spacing: -1px; + line-height: 1; } -.tooltip-inner { - max-width: 500px; +.mastheader h1 { + font-size: 54px; } -.alert a { - font-weight: bold; - text-decoration: underline; +.mastheader small { + font-size: 20px; + font-weight: 300; } -.alert p { - margin: 0; +.navbar .dropdown-menu ul:before { + border-bottom: 7px solid transparent; + border-left: none; + border-right: 7px solid rgba(0, 0, 0, 0.2); + border-top: 7px solid transparent; + left: -7px; + top: 5px; } -.hero-unit { - margin-top: 60px; - margin-bottom: 60px; +.navbar .dropdown-menu ul:after { + border-top: 6px solid transparent; + border-left: none; + border-right: 6px solid #fff; + border-bottom: 6px solid transparent; + left: 10px; + top: 6px; + left: -6px; } -.hero-unit h1, .hero-unit p { - text-align: center; - margin-bottom: 15px; +.dropdown-menu span{ + display:inline-block; } -#social { - margin-top: 45px; -} - -.twitter-follow-button { - width: 150px !important; -} - -.rss-button { - width: 40px; - height: 14px; - font-size: 11px; - line-height: 14px; - font-weight: bold; - margin: 0; - padding: 2px 5px 2px 4px; -} - -.icon-rss { - background: url(../img/rss-icons.png) no-repeat 0 0; - opacity: .65; - width: 16px; -} - -.icon-envelope { - opacity: .65; -} - -.about { - margin-top: 20px; -} - -.about .span4 { - margin-bottom: 20px; -} - -.about h3 { - margin: 0 0 5px 35px; -} - -.about img { - float: left; - margin-top: 5px; +.chevron-right { + border-left: 4px solid #000; + border-right: 4px solid transparent; + border-bottom: 4px solid transparent; + border-top: 4px solid transparent; + content: ""; + display: inline-block; + height: 0; opacity: 0.7; + vertical-align: top; + width: 0; + margin-right:-13px; + margin-top: 7px; + float:right; } -#gallery { - margin: 45px 0 30px 0; - padding-right: 20px; - text-align: center; +.open > .dropdown-menu ul { /* fix menu issue when BS2.0.4 is applied */ + display: block; } -.thumbnail { - margin-bottom: 20px; - background-color: rgba(0, 0, 0, 0.05); +.ie-lte7 #navbar .auth_navbar, #navbar .auth_navbar a {color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */} + +#navbar .auth_navbar a:hover {color:white;text-decoration:none;} /* this overwrite bootswatch */ + +body { + height:auto; /*to avoid vertical scroll bar*/ } -.thumbnail img { - width: 100%; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - border-radius: 7px; +h1,h2,h3,h4,h5,h6 {font-family: inherit;} + +li {margin-bottom: 0;} /*bootswatch*/ + +.auth_navbar, .navbar .btn-group { padding:0; } + +[class^="icon-"],[class*=" icon-"]{background-image:url("../images/glyphicons-halflings.png")} /* right folder for bootstrap black images/icons */ +.icon-white{background-image:url("../images/glyphicons-halflings-white.png");} /* right folder for bootstrap white images/icons */ + +@media only screen and (max-width: 979px) { + body { + padding-top: 0px; + } + + .navbar-inner{position:relative;} + #navbar{bottom:-10px;left:4px;} + + div.flash { + right: 5px; + } + + .dropdown-menu ul { + visibility: visible; + } + } -.thumbnail .label { - vertical-align: top; +@media only screen and (max-width: 479px) { + body { + padding-left: 10px; + padding-right: 10px; + } + + .navbar-fixed-top, .navbar-fixed-bottom { + margin-left: -10px; + margin-right: -10px; + } + + input[type="text"], input[type="password"], select { + width: 95%; + } } - -.thumbnail .btn-toolbar { - text-align: right; -} - -.modal .label { - vertical-align: text-top; -} - -.links { - margin-bottom: 20px; -} - -.links > a { - margin-right: 10px; -} - -/* Landscape phones and down */ -@media (max-width: 480px) { - - .hero-unit { - padding: 40px 20px 10px; - margin: 0 0 20px; - } - - .hero-unit h1 { - font-size: 36px; - } - - .hero-unit p { - font-size: 13px; - line-height: 18px; - } - - #social { - margin-top: 0px; - margin-bottom: 40px; - } - - .about { - margin-top: 0; - } - - .about h3 { - margin-top: 20px; - } - - .about p { - margin-bottom: 0; - } - - .modal { - position: fixed !important; - top: 25% !important; - } -} - -div.one .bsa_it_ad { - padding: 25px 25px 15px 25px; -} - -div.one .bsa_it_p { - display: none; -} - -#bsap_aplink { - float: right; - margin-bottom: 20px; - font-size: 12px; -} - -/* Landscape phone to portrait tablet */ -@media (min-width: 481px) and (max-width: 767px) { - - .hero-unit { - margin-top: 0; - padding-bottom: 60px; - } - - .about { - margin-top: 0; - } -} - -/* Portrait tablet to landscape and desktop */ -@media (min-width: 768px) and (max-width: 980px) { - - .hero-unit { - margin-top: 0; - } - - .thumbnail .btn { - font-size: 11px; - } -} - -/* Large desktop */ -@media (min-width: 1200px) { - -} \ No newline at end of file From 38fb587db07bb411faafaf4aab237eab902f833f Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 15:53:10 -0500 Subject: [PATCH 33/53] fixed scripts/setup-web2py-nginx-uwsgi-ubuntu.sh \r --- VERSION | 2 +- scripts/setup-web2py-nginx-uwsgi-on-centos.sh | 1 + scripts/setup-web2py-nginx-uwsgi-ubuntu.sh | 157 +++++++++--------- 3 files changed, 80 insertions(+), 80 deletions(-) diff --git a/VERSION b/VERSION index 0554668f..64de51cc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 15:33:59) dev +Version 2.00.0 (2012-08-24 15:53:07) dev diff --git a/scripts/setup-web2py-nginx-uwsgi-on-centos.sh b/scripts/setup-web2py-nginx-uwsgi-on-centos.sh index d6d613c1..0892026d 100644 --- a/scripts/setup-web2py-nginx-uwsgi-on-centos.sh +++ b/scripts/setup-web2py-nginx-uwsgi-on-centos.sh @@ -315,3 +315,4 @@ reboot as superuser " + diff --git a/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh b/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh index 1d50f6ad..f62a529b 100644 --- a/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh +++ b/scripts/setup-web2py-nginx-uwsgi-ubuntu.sh @@ -1,79 +1,78 @@ -#!/bin/bash - -echo 'setup-web2py-nginx-uwsgi-ubuntu-precise.sh' -echo 'Requires Ubuntu 12.04 and installs Nginx + uWSGI + Web2py' - -# Get Web2py Admin Password -echo -e "Web2py Admin Password: \c " -read PW - -# Upgrade and install needed software -apt-get update -apt-get -y upgrade -apt-get -y dist-upgrade -apt-get autoremove -apt-get autoclean -apt-get -y install nginx-full -apt-get -y install uwsgi uwsgi-plugin-python - -# Create configuration file /etc/nginx/sites-available/web2py -echo 'server { - listen 80; - server_name $hostname; - location ~* /(\w+)/static/ { - root /home/www-data/web2py/applications/; - } - location / { - uwsgi_pass 127.0.0.1:9001; - include uwsgi_params; - uwsgi_param UWSGI_SCHEME $scheme; - uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; - } -} - -server { - listen 443; - server_name $hostname; - ssl on; - ssl_certificate /etc/nginx/ssl/web2py.crt; - ssl_certificate_key /etc/nginx/ssl/web2py.key; - location / { - uwsgi_pass 127.0.0.1:9001; - include uwsgi_params; - uwsgi_param UWSGI_SCHEME $scheme; - uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; - } - -}' >/etc/nginx/sites-available/web2py - -ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enabled/web2py -rm /etc/nginx/sites-enabled/default -mkdir /etc/nginx/ssl -cd /etc/nginx/ssl -openssl genrsa -out web2py.key 1024 -openssl req -batch -new -key web2py.key -out web2py.csr -openssl x509 -req -days 1780 -in web2py.csr -signkey web2py.key -out web2py.crt - -# Create configuration file /etc/uwsgi/apps-available/web2py.xml -echo ' - python - 127.0.0.1:9001 - /home/www-data/web2py/ - - - -' >/etc/uwsgi/apps-available/web2py.xml -ln -s /etc/uwsgi/apps-available/web2py.xml /etc/uwsgi/apps-enabled/web2py.xml - -# Install Web2py -apt-get -y install unzip -mkdir /home/www-data -cd /home/www-data -wget http://web2py.com/examples/static/web2py_src.zip -unzip web2py_src.zip -rm web2py_src.zip -chown -R www-data:www-data web2py -cd /home/www-data/web2py -sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)" -/etc/init.d/uwsgi restart -/etc/init.d/nginx restart +echo 'setup-web2py-nginx-uwsgi-ubuntu-precise.sh' +echo 'Requires Ubuntu 12.04 and installs Nginx + uWSGI + Web2py' + +# Get Web2py Admin Password +echo -e "Web2py Admin Password: \c " +read PW + +# Upgrade and install needed software +apt-get update +apt-get -y upgrade +apt-get -y dist-upgrade +apt-get autoremove +apt-get autoclean +apt-get -y install nginx-full +apt-get -y install uwsgi uwsgi-plugin-python + +# Create configuration file /etc/nginx/sites-available/web2py +echo 'server { + listen 80; + server_name $hostname; + location ~* /(\w+)/static/ { + root /home/www-data/web2py/applications/; + } + location / { + uwsgi_pass 127.0.0.1:9001; + include uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + } +} + +server { + listen 443; + server_name $hostname; + ssl on; + ssl_certificate /etc/nginx/ssl/web2py.crt; + ssl_certificate_key /etc/nginx/ssl/web2py.key; + location / { + uwsgi_pass 127.0.0.1:9001; + include uwsgi_params; + uwsgi_param UWSGI_SCHEME $scheme; + uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; + } + +}' >/etc/nginx/sites-available/web2py + +ln -s /etc/nginx/sites-available/web2py /etc/nginx/sites-enabled/web2py +rm /etc/nginx/sites-enabled/default +mkdir /etc/nginx/ssl +cd /etc/nginx/ssl +openssl genrsa -out web2py.key 1024 +openssl req -batch -new -key web2py.key -out web2py.csr +openssl x509 -req -days 1780 -in web2py.csr -signkey web2py.key -out web2py.crt + +# Create configuration file /etc/uwsgi/apps-available/web2py.xml +echo ' + python + 127.0.0.1:9001 + /home/www-data/web2py/ + + + +' >/etc/uwsgi/apps-available/web2py.xml +ln -s /etc/uwsgi/apps-available/web2py.xml /etc/uwsgi/apps-enabled/web2py.xml + +# Install Web2py +apt-get -y install unzip +mkdir /home/www-data +cd /home/www-data +wget http://web2py.com/examples/static/web2py_src.zip +unzip web2py_src.zip +rm web2py_src.zip +chown -R www-data:www-data web2py +cd /home/www-data/web2py +sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)" +/etc/init.d/uwsgi restart +/etc/init.d/nginx restart + From 636f6e6434c490fd55cb453468d0468d0c6cddf1 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 16:17:32 -0500 Subject: [PATCH 34/53] added links to multi_user_mode management --- VERSION | 2 +- applications/admin/views/default/site.html | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 64de51cc..d91343d1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 15:53:07) dev +Version 2.00.0 (2012-08-24 16:17:29) dev diff --git a/applications/admin/views/default/site.html b/applications/admin/views/default/site.html index 879dccc2..160277d5 100644 --- a/applications/admin/views/default/site.html +++ b/applications/admin/views/default/site.html @@ -78,6 +78,16 @@

    {{pass}} + + {{if MULTI_USER_MODE and is_manager():}} +
    +

    {{=T("Multi User Mode")}}

    +

    + {{=button(URL('bulk_register'),T('Bulk Register'))}} + {{=button(URL('manage_students'),T('Manage Students'))}} +

    +
    + {{pass}}

    {{=T("New application wizard")}}

    From ca6a03dac38abd4d4c59d98343663a9f519c85c7 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 16:24:43 -0500 Subject: [PATCH 35/53] another multi_user_mode fix --- VERSION | 2 +- applications/admin/views/default/site.html | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index d91343d1..91d4bc4f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 16:17:29) dev +Version 2.00.0 (2012-08-24 16:24:40) dev diff --git a/applications/admin/views/default/site.html b/applications/admin/views/default/site.html index 160277d5..a9e7719d 100644 --- a/applications/admin/views/default/site.html +++ b/applications/admin/views/default/site.html @@ -135,13 +135,15 @@ {{=form_update.custom.end}}
    + {{if not MULTI_USER_MODE or is_manager():}}

    {{=T("Deploy")}}

    {{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}} {{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}

    -

    + + {{pass}} {{if TWITTER_HASH:}}

    {{=T("%s Recent Tweets"%TWITTER_HASH)}}

    From 78e18153953abff83a2dbd1efe7568f1eb1a6419 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 16:36:14 -0500 Subject: [PATCH 36/53] auth links should have same scheme as app --- VERSION | 2 +- gluon/tools.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 91d4bc4f..94a0778c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 16:24:40) dev +Version 2.00.0 (2012-08-24 16:36:11) dev diff --git a/gluon/tools.py b/gluon/tools.py index edc1fb6a..a983869b 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1084,8 +1084,8 @@ class Auth(object): messages.is_empty = "Cannot be empty" messages.mismatched_password = "Password fields don't match" messages.verify_email = \ - 'Click on the link http://' + current.request.env.http_host + \ - URL('default','user',args=['verify_email']) + \ + 'Click on the link ' + \ + URL('default','user',args='verify_email',scheme=True) + \ '/%(key)s to verify your email' messages.verify_email_subject = 'Email verification' messages.username_sent = 'Your username was emailed to you' @@ -1096,8 +1096,8 @@ class Auth(object): messages.retrieve_password = 'Your password is: %(password)s' messages.retrieve_password_subject = 'Password retrieve' messages.reset_password = \ - 'Click on the link http://' + current.request.env.http_host + \ - URL('default','user',args=['reset_password']) + \ + 'Click on the link ' + \ + URL('default','user',args='reset_password',scheme=True) + \ '/%(key)s to reset your password' messages.reset_password_subject = 'Password reset' messages.invalid_reset_password = 'Invalid reset password' From c5be7cb2f7b6c13ea3e0527391e7e6ad128c601c Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 17:05:18 -0500 Subject: [PATCH 37/53] better error reporing on app_create failures --- VERSION | 2 +- applications/admin/controllers/default.py | 7 ++--- applications/admin/views/default/site.html | 8 +++--- gluon/admin.py | 31 ++++++++++++++++------ 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/VERSION b/VERSION index 94a0778c..9ff7d60c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 16:36:11) dev +Version 2.00.0 (2012-08-24 17:05:15) dev diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index f1f4e9db..d4ece9ce 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -206,7 +206,8 @@ def site(): elif form_create.accepted: # create a new application appname = cleanpath(form_create.vars.name) - if app_create(appname, request): + created, error = app_create(appname, request,info=True) + if created: if MULTI_USER_MODE: db.app.insert(name=appname,owner=auth.user.id) log_progress(appname) @@ -214,8 +215,8 @@ def site(): redirect(URL('design',args=appname)) else: session.flash = \ - T('unable to create application "%s" (it may exist already)', - form_create.vars.name) + DIV(T('unable to create application "%s"' % appname), + PRE(error)) redirect(URL(r=request)) elif form_update.accepted: diff --git a/applications/admin/views/default/site.html b/applications/admin/views/default/site.html index a9e7719d..e983d00c 100644 --- a/applications/admin/views/default/site.html +++ b/applications/admin/views/default/site.html @@ -83,8 +83,8 @@

    {{=T("Multi User Mode")}}

    - {{=button(URL('bulk_register'),T('Bulk Register'))}} - {{=button(URL('manage_students'),T('Manage Students'))}} + {{=button(URL('bulk_register'),T('Bulk Register'))}} + {{=button(URL('manage_students'),T('Manage Students'))}}

    {{pass}} @@ -135,15 +135,13 @@ {{=form_update.custom.end}}
    - {{if not MULTI_USER_MODE or is_manager():}}

    {{=T("Deploy")}}

    {{=button(URL('gae','deploy'), T('Deploy on Google App Engine'))}} {{=button(URL('openshift','deploy'),T('Deploy to OpenShift'))}}

    -
    - {{pass}} +
    {{if TWITTER_HASH:}}

    {{=T("%s Recent Tweets"%TWITTER_HASH)}}

    diff --git a/gluon/admin.py b/gluon/admin.py index b5037bd8..d84ece9e 100644 --- a/gluon/admin.py +++ b/gluon/admin.py @@ -18,6 +18,7 @@ from fileutils import up, fix_newlines, abspath, recursive_unlink from fileutils import read_file, write_file, parse_version from restricted import RestrictedError from settings import global_settings +from http import HTTP if not global_settings.web2py_runtime_gae: import site @@ -157,7 +158,7 @@ def app_compile(app, request): remove_compiled_application(folder) return tb -def app_create(app, request,force=False,key=None): +def app_create(app, request,force=False,key=None,info=False): """ Create a copy of welcome.w2p (scaffolding) app @@ -169,11 +170,19 @@ def app_create(app, request,force=False,key=None): the global request object """ - try: - path = apath(app, request) - os.mkdir(path) - except: - if not force: + path = apath(app, request) + if not os.path.exists(path): + try: + os.mkdir(path) + except: + if info: + return False, traceback.format_exc(sys.exc_info) + else: + return False + elif not force: + if info: + return False, "Application exists" + else: return False try: w2p_unpack('welcome.w2p', path) @@ -189,10 +198,16 @@ def app_create(app, request,force=False,key=None): data = data.replace('', 'sha512:'+(key or web2py_uuid())) write_file(db, data) - return True + if info: + return True, None + else: + return True except: rmtree(path) - return False + if info: + return False, traceback.format_exc(sys.exc_info) + else: + return False def app_install(app, fobj, request, filename, overwrite=None): From 0beafb39f94805287a1889c310d99d05daa1b381 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 17:32:26 -0500 Subject: [PATCH 38/53] new widget.py thanks Niphlod --- VERSION | 2 +- gluon/widget.py | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/VERSION b/VERSION index 9ff7d60c..37e812f6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 17:05:15) dev +Version 2.00.0 (2012-08-24 17:32:21) dev diff --git a/gluon/widget.py b/gluon/widget.py index a0bb9dfd..a2b84ac2 100644 --- a/gluon/widget.py +++ b/gluon/widget.py @@ -754,9 +754,11 @@ def console(): default='', help=msg) - msg = 'run scheduled tasks for the specified apps' - msg += '-K app1,app2,app3' - msg += 'requires a scheduler defined in the models' + msg = 'run scheduled tasks for the specified apps: expects a list of ' + msg += 'app names as -K app1,app2,app3 ' + msg += 'or a list of app:groups as -K app1:group1:group2,app2:group1 ' + msg += 'to override specific group_names. (only strings, no spaces ' + msg += 'allowed. Requires a scheduler defined in the models' parser.add_option('-K', '--scheduler', dest='scheduler', @@ -917,9 +919,20 @@ def console(): options.interfaces = [ tuple(interface) for interface in options.interfaces] + # accepts --scheduler in the form + # "app:group1,group2,app2:group1" + scheduler = [] + options.scheduler_groups = None + if isinstance(options.scheduler, str): + if ':' in options.scheduler: + for opt in options.scheduler.split(','): + scheduler.append(opt.split(':')) + options.scheduler = ','.join([app[0] for app in scheduler]) + options.scheduler_groups = scheduler + if options.numthreads is not None and options.minthreads is None: - options.minthreads = options.numthreads # legacy - + options.minthreads = options.numthreads # legacy + if not options.cronjob: # If we have the applications package or if we should upgrade if not os.path.exists('applications/__init__.py'): @@ -940,20 +953,28 @@ def check_existent_app(options,appname): return True def start_schedulers(options): - apps = [app.strip() for app in options.scheduler.split(',')] try: from multiprocessing import Process except: sys.stderr.write('Sorry, -K only supported for python 2.6-2.7\n') return processes = [] - code = "from gluon import current;current._scheduler.loop()" + apps = [(app.strip(), None) for app in options.scheduler.split(',')] + if options.scheduler_groups: + apps = options.scheduler_groups for app in apps: - if not check_existent_app(options, app): - print "Application '%s' doesn't exist, skipping" % (app) + if len(app) == 1 or app[1] == None: + code = "from gluon import current;current._scheduler.loop()" + else: + code = "from gluon import current;current._scheduler.group_names = ['%s'];" + code += "current._scheduler.loop()" + code = code % ("','".join(app[1:])) + app_ = app[0] + if not check_existent_app(options, app_): + print "Application '%s' doesn't exist, skipping" % (app_) continue - print 'starting scheduler for "%s"...' % app - args = (app,True,True,None,False,code) + print 'starting scheduler for "%s"...' % app_ + args = (app_,True,True,None,False,code) logging.getLogger().setLevel(options.debuglevel) p = Process(target=run, args=args) processes.append(p) From 0b3604e3c765f61bddaec532728cbe0cf38dd9e8 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 17:39:59 -0500 Subject: [PATCH 39/53] more forgining auto links in markmin --- VERSION | 2 +- gluon/contrib/markmin/markmin2html.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 37e812f6..da53f4a0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 17:32:21) dev +Version 2.00.0 (2012-08-24 17:39:55) dev diff --git a/gluon/contrib/markmin/markmin2html.py b/gluon/contrib/markmin/markmin2html.py index a84c6d3a..d08cad32 100755 --- a/gluon/contrib/markmin/markmin2html.py +++ b/gluon/contrib/markmin/markmin2html.py @@ -523,7 +523,7 @@ regex_list=re.compile('^(?:(#{1,6}|\.+ |\++ |\++\. |\-+ |\-+\. )\s*)?(.*)$') regex_bq_headline=re.compile('^(?:(\.+|\++|\-+)(\.)?\s+)?(-{3}-*)$') regex_tq=re.compile('^(-{3}-*)(?::(?P[a-zA-Z][_a-zA-Z\-\d]*)(?:\[(?P

    [a-zA-Z][_a-zA-Z\-\d]*)\])?)?$') regex_proto = re.compile(r'(?/=])(?P

    \w+):(?P\w+://[\w\d\-+=?%&/:.]+)', re.M) -regex_auto = re.compile(r'(?/=])(?P\w+://[\w\d\-+_=?%&/:.]+)',re.M) +regex_auto = re.compile(r'(?/=])(?P\w+://[^\s\'\"\]\}\)]+)',re.M) regex_link=re.compile(r'('+LINK+r')|\[\[(?P.+?)\]\]') regex_link_level2=re.compile(r'^(?P\S.*?)?(?:\s+\[(?P.+?)\])?(?:\s+(?P\S+))?(?:\s+(?P

    popup))?\s*$') regex_media_level2=re.compile(r'^(?P\S.*?)?(?:\s+\[(?P.+?)\])?(?:\s+(?P\S+))?\s+(?P

    img|IMG|left|right|center|video|audio)(?:\s+(?P\d+px))?\s*$') From e3d34d860ab48257561721afbf0bbb1e0131d102 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 19:24:58 -0500 Subject: [PATCH 40/53] added .btn class in admin for grid --- VERSION | 2 +- applications/admin/static/css/styles.css | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/VERSION b/VERSION index da53f4a0..31364eab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 17:39:55) dev +Version 2.00.0 (2012-08-24 19:24:54) dev diff --git a/applications/admin/static/css/styles.css b/applications/admin/static/css/styles.css index 8375f145..c9e4c8d3 100644 --- a/applications/admin/static/css/styles.css +++ b/applications/admin/static/css/styles.css @@ -274,13 +274,13 @@ ul.button li a { display: block; z-index: 2; } -a.button { +a.button, a.btn { display: inline-block; vertical-align: middle; } /* 1.1. Normal status */ -a.button, +a.button, a.btn, ul.button li a { background-position: 100% 0; background-repeat: no-repeat; @@ -313,14 +313,14 @@ ul.button li.select a span { /* 2. EDITABLE STYLES */ /* 2.1. Image background used */ -a.button, +a.button, a.btn, .button a, .button span { background-image: url(../images/button.png); } /* 2.2. Normal status (Example for padding 10px) */ -a.button, +a.button, a.btn, .button a { padding: 0 10px 0 0; /* Padding-right: 10px */ margin: 0 1px 0 10px; /* Margin-left: 10px */ @@ -342,7 +342,7 @@ a.button span { _float: left; /* Only IE6 */ _position: relative; /* Only IE6 */ } -a.button { +a.button, a.btn { display: -moz-inline-box; /* FF<3 */ display: inline-block; /* FF<3 */ -moz-box-orient: vertical; /* FF<3 */ From 84cb7b67903978db1c719c9c2811bd386a475783 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 22:17:49 -0500 Subject: [PATCH 41/53] DIV.elements(replace=...), thanks Anthony --- CHANGELOG | 1 + VERSION | 2 +- gluon/html.py | 111 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 84 insertions(+), 30 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 41b5f636..eaf4baec 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -76,6 +76,7 @@ ### Other Improvements +- DIV(..).elements(...replace=...), thanks Anthony - new layout based on Twitter Bootstrap - New generic views: generic.ics (Mac Mail Calendar) and generic.map (Google Maps) - request.args(0,default=0, cast=int, otherwise=URL(...)), thanks Anthony diff --git a/VERSION b/VERSION index 31364eab..c517cf07 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 19:24:54) dev +Version 2.00.0 (2012-08-24 22:17:44) dev diff --git a/gluon/html.py b/gluon/html.py index e88d8604..8522b7a5 100644 --- a/gluon/html.py +++ b/gluon/html.py @@ -962,6 +962,48 @@ class DIV(XmlComponent): >>> for c in a.elements('input, select, textarea'): c['_disabled'] = 'disabled' >>> a.xml() '

    ' + + Elements that are matched can also be replaced or removed by specifying + a "replace" argument (note, a list of the original matching elements + is still returned as usual). + + >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) + >>> b = a.elements('span.abc', replace=P('x', _class='xyz')) + >>> print a +

    x

    x

    x

    + + "replace" can be a callable, which will be passed the original element and + should return a new element to replace it. + + >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) + >>> b = a.elements('span.abc', replace=lambda el: P(el[0], _class='xyz')) + >>> print a +

    x

    y

    z

    + + If replace=None, matching elements will be removed completely. + + >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) + >>> b = a.elements('span', find='y', replace=None) + >>> print a +
    x
    z
    + + If a "find_text" argument is specified, elements will be searched for text + components that match find_text, and any matching text components will be + replaced (find_text is ignored if "replace" is not also specified). + Like the "find" argument, "find_text" can be a string or a compiled regex. + + >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='abc'), SPAN('z', _class='abc')))) + >>> b = a.elements(find_text=re.compile('x|y|z'), replace='hello') + >>> print a +
    hello
    hellohello
    + + If other attributes are specified along with find_text, then only components + that match the specified attributes will be searched for find_text. + + >>> a = DIV(DIV(SPAN('x', _class='abc'), DIV(SPAN('y', _class='efg'), SPAN('z', _class='abc')))) + >>> b = a.elements('span.efg', find_text=re.compile('x|y|z'), replace='hello') + >>> print a +
    x
    helloz
    """ if len(args)==1: args = [a.strip() for a in args[0].split(',')] @@ -990,49 +1032,60 @@ class DIV(XmlComponent): return self.elements(*args,**kargs) # make a copy of the components matches = [] - first_only = False - if kargs.has_key("first_only"): - first_only = kargs["first_only"] - del kargs["first_only"] # check if the component has an attribute with the same # value as provided check = True - tag = getattr(self,'tag').replace("/","") + tag = getattr(self,'tag').replace('/', '') if args and tag not in args: check = False for (key, value) in kargs.items(): - if isinstance(value,(str,int)): - if self[key] != str(value): + if key not in ['first_only', 'replace', 'find_text']: + if isinstance(value, (str, int)): + if self[key] != str(value): + check = False + elif key in self.attributes: + if not value.search(str(self[key])): + check = False + else: check = False - elif key in self.attributes: - if not value.search(str(self[key])): - check = False - else: - check = False if 'find' in kargs: find = kargs['find'] + is_regex = not isinstance(find, (str, int)) for c in self.components: - if isinstance(find,(str,int)): - if isinstance(c,str) and str(find) in c: - check = True - else: - if isinstance(c,str) and find.search(c): - check = True + if (isinstance(c, str) and ((is_regex and find.search(c)) or + (str(find) in c))): + check = True # if found, return the component if check: matches.append(self) - if first_only: - return matches - # loop the copy - for c in self.components: - if isinstance(c, XmlComponent): - kargs['first_only'] = first_only - child_matches = c.elements( *args, **kargs ) - if first_only and len(child_matches) != 0: - return child_matches - matches.extend( child_matches ) - return matches + first_only = kargs.get('first_only', False) + replace = kargs.get('replace', False) + find_text = replace is not False and kargs.get('find_text', False) + is_regex = not isinstance(find_text, (str, int, bool)) + find_components = not (check and first_only) + def replace_component(i): + if replace is None: + del self[i] + elif callable(replace): + self[i] = replace(self[i]) + else: + self[i] = replace + # loop the components + if find_text or find_components: + for i, c in enumerate(self.components): + if check and find_text and isinstance(c, str) and \ + ((is_regex and find_text.search(c)) or (str(find_text) in c)): + replace_component(i) + if find_components and isinstance(c, XmlComponent): + child_matches = c.elements(*args, **kargs) + if len(child_matches): + if not find_text and replace is not False and child_matches[0] is c: + replace_component(i) + if first_only: + return child_matches + matches.extend(child_matches) + return matches def element(self, *args, **kargs): """ From 6d0721af667d08719c34c8f6a8cffd98ed97e1a8 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 22:40:18 -0500 Subject: [PATCH 42/53] template render can recycle a Response(), thanks Anthony --- VERSION | 2 +- gluon/template.py | 71 ++++++++++++++++++++++++++++------------------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/VERSION b/VERSION index c517cf07..20895a41 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 22:17:44) dev +Version 2.00.0 (2012-08-24 22:40:15) dev diff --git a/gluon/template.py b/gluon/template.py index 0127f1e2..72a75555 100644 --- a/gluon/template.py +++ b/gluon/template.py @@ -841,6 +841,32 @@ def get_parsed(text): """ return str(TemplateParser(text)) +class DummyResponse(): + def __init__(self): + self.body = cStringIO.StringIO() + def write(self, data, escape=True): + if not escape: + self.body.write(str(data)) + elif hasattr(data,'xml') and callable(data.xml): + self.body.write(data.xml()) + else: + # make it a string + if not isinstance(data, (str, unicode)): + data = str(data) + elif isinstance(data, unicode): + data = data.encode('utf8', 'xmlcharrefreplace') + data = cgi.escape(data, True).replace("'","'") + self.body.write(data) + +class NOESCAPE(): + """ + A little helper to avoid escaping. + """ + def __init__(self, text): + self.text = text + def xml(self): + return self.text + # And this is a generic render function. # Here for integration with gluon. def render(content = "hello world", @@ -877,42 +903,29 @@ def render(content = "hello world", >>> render(content='{{for i in range(3):\\n=i\\npass}}') '012' """ - # Here to avoid circular Imports + # save current response class + if context and 'response' in context: + old_response = context['response'] + else: + old_response = None + + # here to avoid circular Imports try: from globals import Response - except: + except ImportError: # Working standalone. Build a mock Response object. - class Response(): - def __init__(self): - self.body = cStringIO.StringIO() - def write(self, data, escape=True): - if not escape: - self.body.write(str(data)) - elif hasattr(data,'xml') and callable(data.xml): - self.body.write(data.xml()) - else: - # make it a string - if not isinstance(data, (str, unicode)): - data = str(data) - elif isinstance(data, unicode): - data = data.encode('utf8', 'xmlcharrefreplace') - data = cgi.escape(data, True).replace("'","'") - self.body.write(data) + Response = DummyResponse - # A little helper to avoid escaping. - class NOESCAPE(): - def __init__(self, text): - self.text = text - def xml(self): - return self.text # Add it to the context so we can use it. - context['NOESCAPE'] = NOESCAPE - + if not 'NOESCAPE' in context: + context['NOESCAPE'] = XML + # If we don't have anything to render, why bother? if not content and not stream and not filename: raise SyntaxError, "Must specify a stream or filename or content" - # Here for legacy purposes, probably can be reduced to something more simple. + # Here for legacy purposes, probably can be reduced to + # something more simple. close_stream = False if not stream: if filename: @@ -936,7 +949,9 @@ def render(content = "hello world", stream.close() # Returned the rendered content. - return context['response'].body.getvalue() + text = context['response'].body.getvalue() + if old_response is not None: context['response'] = old_response + return text if __name__ == '__main__': From 19e9596b5b6f4adf5f5b74a5b9573a643c5c1565 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 22:52:45 -0500 Subject: [PATCH 43/53] executesql(fields=,columns=),thanks Anthony --- VERSION | 2 +- gluon/dal.py | 42 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/VERSION b/VERSION index 20895a41..a6dad91d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 22:40:15) dev +Version 2.00.0 (2012-08-24 22:52:42) dev diff --git a/gluon/dal.py b/gluon/dal.py index d29fa676..0d34e0b3 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -7035,9 +7035,10 @@ def index(): thread.instances.remove(self._adapter) self._adapter.close() - def executesql(self, query, placeholders=None, as_dict=False): + def executesql(self, query, placeholders=None, as_dict=False, + fields=None, colnames=None): """ - placeholders is optional and will always be None when using DAL. + placeholders is optional and will always be None. If using raw SQL with placeholders, placeholders may be a sequence of values to be substituted in or, (if supported by the DB driver), a dictionary with keys @@ -7054,7 +7055,21 @@ def index(): [{field1: value1, field2: value2}, {field1: value1b, field2: value2b}] - --bmeredyk + Added 2012-08-24 "fields" optional argument. If not None, the + results cursor returned by the DB driver will be converted to a + DAL Rows object using the db._adapter.parse() method. This requires + specifying the "fields" argument as a list of DAL Field objects + that match the fields returned from the DB. The Field objects should + be part of one or more Table objects defined on the DAL object. + The "fields" list can include one or more DAL Table objects in addition + to or instead of including Field objects, or it can be just a single + table (not in a list). In that case, the Field objects will be + extracted from the table(s). + + The field names will be extracted from the Field objects, or optionally, + a list of field names can be provided (in tablename.fieldname format) + via the "colnames" argument. Note, the fields and colnames must be in + the same order as the fields in the results cursor returned from the DB. """ if placeholders: self._adapter.execute(query, placeholders) @@ -7074,11 +7089,22 @@ def index(): # convert the list for each row into a dictionary so it's # easier to work with. row['field_name'] rather than row[0] return [dict(zip(fields,row)) for row in data] - # see if any results returned from database - try: - return self._adapter.cursor.fetchall() - except: - return None + data = self._adapter.cursor.fetchall() + if fields: + if not isinstance(fields, list): + fields = [fields] + extracted_fields = [] + for field in fields: + if isinstance(field, Table): + extracted_fields.extend([f for f in field]) + else: + extracted_fields.append(field) + if not colnames: + colnames = ['%s.%s' % (f.tablename, f.name) + for f in extracted_fields] + data = self._adapter.parse( + data, fields=extracted_fields, colnames=colnames) + return data def _update_referenced_by(self, other): for tablename in self.tables: From 477cefa5e12c37275706562252bb39bfb80c9e72 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 23:11:45 -0500 Subject: [PATCH 44/53] fixed some styles for auth.wiki --- VERSION | 2 +- applications/admin/static/css/web2py.css | 12 +++++++++--- applications/examples/static/css/web2py.css | 12 +++++++++--- applications/welcome/static/css/web2py.css | 8 +++++++- gluon/sqlhtml.py | 9 ++++++--- gluon/tools.py | 3 ++- 6 files changed, 34 insertions(+), 12 deletions(-) diff --git a/VERSION b/VERSION index a6dad91d..e12db2ed 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 22:52:42) dev +Version 2.00.0 (2012-08-24 23:11:41) dev diff --git a/applications/admin/static/css/web2py.css b/applications/admin/static/css/web2py.css index 13f24237..54b1cbce 100644 --- a/applications/admin/static/css/web2py.css +++ b/applications/admin/static/css/web2py.css @@ -80,11 +80,11 @@ fieldset legend {text-transform:uppercase; font-weight:bold; padding:4px 16px 4p td.w2p_fw {padding-bottom:1px} td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top} -td.w2p_fl {text-align:right} +td.w2p_fl {text-align:left} td.w2p_fl, td.w2p_fw {padding-right:7px} td.w2p_fl,td.w2p_fc {padding-top:4px} div.w2p_export_menu {margin:5px 0} -div.w2p_export_menu a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;} +div.w2p_export_menu a, div.w2p_wiki_tags a, div.w2p_cloud a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;} /* tr#submit_record__row {border-top:1px solid #E5E5E5} */ #submit_record__row td {padding-top:.5em} @@ -294,8 +294,14 @@ div.error { margin-bottom:18px; } -.web2py_breadcrumbs ul li { +li.w2p_grid_breadcrumb_elem { display:inline-block; } .ie9 #query_panel {padding-bottom:2px} + +#wiki_page_body { + width: 600px; + height: auto; + min-height: 400px; +} \ No newline at end of file diff --git a/applications/examples/static/css/web2py.css b/applications/examples/static/css/web2py.css index 13f24237..54b1cbce 100644 --- a/applications/examples/static/css/web2py.css +++ b/applications/examples/static/css/web2py.css @@ -80,11 +80,11 @@ fieldset legend {text-transform:uppercase; font-weight:bold; padding:4px 16px 4p td.w2p_fw {padding-bottom:1px} td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top} -td.w2p_fl {text-align:right} +td.w2p_fl {text-align:left} td.w2p_fl, td.w2p_fw {padding-right:7px} td.w2p_fl,td.w2p_fc {padding-top:4px} div.w2p_export_menu {margin:5px 0} -div.w2p_export_menu a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;} +div.w2p_export_menu a, div.w2p_wiki_tags a, div.w2p_cloud a {margin-left:5px; padding:2px 5px; background-color:#f1f1f1; border-radius:5px; -moz-border-radius:5px; -webkit-border-radius:5px;} /* tr#submit_record__row {border-top:1px solid #E5E5E5} */ #submit_record__row td {padding-top:.5em} @@ -294,8 +294,14 @@ div.error { margin-bottom:18px; } -.web2py_breadcrumbs ul li { +li.w2p_grid_breadcrumb_elem { display:inline-block; } .ie9 #query_panel {padding-bottom:2px} + +#wiki_page_body { + width: 600px; + height: auto; + min-height: 400px; +} \ No newline at end of file diff --git a/applications/welcome/static/css/web2py.css b/applications/welcome/static/css/web2py.css index d6f06391..54b1cbce 100644 --- a/applications/welcome/static/css/web2py.css +++ b/applications/welcome/static/css/web2py.css @@ -80,7 +80,7 @@ fieldset legend {text-transform:uppercase; font-weight:bold; padding:4px 16px 4p td.w2p_fw {padding-bottom:1px} td.w2p_fl,td.w2p_fw,td.w2p_fc {vertical-align:top} -td.w2p_fl {text-align:right} +td.w2p_fl {text-align:left} td.w2p_fl, td.w2p_fw {padding-right:7px} td.w2p_fl,td.w2p_fc {padding-top:4px} div.w2p_export_menu {margin:5px 0} @@ -299,3 +299,9 @@ li.w2p_grid_breadcrumb_elem { } .ie9 #query_panel {padding-bottom:2px} + +#wiki_page_body { + width: 600px; + height: auto; + min-height: 400px; +} \ No newline at end of file diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index 02314221..0436ce0d 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -238,8 +238,10 @@ class ListWidget(StringWidget): if field.type=='list:integer': _class = 'integer' else: _class = 'string' requires = field.requires if isinstance(field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None - items=[LI(INPUT(_id=_id, _class=_class, _name=_name, value=v, hideerror=True, requires=requires)) \ - for v in value or ['']] + attributes['_style'] = 'list-style:none' + items=[LI(INPUT(_id=_id, _class=_class, _name=_name, + value=v, hideerror=True, requires=requires), + **attributes) for v in value or ['']] script=SCRIPT(""" // from http://refactormycode.com/codes/694-expanding-input-list-using-jquery (function(){ @@ -270,7 +272,8 @@ function rel(ul) { })(); jQuery(document).ready(function(){jQuery('#%s_grow_input').grow_input();}); """ % _id) - attributes['_id']=_id+'_grow_input' + attributes['_id'] = _id+'_grow_input' + attributes['_style'] = 'list-style:none' return TAG[''](UL(*items,**attributes),script) diff --git a/gluon/tools.py b/gluon/tools.py index a983869b..25f48d07 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -4662,7 +4662,8 @@ class Wiki(object): vars = current.request.post_vars if vars.body: vars.body=vars.body.replace('://%s' % self.host,'://HOSTNAME') - form = SQLFORM(db.wiki_page,page,deletable=True,showid=False).process() + form = SQLFORM(db.wiki_page,page,deletable=True, + formstyle='table2cols',showid=False).process() if form.deleted: current.session.flash = 'page deleted' redirect(URL()) From e16d24b1d364e4270a70b02a5f8977de6f087227 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 23:37:10 -0500 Subject: [PATCH 45/53] changelog update --- CHANGELOG | 1 + VERSION | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index eaf4baec..3e3c7017 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ - added db.table.field.avg() - Support for Google App Engine projections - Field(... 'upload', default=path) now accepts a path to a local file as default value, if user does not upload a file. Relative path looks inside current application folder, thanks Marin +- executesql(...,fields=,columns=) allows parsing of results in Rows, thanks Anthony ### Auth improvements diff --git a/VERSION b/VERSION index e12db2ed..ab9bd0d7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 23:11:41) dev +Version 2.00.0 (2012-08-24 23:37:07) dev From da2083ee3616a040a2477dcf56d5285294c86cac Mon Sep 17 00:00:00 2001 From: mdipierro Date: Fri, 24 Aug 2012 23:47:47 -0500 Subject: [PATCH 46/53] better fix of recycle Response in template, thanks Anthony --- VERSION | 2 +- gluon/template.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/VERSION b/VERSION index ab9bd0d7..e2ae8483 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 23:37:07) dev +Version 2.00.0 (2012-08-24 23:47:44) dev diff --git a/gluon/template.py b/gluon/template.py index 72a75555..06d01023 100644 --- a/gluon/template.py +++ b/gluon/template.py @@ -903,12 +903,6 @@ def render(content = "hello world", >>> render(content='{{for i in range(3):\\n=i\\npass}}') '012' """ - # save current response class - if context and 'response' in context: - old_response = context['response'] - else: - old_response = None - # here to avoid circular Imports try: from globals import Response @@ -920,6 +914,14 @@ def render(content = "hello world", if not 'NOESCAPE' in context: context['NOESCAPE'] = XML + # save current response class + if context and 'response' in context: + old_response_body = context['response'].body + context['response'].body = cStringIO.StringIO() + else: + old_response_body = None + context['response'] = Response() + # If we don't have anything to render, why bother? if not content and not stream and not filename: raise SyntaxError, "Must specify a stream or filename or content" @@ -934,9 +936,6 @@ def render(content = "hello world", elif content: stream = cStringIO.StringIO(content) - # Get a response class. - context['response'] = Response() - # Execute the template. code = str(TemplateParser(stream.read(), context=context, path=path, lexers=lexers, delimiters=delimiters)) try: @@ -950,7 +949,8 @@ def render(content = "hello world", # Returned the rendered content. text = context['response'].body.getvalue() - if old_response is not None: context['response'] = old_response + if old_response_body is not None: + context['response'].body = old_response_body return text From 54b9e4126d4fc5c0e5b41fa16227f595e647eeeb Mon Sep 17 00:00:00 2001 From: mdipierro Date: Sat, 25 Aug 2012 11:17:39 -0500 Subject: [PATCH 47/53] GIT_MISSING message, thanks Niphlod --- VERSION | 2 +- applications/admin/controllers/default.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index e2ae8483..c682cecd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-24 23:47:44) dev +Version 2.00.0 (2012-08-25 11:17:34) dev diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index d4ece9ce..4f685ba0 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -20,7 +20,7 @@ try: have_git = True except ImportError: have_git = False - GIT_MISSING = 'requires python-git module, but not installed' + GIT_MISSING = 'requires python-git module, but not installed or incompatible version' from gluon.languages import (regex_language, read_possible_languages, read_possible_plurals, lang_sampling, @@ -223,6 +223,7 @@ def site(): if (form_update.vars.url or '').endswith('.git'): if not have_git: session.flash = GIT_MISSING + redirect(URL(r=request)) target = os.path.join(apath(r=request),form_update.vars.name) try: new_repo = Repo.clone_from(form_update.vars.url,target) From f36546676fa423385e48941b75570445853ee149 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Sat, 25 Aug 2012 11:22:28 -0500 Subject: [PATCH 48/53] updated changelog --- CHANGELOG | 7 ++++--- VERSION | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3e3c7017..993ebe19 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,13 +3,13 @@ ### DAL Improvements - Support for DAL(lazy_tables=True) and db.define_table(on_define=lambda table:), thanks Jonathan -- MongoDB support in DAL (experimental) +- MongoDB support in DAL (experimental), thanks Mark Breedveld - geodal and spatialite, thanks Denes and Fran (experimental) - db.mytable._before_insert, _after_insert, _before_update, _after_update, _before_delete. _after_delete (list of callbacks) - db(...).update_naive(...) same as update but ignores table._before_update and table._after_update - DAL BIGINT support and DAL(...,bigint_id=True) - IS_IN_DB(..., distinct=True) -- new syntax: db.mytable.insert(myuploadfield=open(....)) +- new syntax: db.mytable.insert(myuploadfield=open(....)), thank you Iceberg - db(...).select(db.mytable.myfield.count(distinct=True)) - db(db.a)._update(name=db(db.b.a==db.a.id).nested_select(db.b.id)) - db.mytable.myfield.filter_in, filter_out @@ -17,7 +17,7 @@ - teradata adapter, thanks Andrew Willimott - experimental Sybase Adapter - added db.table.field.avg() -- Support for Google App Engine projections +- Support for Google App Engine projections, thanks Christian - Field(... 'upload', default=path) now accepts a path to a local file as default value, if user does not upload a file. Relative path looks inside current application folder, thanks Marin - executesql(...,fields=,columns=) allows parsing of results in Rows, thanks Anthony @@ -97,6 +97,7 @@ - added tox.ini, thanks Marc - web2py.py --run_system_tests, thanks Marc Abramowitz - html.py (and web2py helpers) can be used without web2py dependencies +- new fpdf, thanks Mariano ## 1.99.5-1.99.7 diff --git a/VERSION b/VERSION index c682cecd..2cefdb04 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-25 11:17:34) dev +Version 2.00.0 (2012-08-25 11:22:25) dev From ae329f6adb2d0cee5f5536edc4debb4e61663d84 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Sat, 25 Aug 2012 11:25:58 -0500 Subject: [PATCH 49/53] fixed anchor in markmin --- VERSION | 2 +- gluon/contrib/markmin/markmin2html.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/VERSION b/VERSION index 2cefdb04..767e083c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-25 11:22:25) dev +Version 2.00.0 (2012-08-25 11:25:55) dev diff --git a/gluon/contrib/markmin/markmin2html.py b/gluon/contrib/markmin/markmin2html.py index d08cad32..162dd6d1 100755 --- a/gluon/contrib/markmin/markmin2html.py +++ b/gluon/contrib/markmin/markmin2html.py @@ -598,7 +598,7 @@ def render(text, - class_prefix is a prefix for ALL classes in markmin text. E.g. if class_prefix='my_' then for ``test``:cls class will be changed to "my_cls" (default value is '') - id_prefix is prefix for ALL ids in markmin text (default value is 'markmin_'). E.g.: - -- [[id]] will be converted to
    + -- [[id]] will be converted to
    -- [[link #id]] will be converted to link -- ``test``:cls[id] will be converted to test @@ -729,19 +729,19 @@ def render(text, '

    [[probe]]

    ' >>> render(r"\\\\[[probe]]") - '

    \\\\

    ' + '

    \\\\

    ' >>> render(r"\\\\\\[[probe]]") '

    \\\\[[probe]]

    ' >>> render(r"\\\\\\\\[[probe]]") - '

    \\\\\\\\

    ' + '

    \\\\\\\\

    ' >>> render(r"\\\\\\\\\[[probe]]") '

    \\\\\\\\[[probe]]

    ' >>> render(r"\\\\\\\\\\\[[probe]]") - '

    \\\\\\\\\\\\

    ' + '

    \\\\\\\\\\\\

    ' >>> render("``[[ [\\[[probe\]\\]] URL\\[x\\]]]``:red[dummy_params]") 'URL[x]' @@ -789,7 +789,7 @@ def render(text, '

    test 1

    ' >>> render('[[id1 [span **messag** in ''markmin''] ]] ... [[**link** to id [link\\\'s title] #mark1]]') - '

    span messag in markmin ... link to id

    ' + '

    span messag in markmin
    ... link to id

    ' """ if autolinks=="default": autolinks = autolinks_simple @@ -1200,7 +1200,7 @@ def render(text, protolinks, class_prefix, id_prefix) if t else k return '%(t)s' \ % dict(k=k, title=title, target=target, t=t) - return '%s' % (escape(id_prefix+t), + return '
    %s
    ' % (escape(id_prefix+t), render(a, {},{},'br', URL, environment, latex, autolinks, protolinks, class_prefix, id_prefix)) From d322ec5690528f5a8b84ca59a6302df08a06adda Mon Sep 17 00:00:00 2001 From: mdipierro Date: Sat, 25 Aug 2012 11:29:11 -0500 Subject: [PATCH 50/53] fixed @//// in wiki and pep8 spacing --- VERSION | 2 +- __init__.py | 2 ++ anyserver.py | 1 + appengine_config.py | 1 + cgihandler.py | 1 + fcgihandler.py | 1 + gaehandler.py | 1 + gluon/__init__.py | 1 + gluon/admin.py | 1 + gluon/cache.py | 1 + gluon/cfs.py | 1 + gluon/compileapp.py | 1 + gluon/contenttype.py | 1 + gluon/contrib/AuthorizeNet.py | 1 + gluon/contrib/DowCommerce.py | 1 + gluon/contrib/__init__.py | 1 + gluon/contrib/aes.py | 1 + gluon/contrib/autolinks.py | 5 +-- gluon/contrib/comet_messaging.py | 1 + gluon/contrib/feedparser.py | 1 + gluon/contrib/gae_memcache.py | 1 + gluon/contrib/gae_retry.py | 1 + gluon/contrib/generics.py | 1 + gluon/contrib/google_wallet.py | 1 + gluon/contrib/gql.py | 1 + gluon/contrib/imageutils.py | 1 + gluon/contrib/login_methods/__init__.py | 1 + gluon/contrib/login_methods/basic_auth.py | 1 + .../login_methods/browserid_account.py | 19 ++++++----- gluon/contrib/login_methods/cas_auth.py | 1 + .../contrib/login_methods/dropbox_account.py | 11 ++++--- gluon/contrib/login_methods/email_auth.py | 1 + .../login_methods/extended_login_form.py | 3 +- .../login_methods/gae_google_account.py | 1 + gluon/contrib/login_methods/ldap_auth.py | 1 + .../contrib/login_methods/linkedin_account.py | 1 + gluon/contrib/login_methods/loginza.py | 1 + gluon/contrib/login_methods/motp_auth.py | 33 ++++++++++--------- .../contrib/login_methods/oauth10a_account.py | 1 + .../contrib/login_methods/oauth20_account.py | 11 ++++--- gluon/contrib/login_methods/openid_auth.py | 1 + gluon/contrib/login_methods/pam_auth.py | 1 + gluon/contrib/login_methods/rpx_account.py | 5 +-- gluon/contrib/login_methods/x509_auth.py | 5 +-- gluon/contrib/markmin/markmin2html.py | 2 +- gluon/contrib/memdb.py | 1 + gluon/contrib/pam.py | 1 + gluon/contrib/pbkdf2.py | 1 + gluon/contrib/populate.py | 1 + gluon/contrib/pyfpdf.py | 1 + gluon/contrib/qdb.py | 1 + gluon/contrib/redis_cache.py | 1 + gluon/contrib/rss2.py | 1 + gluon/contrib/shell.py | 1 + gluon/contrib/simplejsonrpc.py | 1 + gluon/contrib/sms_utils.py | 1 + gluon/contrib/spreadsheet.py | 1 + gluon/contrib/stripe.py | 1 + gluon/contrib/taskbar_widget.py | 1 + gluon/contrib/timecollect.py | 1 + gluon/contrib/user_agent_parser.py | 1 + gluon/custom_import.py | 1 + gluon/dal.py | 13 ++++---- gluon/debug.py | 1 + gluon/decoder.py | 1 + gluon/fileutils.py | 1 + gluon/globals.py | 3 +- gluon/highlight.py | 1 + gluon/html.py | 3 +- gluon/http.py | 1 + gluon/import_all.py | 1 + gluon/languages.py | 1 + gluon/main.py | 1 + gluon/messageboxhandler.py | 1 + gluon/myregex.py | 1 + gluon/newcron.py | 1 + gluon/portalocker.py | 1 + gluon/reserved_sql_keywords.py | 1 + gluon/restricted.py | 1 + gluon/rewrite.py | 3 +- gluon/rocket.py | 1 + gluon/sanitizer.py | 1 + gluon/scheduler.py | 1 + gluon/serializers.py | 1 + gluon/settings.py | 1 + gluon/shell.py | 1 + gluon/sql.py | 1 + gluon/sqlhtml.py | 3 +- gluon/storage.py | 5 +-- gluon/streamer.py | 1 + gluon/template.py | 5 +-- gluon/tools.py | 23 ++++++------- gluon/utf8.py | 1 + gluon/utils.py | 1 + gluon/validators.py | 1 + gluon/widget.py | 7 ++-- gluon/winservice.py | 1 + gluon/xmlrpc.py | 1 + isapiwsgihandler.py | 1 + modpythonhandler.py | 1 + options_std.py | 1 + router.example.py | 1 + routes.example.py | 1 + scgihandler.py | 1 + setup.py | 1 + setup_app.py | 1 + setup_exe.py | 1 + setup_exe_2.6.py | 1 + web2py.py | 1 + wsgihandler.py | 1 + 110 files changed, 181 insertions(+), 72 deletions(-) diff --git a/VERSION b/VERSION index 767e083c..296d274f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-25 11:25:55) dev +Version 2.00.0 (2012-08-25 11:29:08) dev diff --git a/__init__.py b/__init__.py index 12a6f48e..584ba879 100644 --- a/__init__.py +++ b/__init__.py @@ -6,3 +6,5 @@ + + diff --git a/anyserver.py b/anyserver.py index 3d6c929c..53985442 100644 --- a/anyserver.py +++ b/anyserver.py @@ -309,3 +309,4 @@ if __name__=='__main__': + diff --git a/appengine_config.py b/appengine_config.py index 33916e4d..4bb11668 100644 --- a/appengine_config.py +++ b/appengine_config.py @@ -6,3 +6,4 @@ def webapp_add_wsgi_middleware(app): + diff --git a/cgihandler.py b/cgihandler.py index 16620054..c4c14993 100755 --- a/cgihandler.py +++ b/cgihandler.py @@ -65,3 +65,4 @@ wsgiref.handlers.CGIHandler().run(gluon.main.wsgibase) + diff --git a/fcgihandler.py b/fcgihandler.py index 196e538f..f45067a6 100755 --- a/fcgihandler.py +++ b/fcgihandler.py @@ -55,3 +55,4 @@ fcgi.WSGIServer(application, bindAddress='/tmp/fcgi.sock').run() + diff --git a/gaehandler.py b/gaehandler.py index 0d09987b..7557a982 100755 --- a/gaehandler.py +++ b/gaehandler.py @@ -103,3 +103,4 @@ if __name__ == '__main__': + diff --git a/gluon/__init__.py b/gluon/__init__.py index 2f48d365..fd88cd43 100644 --- a/gluon/__init__.py +++ b/gluon/__init__.py @@ -52,3 +52,4 @@ if 0: + diff --git a/gluon/admin.py b/gluon/admin.py index d84ece9e..bb3bcf92 100644 --- a/gluon/admin.py +++ b/gluon/admin.py @@ -480,3 +480,4 @@ def create_missing_app_folders(request): + diff --git a/gluon/cache.py b/gluon/cache.py index cbe2b215..bc9cc0f9 100644 --- a/gluon/cache.py +++ b/gluon/cache.py @@ -498,3 +498,4 @@ def lazy_cache(key=None,time_expire=None,cache_model='ram'): return decorator + diff --git a/gluon/cfs.py b/gluon/cfs.py index d643882b..b3669f4b 100644 --- a/gluon/cfs.py +++ b/gluon/cfs.py @@ -56,3 +56,4 @@ def getcfs(key, filename, filter=None): + diff --git a/gluon/compileapp.py b/gluon/compileapp.py index 378e8441..a6bb23f8 100644 --- a/gluon/compileapp.py +++ b/gluon/compileapp.py @@ -691,3 +691,4 @@ if __name__ == '__main__': + diff --git a/gluon/contenttype.py b/gluon/contenttype.py index 6e4c78b6..cb11c687 100644 --- a/gluon/contenttype.py +++ b/gluon/contenttype.py @@ -723,3 +723,4 @@ def contenttype(filename, default='text/plain'): + diff --git a/gluon/contrib/AuthorizeNet.py b/gluon/contrib/AuthorizeNet.py index aa6bf785..8b24ef0a 100755 --- a/gluon/contrib/AuthorizeNet.py +++ b/gluon/contrib/AuthorizeNet.py @@ -263,3 +263,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/DowCommerce.py b/gluon/contrib/DowCommerce.py index 090fd077..d71c3911 100644 --- a/gluon/contrib/DowCommerce.py +++ b/gluon/contrib/DowCommerce.py @@ -243,3 +243,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/__init__.py b/gluon/contrib/__init__.py index 9e5f5f8a..12a6f48e 100644 --- a/gluon/contrib/__init__.py +++ b/gluon/contrib/__init__.py @@ -5,3 +5,4 @@ + diff --git a/gluon/contrib/aes.py b/gluon/contrib/aes.py index bb745310..cfc212b5 100644 --- a/gluon/contrib/aes.py +++ b/gluon/contrib/aes.py @@ -501,3 +501,4 @@ aes_Rcon = array('B', '61c29f254a943366cc831d3a74e8cb'.decode('hex') ) + diff --git a/gluon/contrib/autolinks.py b/gluon/contrib/autolinks.py index cb05079a..be72db03 100644 --- a/gluon/contrib/autolinks.py +++ b/gluon/contrib/autolinks.py @@ -135,7 +135,7 @@ def oembed(url): for k,v in EMBED_MAPS: if k.match(url): oembed = v+'?format=json&url='+cgi.escape(url) - try: + try: data = urllib.urlopen(oembed).read() print data return loads(data) # json! @@ -152,7 +152,7 @@ def expand_one(url,cdict): r = cdict[url] else: r = oembed(url) - if isinstance(cdict,dict): + if isinstance(cdict,dict): cdict[url] = r # if oembed service if 'html' in r: @@ -204,3 +204,4 @@ if __name__=="__main__": else: print test() + diff --git a/gluon/contrib/comet_messaging.py b/gluon/contrib/comet_messaging.py index d41afb51..c3f2ed35 100644 --- a/gluon/contrib/comet_messaging.py +++ b/gluon/contrib/comet_messaging.py @@ -194,3 +194,4 @@ if __name__ == "__main__": + diff --git a/gluon/contrib/feedparser.py b/gluon/contrib/feedparser.py index 371323e9..1afb2c11 100755 --- a/gluon/contrib/feedparser.py +++ b/gluon/contrib/feedparser.py @@ -3910,3 +3910,4 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer + diff --git a/gluon/contrib/gae_memcache.py b/gluon/contrib/gae_memcache.py index e03e74fe..99c4f3cf 100644 --- a/gluon/contrib/gae_memcache.py +++ b/gluon/contrib/gae_memcache.py @@ -55,3 +55,4 @@ class MemcacheClient(Client): + diff --git a/gluon/contrib/gae_retry.py b/gluon/contrib/gae_retry.py index a3f671f2..134112a4 100644 --- a/gluon/contrib/gae_retry.py +++ b/gluon/contrib/gae_retry.py @@ -90,3 +90,4 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0): + diff --git a/gluon/contrib/generics.py b/gluon/contrib/generics.py index d50137c0..0c9c2a23 100644 --- a/gluon/contrib/generics.py +++ b/gluon/contrib/generics.py @@ -67,3 +67,4 @@ def pdf_from_html(html): + diff --git a/gluon/contrib/google_wallet.py b/gluon/contrib/google_wallet.py index 84d39171..9ea64ea6 100644 --- a/gluon/contrib/google_wallet.py +++ b/gluon/contrib/google_wallet.py @@ -19,3 +19,4 @@ def button(merchant_id="123456789012345", + diff --git a/gluon/contrib/gql.py b/gluon/contrib/gql.py index 94465a7d..92b637e9 100644 --- a/gluon/contrib/gql.py +++ b/gluon/contrib/gql.py @@ -9,3 +9,4 @@ from gluon.dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, driv + diff --git a/gluon/contrib/imageutils.py b/gluon/contrib/imageutils.py index 1c5041ff..e8094458 100644 --- a/gluon/contrib/imageutils.py +++ b/gluon/contrib/imageutils.py @@ -58,3 +58,4 @@ def THUMB(image, nx=120, ny=120, gae=False, name='thumb'): else: return image + diff --git a/gluon/contrib/login_methods/__init__.py b/gluon/contrib/login_methods/__init__.py index 139597f9..b28b04f6 100644 --- a/gluon/contrib/login_methods/__init__.py +++ b/gluon/contrib/login_methods/__init__.py @@ -1,2 +1,3 @@ + diff --git a/gluon/contrib/login_methods/basic_auth.py b/gluon/contrib/login_methods/basic_auth.py index 78b461cb..fee1c35b 100644 --- a/gluon/contrib/login_methods/basic_auth.py +++ b/gluon/contrib/login_methods/basic_auth.py @@ -23,3 +23,4 @@ def basic_auth(server="http://127.0.0.1"): return False return basic_login_aux + diff --git a/gluon/contrib/login_methods/browserid_account.py b/gluon/contrib/login_methods/browserid_account.py index 8d74af30..83375c8e 100644 --- a/gluon/contrib/login_methods/browserid_account.py +++ b/gluon/contrib/login_methods/browserid_account.py @@ -6,18 +6,18 @@ developed by Madhukar R Pai (Copyright 2012) Email License : LGPL - + thanks and credits to the web2py community - + This custom authenticator allows web2py to authenticate using browserid (https://browserid.org/) BrowserID is a project by Mozilla Labs (http://mozillalabs.com/) to Know how browserid works please visit http://identity.mozilla.com/post/7616727542/introducing-browserid-a-better-way-to-sign-in - + bottom line BrowserID provides a free, secure, de-centralized, easy to use(for users and developers) login solution. You can use any email id as your login id. Browserid just verifys the email id and lets you login with that id. - + credits for the doPost jquery function - itsadok (http://stackoverflow.com/users/7581/itsadok) - + """ import time from gluon import * @@ -32,7 +32,7 @@ class BrowserID(object): audience = "http://127.0.0.1:8000" assertion_post_url = "http://127.0.0.1:8000/%s/default/user/login" % request.application) """ - + def __init__(self, request, audience = "", @@ -45,7 +45,7 @@ class BrowserID(object): crypto_js = "https://crypto-js.googlecode.com/files/2.2.0-crypto-md5.js", on_login_failure = None, ): - + self.request = request self.audience = audience self.assertion_post_url = assertion_post_url @@ -64,13 +64,13 @@ class BrowserID(object): def get_user(self): request = self.request - if request.vars.assertion: + if request.vars.assertion: audience = self.audience issuer = self.issuer assertion = XML(request.vars.assertion,sanitize=True) verify_data = {'assertion':assertion,'audience':audience} auth_info_json = fetch(self.verify_url,data=verify_data) - j = json.loads(auth_info_json) + j = json.loads(auth_info_json) epoch_time = int(time.time()*1000) # we need 13 digit epoch time if j["status"] == "okay" and j["audience"] == audience and j['issuer'] == issuer and j['expires'] >= epoch_time: return dict(email = j['email']) @@ -88,3 +88,4 @@ class BrowserID(object): A(IMG(_src=self.browserid_button,_alt=self.prompt),_href="#",_onclick=onclick,_class="browserid",_title="Login With BrowserID"), SCRIPT(self.asertion_js)) return form + diff --git a/gluon/contrib/login_methods/cas_auth.py b/gluon/contrib/login_methods/cas_auth.py index d53f3608..0c922a56 100644 --- a/gluon/contrib/login_methods/cas_auth.py +++ b/gluon/contrib/login_methods/cas_auth.py @@ -136,3 +136,4 @@ class CasAuth( object ): import urllib redirect("%s?service=%s" % (self.cas_logout_url,self.cas_my_url)) + diff --git a/gluon/contrib/login_methods/dropbox_account.py b/gluon/contrib/login_methods/dropbox_account.py index 54b71c46..bfd94723 100644 --- a/gluon/contrib/login_methods/dropbox_account.py +++ b/gluon/contrib/login_methods/dropbox_account.py @@ -12,7 +12,7 @@ import os import re import urllib -from dropbox import client, rest, session +from dropbox import client, rest, session from gluon import * from gluon.tools import fetch from gluon.storage import Storage @@ -50,15 +50,15 @@ class DropboxAccount(object): self.sess = session.DropboxSession( self.key,self.secret,self.access_type) - + def get_user(self): request = self.request token = current.session.dropbox_token try: - access_token = self.sess.obtain_access_token(token) + access_token = self.sess.obtain_access_token(token) except: access_token = None - if access_token: + if access_token: user = Storage() self.client = client.DropboxClient(self.sess) data = self.client.account_info() @@ -68,7 +68,7 @@ class DropboxAccount(object): last_name = display_name[-1], registration_id = data.get('uid',None)) if not user['registration_id'] and self.on_login_failure: - redirect(self.on_login_failure) + redirect(self.on_login_failure) return user return None @@ -107,3 +107,4 @@ def use_dropbox(auth,filename='private/dropbox.key',**kwargs): auth.settings.login_form = DropboxAccount( request,key=key,secret=secret,access_type=access_type, login_url = login_url,**kwargs) + diff --git a/gluon/contrib/login_methods/email_auth.py b/gluon/contrib/login_methods/email_auth.py index 5cba3108..a53011a2 100644 --- a/gluon/contrib/login_methods/email_auth.py +++ b/gluon/contrib/login_methods/email_auth.py @@ -43,3 +43,4 @@ def email_auth(server="smtp.gmail.com:587", pass return False return email_auth_aux + diff --git a/gluon/contrib/login_methods/extended_login_form.py b/gluon/contrib/login_methods/extended_login_form.py index 26e105b1..059d4816 100644 --- a/gluon/contrib/login_methods/extended_login_form.py +++ b/gluon/contrib/login_methods/extended_login_form.py @@ -86,7 +86,7 @@ class ExtendedLoginForm(object): Otherwise it will render the normal login form combined with alt_login_form.login_form. """ - + request = current.request args = request.args @@ -102,3 +102,4 @@ class ExtendedLoginForm(object): form.components.append(self.alt_login_form.login_form()) return form + diff --git a/gluon/contrib/login_methods/gae_google_account.py b/gluon/contrib/login_methods/gae_google_account.py index 2d7c2375..9559b42a 100644 --- a/gluon/contrib/login_methods/gae_google_account.py +++ b/gluon/contrib/login_methods/gae_google_account.py @@ -36,3 +36,4 @@ class GaeGoogleAccount(object): return dict(nickname=user.nickname(), email=user.email(), user_id=user.user_id(), source="google account") + diff --git a/gluon/contrib/login_methods/ldap_auth.py b/gluon/contrib/login_methods/ldap_auth.py index 1df9b3b0..2eb76bcf 100644 --- a/gluon/contrib/login_methods/ldap_auth.py +++ b/gluon/contrib/login_methods/ldap_auth.py @@ -634,3 +634,4 @@ def ldap_auth(server='ldap', port=None, if filterstr[0] == '(' and filterstr[-1] == ')': # rfc4515 syntax filterstr = filterstr[1:-1] # parens added again where used return ldap_auth_aux + diff --git a/gluon/contrib/login_methods/linkedin_account.py b/gluon/contrib/login_methods/linkedin_account.py index b97cab97..f16deadd 100644 --- a/gluon/contrib/login_methods/linkedin_account.py +++ b/gluon/contrib/login_methods/linkedin_account.py @@ -49,3 +49,4 @@ class LinkedInAccount(object): username = profile.id) + diff --git a/gluon/contrib/login_methods/loginza.py b/gluon/contrib/login_methods/loginza.py index 2a665e42..a54e3ca9 100644 --- a/gluon/contrib/login_methods/loginza.py +++ b/gluon/contrib/login_methods/loginza.py @@ -110,3 +110,4 @@ class Loginza(object): SCRIPT(_src="https://s3-eu-west-1.amazonaws.com/s1.loginza.ru/js/widget.js", _type="text/javascript")) return form + diff --git a/gluon/contrib/login_methods/motp_auth.py b/gluon/contrib/login_methods/motp_auth.py index a776b3e4..8d2bfa70 100644 --- a/gluon/contrib/login_methods/motp_auth.py +++ b/gluon/contrib/login_methods/motp_auth.py @@ -6,24 +6,24 @@ from gluon.dal import DAL def motp_auth(db=DAL('sqlite://storage.sqlite'), time_offset=60): - + """ - motp allows you to login with a one time password(OTP) generated on a motp client, + motp allows you to login with a one time password(OTP) generated on a motp client, motp clients are available for practically all platforms. to know more about OTP visit http://en.wikipedia.org/wiki/One-time_password to know more visit http://motp.sourceforge.net - - + + Written by Madhukar R Pai (madspai@gmail.com) License : MIT or GPL v2 - + thanks and credits to the web2py community - + to use motp_auth: motp_auth.py has to be located in gluon/contrib/login_methods/ folder first auth_user has to have 2 extra fields - motp_secret and motp_pin for that define auth like shown below: - + ## after auth = Auth(db) db.define_table( auth.settings.table_user_name, @@ -42,7 +42,7 @@ def motp_auth(db=DAL('sqlite://storage.sqlite'), writable=False, readable=False, default=''), Field('registration_id', length=512, # required writable=False, readable=False, default='')) - + ##validators custom_auth_table = db[auth.settings.table_user_name] # get the custom_auth_table custom_auth_table.first_name.requires = \ @@ -53,22 +53,22 @@ def motp_auth(db=DAL('sqlite://storage.sqlite'), custom_auth_table.email.requires = [ IS_EMAIL(error_message=auth.messages.invalid_email), IS_NOT_IN_DB(db, custom_auth_table.email)] - + auth.settings.table_user = custom_auth_table # tell auth to use custom_auth_table ## before auth.define_tables() - - ##after that: - + + ##after that: + from gluon.contrib.login_methods.motp_auth import motp_auth auth.settings.login_methods.append(motp_auth(db=db)) - + ##Instructions for using MOTP - after configuring motp for web2py, Install a MOTP client on your phone (android,IOS, java, windows phone, etc) - - initialize the motp client (to reset a motp secret type in #**#), + - initialize the motp client (to reset a motp secret type in #**#), During user creation enter the secret generated during initialization into the motp_secret field in auth_user and similarly enter a pre-decided pin into the motp_pin - done.. to login, just generate a fresh OTP by typing in the pin and use the OTP as password - + ###To Dos### - both motp_secret and pin are stored in plain text! need to have some way of encrypting - web2py stores the password in db on successful login (should not happen) @@ -85,7 +85,7 @@ def motp_auth(db=DAL('sqlite://storage.sqlite'), hash = md5(to_hash).hexdigest()[:6] if otp == hash: return True return False - + def motp_auth_aux(email, password, db=db, @@ -102,3 +102,4 @@ def motp_auth(db=DAL('sqlite://storage.sqlite'), else: return False return False return motp_auth_aux + diff --git a/gluon/contrib/login_methods/oauth10a_account.py b/gluon/contrib/login_methods/oauth10a_account.py index fe388dde..534a7582 100644 --- a/gluon/contrib/login_methods/oauth10a_account.py +++ b/gluon/contrib/login_methods/oauth10a_account.py @@ -188,3 +188,4 @@ class OAuthAccount(object): + diff --git a/gluon/contrib/login_methods/oauth20_account.py b/gluon/contrib/login_methods/oauth20_account.py index 354fa9ba..8d740499 100644 --- a/gluon/contrib/login_methods/oauth20_account.py +++ b/gluon/contrib/login_methods/oauth20_account.py @@ -66,7 +66,7 @@ class OAuthAccount(object): if not self.accessToken(): return None - + if not self.graph: self.graph = GraphAPI((self.accessToken())) @@ -117,7 +117,7 @@ server for requests. It can be used for the optional"scope" parameters for Face """ Build the url opener for managing HTTP Basic Athentication """ - # Create an OpenerDirector with support + # Create an OpenerDirector with support # for Basic HTTP Authentication... auth_handler = urllib2.HTTPBasicAuthHandler() @@ -172,7 +172,7 @@ server for requests. It can be used for the optional"scope" parameters for Face if current.session.token.has_key('expires_in'): exps = 'expires_in' elif current.session.token.has_key('expires'): - exps = 'expires' + exps = 'expires' else: exps = None current.session.token['expires'] = exps and \ @@ -185,7 +185,7 @@ server for requests. It can be used for the optional"scope" parameters for Face current.session.token = None return None - def __init__(self, g=None, + def __init__(self, g=None, client_id=None, client_secret=None, auth_url=None, token_url=None, **args): """ @@ -215,7 +215,7 @@ server for requests. It can be used for the optional"scope" parameters for Face def get_user(self): """ Override this method by sublcassing the class. - + """ if not current.session.token: return None return dict(first_name = 'Pinco', @@ -274,3 +274,4 @@ server for requests. It can be used for the optional"scope" parameters for Face return current.session.code return None + diff --git a/gluon/contrib/login_methods/openid_auth.py b/gluon/contrib/login_methods/openid_auth.py index d754e5e4..a2c22633 100644 --- a/gluon/contrib/login_methods/openid_auth.py +++ b/gluon/contrib/login_methods/openid_auth.py @@ -630,3 +630,4 @@ class Web2pyStore(OpenIDStore): return self.cleanupNonces(), self.cleanupAssociations() + diff --git a/gluon/contrib/login_methods/pam_auth.py b/gluon/contrib/login_methods/pam_auth.py index a8a59523..31c343e0 100644 --- a/gluon/contrib/login_methods/pam_auth.py +++ b/gluon/contrib/login_methods/pam_auth.py @@ -20,3 +20,4 @@ def pam_auth(): return pam_auth_aux + diff --git a/gluon/contrib/login_methods/rpx_account.py b/gluon/contrib/login_methods/rpx_account.py index 46837cf5..34688a69 100644 --- a/gluon/contrib/login_methods/rpx_account.py +++ b/gluon/contrib/login_methods/rpx_account.py @@ -53,12 +53,12 @@ class RPXAccount(object): self.prompt = prompt self.on_login_failure = on_login_failure self.mappings = Storage() - + dn = {'givenName':'','familyName':''} self.mappings.Facebook = lambda profile, dn=dn:\ dict(registration_id = profile.get("identifier",""), username = profile.get("preferredUsername",""), - email = profile.get("email",""), + email = profile.get("email",""), first_name = profile.get("name",dn).get("givenName",""), last_name = profile.get("name",dn).get("familyName","")) self.mappings.Google = lambda profile, dn=dn:\ @@ -125,3 +125,4 @@ def use_janrain(auth,filename='private/janrain.key',**kwargs): ['register','change_password','request_reset_password'] auth.settings.login_form = RPXAccount( request, api_key=key,domain=domain, url = url,**kwargs) + diff --git a/gluon/contrib/login_methods/x509_auth.py b/gluon/contrib/login_methods/x509_auth.py index 09c3e922..36db643d 100644 --- a/gluon/contrib/login_methods/x509_auth.py +++ b/gluon/contrib/login_methods/x509_auth.py @@ -53,7 +53,7 @@ class X509Auth(object): # cn = self.subject.cn self.subject = Storage(filter(None, map(lambda x: - (x,map(lambda y: + (x,map(lambda y: y.get_data().as_text(), subject.get_entries_by_nid(subject.nid[x]))), subject.nid.keys()))) @@ -63,7 +63,7 @@ class X509Auth(object): def login_form(self, **args): raise HTTP(403,'Login not allowed. No valid x509 crentials') - + def login_url(self, next="/"): raise HTTP(403,'Login not allowed. No valid x509 crentials') @@ -102,3 +102,4 @@ class X509Auth(object): return profile + diff --git a/gluon/contrib/markmin/markmin2html.py b/gluon/contrib/markmin/markmin2html.py index 162dd6d1..8e6431bc 100755 --- a/gluon/contrib/markmin/markmin2html.py +++ b/gluon/contrib/markmin/markmin2html.py @@ -801,7 +801,7 @@ def render(text, # this is experimental @{function/args} # turns into a digitally signed URL def u1(match,URL=URL): - a,c,f,args = match.group('a','c','f','args') + a,c,f,args = match.group('a','c','f','args') return URL(a=a or None,c=c or None,f = f or None, args=args.split('/'), scheme=True, host=True) text = regex_URL.sub(u1,text) diff --git a/gluon/contrib/memdb.py b/gluon/contrib/memdb.py index ee25566d..ae2189aa 100644 --- a/gluon/contrib/memdb.py +++ b/gluon/contrib/memdb.py @@ -911,3 +911,4 @@ if __name__ == '__main__': + diff --git a/gluon/contrib/pam.py b/gluon/contrib/pam.py index 57b9e5be..4622b7cc 100644 --- a/gluon/contrib/pam.py +++ b/gluon/contrib/pam.py @@ -127,3 +127,4 @@ if __name__ == "__main__": + diff --git a/gluon/contrib/pbkdf2.py b/gluon/contrib/pbkdf2.py index c751b4be..a58a9dd1 100644 --- a/gluon/contrib/pbkdf2.py +++ b/gluon/contrib/pbkdf2.py @@ -129,3 +129,4 @@ def test(): if __name__ == '__main__': test() + diff --git a/gluon/contrib/populate.py b/gluon/contrib/populate.py index efd90670..38760f00 100644 --- a/gluon/contrib/populate.py +++ b/gluon/contrib/populate.py @@ -171,3 +171,4 @@ if __name__ == '__main__': + diff --git a/gluon/contrib/pyfpdf.py b/gluon/contrib/pyfpdf.py index 26fc2940..1cc8c8f0 100644 --- a/gluon/contrib/pyfpdf.py +++ b/gluon/contrib/pyfpdf.py @@ -9,3 +9,4 @@ from fpdf import * # import warnings # warnings.warn("pyfpdf package name is deprecated, please use fpdf instead") + diff --git a/gluon/contrib/qdb.py b/gluon/contrib/qdb.py index bb6ecc0e..a23038d2 100644 --- a/gluon/contrib/qdb.py +++ b/gluon/contrib/qdb.py @@ -964,3 +964,4 @@ if __name__ == '__main__': + diff --git a/gluon/contrib/redis_cache.py b/gluon/contrib/redis_cache.py index 3a1a47fa..2f2366d9 100644 --- a/gluon/contrib/redis_cache.py +++ b/gluon/contrib/redis_cache.py @@ -167,3 +167,4 @@ class RedisClient(object): + diff --git a/gluon/contrib/rss2.py b/gluon/contrib/rss2.py index 8f1a601e..47fde9d2 100644 --- a/gluon/contrib/rss2.py +++ b/gluon/contrib/rss2.py @@ -592,3 +592,4 @@ if __name__ == '__main__': + diff --git a/gluon/contrib/shell.py b/gluon/contrib/shell.py index d40400b3..227a1aec 100755 --- a/gluon/contrib/shell.py +++ b/gluon/contrib/shell.py @@ -270,3 +270,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/simplejsonrpc.py b/gluon/contrib/simplejsonrpc.py index 865bb1c4..5a29b5b8 100644 --- a/gluon/contrib/simplejsonrpc.py +++ b/gluon/contrib/simplejsonrpc.py @@ -151,3 +151,4 @@ if __name__ == "__main__": + diff --git a/gluon/contrib/sms_utils.py b/gluon/contrib/sms_utils.py index 29a50226..5777661e 100644 --- a/gluon/contrib/sms_utils.py +++ b/gluon/contrib/sms_utils.py @@ -116,3 +116,4 @@ def sms_email(number,provider): + diff --git a/gluon/contrib/spreadsheet.py b/gluon/contrib/spreadsheet.py index b343eb31..b13dced0 100644 --- a/gluon/contrib/spreadsheet.py +++ b/gluon/contrib/spreadsheet.py @@ -879,3 +879,4 @@ if __name__ == '__main__': print s['c'].computed_value + diff --git a/gluon/contrib/stripe.py b/gluon/contrib/stripe.py index fc1a12b9..dbde9117 100644 --- a/gluon/contrib/stripe.py +++ b/gluon/contrib/stripe.py @@ -66,3 +66,4 @@ if __name__=='__main__': + diff --git a/gluon/contrib/taskbar_widget.py b/gluon/contrib/taskbar_widget.py index 8009c93f..8f9cba9e 100644 --- a/gluon/contrib/taskbar_widget.py +++ b/gluon/contrib/taskbar_widget.py @@ -247,3 +247,4 @@ class TaskBarIcon: + diff --git a/gluon/contrib/timecollect.py b/gluon/contrib/timecollect.py index 229ac2e5..601b7fb2 100644 --- a/gluon/contrib/timecollect.py +++ b/gluon/contrib/timecollect.py @@ -95,3 +95,4 @@ if __name__=='__main__': print(t.getReportText(orderByCost=False)) + diff --git a/gluon/contrib/user_agent_parser.py b/gluon/contrib/user_agent_parser.py index c326e92c..e84f4892 100644 --- a/gluon/contrib/user_agent_parser.py +++ b/gluon/contrib/user_agent_parser.py @@ -520,3 +520,4 @@ class mobilize(object): + diff --git a/gluon/custom_import.py b/gluon/custom_import.py index f31d3630..afcaff33 100644 --- a/gluon/custom_import.py +++ b/gluon/custom_import.py @@ -329,3 +329,4 @@ class _Web2pyDateTrackerImporter(_Web2pyImporter, _DateTrackerImporter): + diff --git a/gluon/dal.py b/gluon/dal.py index 0d34e0b3..7c63d6d9 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -6932,7 +6932,7 @@ def index(): tablename, *fields, **args - ): + ): if not isinstance(tablename,str): raise SyntaxError, "missing table name" elif tablename.startswith('_') or hasattr(self,tablename) or \ @@ -6946,7 +6946,7 @@ def index(): invalid_args = [key for key in args if not key in TABLE_ARGS] if invalid_args: raise SyntaxError, 'invalid table "%s" attributes: %s' \ - % (tablename,invalid_args) + % (tablename,invalid_args) if self._lazy_tables and not tablename in self._LAZY_TABLES: self._LAZY_TABLES[tablename] = (tablename,fields,args) table = None @@ -6985,7 +6985,7 @@ def index(): sql_locker.release() else: table._dbt = None - on_define = args.get('on_define',None) + on_define = args.get('on_define',None) if on_define: on_define(table) return table @@ -7065,7 +7065,7 @@ def index(): to or instead of including Field objects, or it can be just a single table (not in a list). In that case, the Field objects will be extracted from the table(s). - + The field names will be extracted from the Field objects, or optionally, a list of field names can be provided (in tablename.fieldname format) via the "colnames" argument. Note, the fields and colnames must be in @@ -7100,7 +7100,7 @@ def index(): else: extracted_fields.append(field) if not colnames: - colnames = ['%s.%s' % (f.tablename, f.name) + colnames = ['%s.%s' % (f.tablename, f.name) for f in extracted_fields] data = self._adapter.parse( data, fields=extracted_fields, colnames=colnames) @@ -7498,7 +7498,7 @@ class Table(dict): 'value must be a dictionary: %s' % value dict.__setitem__(self, str(key), value) - def __getattr__(self, key): + def __getattr__(self, key): return self[key] def __delitem__(self, key): @@ -9153,3 +9153,4 @@ if __name__ == '__main__': + diff --git a/gluon/debug.py b/gluon/debug.py index 6cb29b7f..b638cc12 100644 --- a/gluon/debug.py +++ b/gluon/debug.py @@ -192,3 +192,4 @@ gluon.main.global_settings.debugging = True + diff --git a/gluon/decoder.py b/gluon/decoder.py index 713a2c75..4eecf8ab 100644 --- a/gluon/decoder.py +++ b/gluon/decoder.py @@ -78,3 +78,4 @@ def decoder(buffer): + diff --git a/gluon/fileutils.py b/gluon/fileutils.py index f66c5fb7..fd23c604 100644 --- a/gluon/fileutils.py +++ b/gluon/fileutils.py @@ -397,3 +397,4 @@ def abspath(*relpath, **base): return os.path.join(global_settings.applications_parent, path) + diff --git a/gluon/globals.py b/gluon/globals.py index 23723731..7bf41549 100644 --- a/gluon/globals.py +++ b/gluon/globals.py @@ -101,7 +101,7 @@ class Request(Storage): self.is_https = False self.is_local = False self.global_settings = settings.global_settings - + def compute_uuid(self): self.uuid = '%s/%s.%s.%s' % ( self.application, @@ -691,3 +691,4 @@ class Session(Storage): + diff --git a/gluon/highlight.py b/gluon/highlight.py index 93c810c4..59332571 100644 --- a/gluon/highlight.py +++ b/gluon/highlight.py @@ -348,3 +348,4 @@ if __name__ == '__main__': + diff --git a/gluon/html.py b/gluon/html.py index 8522b7a5..b758c597 100644 --- a/gluon/html.py +++ b/gluon/html.py @@ -962,7 +962,7 @@ class DIV(XmlComponent): >>> for c in a.elements('input, select, textarea'): c['_disabled'] = 'disabled' >>> a.xml() '
    ' - + Elements that are matched can also be replaced or removed by specifying a "replace" argument (note, a list of the original matching elements is still returned as usual). @@ -2503,3 +2503,4 @@ if __name__ == '__main__': + diff --git a/gluon/http.py b/gluon/http.py index bf8f55ef..c4389b9e 100644 --- a/gluon/http.py +++ b/gluon/http.py @@ -142,3 +142,4 @@ def redirect(location, how=303, client_side=False): + diff --git a/gluon/import_all.py b/gluon/import_all.py index 01c4e8c6..46f231b8 100644 --- a/gluon/import_all.py +++ b/gluon/import_all.py @@ -113,3 +113,4 @@ for module in base_modules + contributed_modules: + diff --git a/gluon/languages.py b/gluon/languages.py index 24f41a49..2c8231d5 100644 --- a/gluon/languages.py +++ b/gluon/languages.py @@ -939,3 +939,4 @@ if __name__ == '__main__': doctest.testmod() + diff --git a/gluon/main.py b/gluon/main.py index 5aa0f15a..29a17992 100644 --- a/gluon/main.py +++ b/gluon/main.py @@ -854,3 +854,4 @@ class HttpServer(object): + diff --git a/gluon/messageboxhandler.py b/gluon/messageboxhandler.py index 17184a57..d22ce719 100644 --- a/gluon/messageboxhandler.py +++ b/gluon/messageboxhandler.py @@ -14,3 +14,4 @@ class MessageBoxHandler(logging.Handler): msg = self.format(record) tkMessageBox.showinfo('info1', msg) + diff --git a/gluon/myregex.py b/gluon/myregex.py index 04b48b73..9808a8cb 100644 --- a/gluon/myregex.py +++ b/gluon/myregex.py @@ -32,3 +32,4 @@ regex_extend = re.compile(\ + diff --git a/gluon/newcron.py b/gluon/newcron.py index ff917551..a238b8a8 100644 --- a/gluon/newcron.py +++ b/gluon/newcron.py @@ -343,3 +343,4 @@ def crondance(applications_parent, ctype='soft', startup=False, apps=None): + diff --git a/gluon/portalocker.py b/gluon/portalocker.py index 36c94547..f516e73e 100644 --- a/gluon/portalocker.py +++ b/gluon/portalocker.py @@ -151,3 +151,4 @@ if __name__=='__main__': + diff --git a/gluon/reserved_sql_keywords.py b/gluon/reserved_sql_keywords.py index 713ac48d..698768c8 100644 --- a/gluon/reserved_sql_keywords.py +++ b/gluon/reserved_sql_keywords.py @@ -1717,3 +1717,4 @@ ADAPTERS['all'] = reduce(lambda a,b:a.union(b),(x for x in ADAPTERS.values())) + diff --git a/gluon/restricted.py b/gluon/restricted.py index 770fe48e..74f3b34c 100644 --- a/gluon/restricted.py +++ b/gluon/restricted.py @@ -308,3 +308,4 @@ def snapshot(info=None, context=5, code=None, environment=None): + diff --git a/gluon/rewrite.py b/gluon/rewrite.py index 14bb1dc6..d7faf450 100644 --- a/gluon/rewrite.py +++ b/gluon/rewrite.py @@ -476,7 +476,7 @@ def load_routers(all_apps): def regex_uri(e, regexes, tag, default=None): "filter incoming URI against a list of regexes" path = e['PATH_INFO'] - host = e.get('http_host', e.get('SERVER_NAME','localhost')).lower() + host = e.get('http_host', e.get('SERVER_NAME','localhost')).lower() i = host.find(':') if i > 0: host = host[:i] @@ -1311,3 +1311,4 @@ def get_effective_router(appname): + diff --git a/gluon/rocket.py b/gluon/rocket.py index a091d8d2..12fd8dc6 100644 --- a/gluon/rocket.py +++ b/gluon/rocket.py @@ -2085,3 +2085,4 @@ if __name__=='__main__': + diff --git a/gluon/sanitizer.py b/gluon/sanitizer.py index 5e88f6e4..fa5ffc4e 100644 --- a/gluon/sanitizer.py +++ b/gluon/sanitizer.py @@ -228,3 +228,4 @@ def sanitize(text, permitted_tags=[ + diff --git a/gluon/scheduler.py b/gluon/scheduler.py index 1875fe7e..9e585d39 100644 --- a/gluon/scheduler.py +++ b/gluon/scheduler.py @@ -869,3 +869,4 @@ def main(): if __name__=='__main__': main() + diff --git a/gluon/serializers.py b/gluon/serializers.py index 8af80157..8934c9b2 100644 --- a/gluon/serializers.py +++ b/gluon/serializers.py @@ -117,3 +117,4 @@ def rss(feed): + diff --git a/gluon/settings.py b/gluon/settings.py index 19617882..3715edc6 100644 --- a/gluon/settings.py +++ b/gluon/settings.py @@ -34,3 +34,4 @@ global_settings.is_jython = 'java' in sys.platform.lower() or \ str(sys.copyright).find('Jython') > 0 + diff --git a/gluon/shell.py b/gluon/shell.py index 50f6d9f3..011ecb6d 100644 --- a/gluon/shell.py +++ b/gluon/shell.py @@ -431,3 +431,4 @@ if __name__ == '__main__': + diff --git a/gluon/sql.py b/gluon/sql.py index c9304adb..1a43f4cc 100644 --- a/gluon/sql.py +++ b/gluon/sql.py @@ -9,3 +9,4 @@ from dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, drivers, B + diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index 0436ce0d..b3df0aee 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -239,7 +239,7 @@ class ListWidget(StringWidget): else: _class = 'string' requires = field.requires if isinstance(field.requires, (IS_NOT_EMPTY, IS_LIST_OF)) else None attributes['_style'] = 'list-style:none' - items=[LI(INPUT(_id=_id, _class=_class, _name=_name, + items=[LI(INPUT(_id=_id, _class=_class, _name=_name, value=v, hideerror=True, requires=requires), **attributes) for v in value or ['']] script=SCRIPT(""" @@ -2669,3 +2669,4 @@ class ExporterXML(ExportClass): + diff --git a/gluon/storage.py b/gluon/storage.py index 1b6da5c1..ce47381c 100644 --- a/gluon/storage.py +++ b/gluon/storage.py @@ -172,7 +172,7 @@ class Messages(Settings): class FastStorage(dict): """ - Eventually this should replace class Storage but causes memory leak + Eventually this should replace class Storage but causes memory leak because of http://bugs.python.org/issue1469629 >>> s = FastStorage() @@ -205,7 +205,7 @@ class FastStorage(dict): >>> s['a'] >>> s['b'] """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs): dict.__init__(self, *args, **kwargs) self.__dict__ = self def __getattr__(self,key): @@ -269,3 +269,4 @@ if __name__ == '__main__': + diff --git a/gluon/streamer.py b/gluon/streamer.py index 2a25aa52..a46ae7cf 100644 --- a/gluon/streamer.py +++ b/gluon/streamer.py @@ -112,3 +112,4 @@ def stream_file_or_304_or_206( + diff --git a/gluon/template.py b/gluon/template.py index 06d01023..9f147895 100644 --- a/gluon/template.py +++ b/gluon/template.py @@ -913,7 +913,7 @@ def render(content = "hello world", # Add it to the context so we can use it. if not 'NOESCAPE' in context: context['NOESCAPE'] = XML - + # save current response class if context and 'response' in context: old_response_body = context['response'].body @@ -926,7 +926,7 @@ def render(content = "hello world", if not content and not stream and not filename: raise SyntaxError, "Must specify a stream or filename or content" - # Here for legacy purposes, probably can be reduced to + # Here for legacy purposes, probably can be reduced to # something more simple. close_stream = False if not stream: @@ -963,3 +963,4 @@ if __name__ == '__main__': + diff --git a/gluon/tools.py b/gluon/tools.py index 25f48d07..ce086c9d 100644 --- a/gluon/tools.py +++ b/gluon/tools.py @@ -1410,9 +1410,9 @@ class Auth(object): passfield = settings.password_field extra_fields = settings.extra_fields.get( settings.table_user_name,[])+signature_list - if username or settings.cas_provider: + if username or settings.cas_provider: is_unique_username = \ - [IS_MATCH('[\w\.\-]+'), + [IS_MATCH('[\w\.\-]+'), IS_NOT_IN_DB(db,'%s.username' % settings.table_user_name)] if not settings.username_case_sensitive: is_unique_username.insert(1,IS_LOWER()) @@ -1584,7 +1584,7 @@ class Auth(object): 'request_reset_password'] from gluon.contrib.login_methods.cas_auth import CasAuth maps = settings.cas_maps - if not maps: + if not maps: table_user = self.table_user() maps = dict((name,lambda v,n=name:v.get(n,None)) for name in \ table_user.fields if name!='id' \ @@ -2476,7 +2476,7 @@ class Auth(object): separator=self.settings.label_separator ) if captcha: - addrow(form, captcha.label, captcha, captcha.comment, self.settings.formstyle,'captcha__row') + addrow(form, captcha.label, captcha, captcha.comment, self.settings.formstyle,'captcha__row') if form.accepts(request, session, formname='reset_password', dbio=False, onvalidation=onvalidation, @@ -3133,7 +3133,7 @@ class Auth(object): archive_table_name, Field(current_record,table), *[field.clone(unique=False) for field in table]) - archive_table = table._db[archive_table_name] + archive_table = table._db[archive_table_name] new_record = {current_record:form.vars.id} for fieldname in archive_table.fields: if not fieldname in ['id',current_record]: @@ -4484,7 +4484,7 @@ class Wiki(object): def __init__(self,auth,env=None,render='markmin', manage_permissions=False,force_prefix=''): self.env = env or {} - self.env['component'] = Wiki.component + self.env['component'] = Wiki.component if render == 'markmin': render=self.markmin_render self.auth = auth if self.auth.user: @@ -4536,7 +4536,7 @@ class Wiki(object): not 'wiki_editor' in auth.user_groups.values(): group = db.auth_group(role='wiki_editor') gid = group.id if group else db.auth_group.insert(role='wiki_editor') - auth.add_membership(gid) + auth.add_membership(gid) # WIKI ACCESS POLICY def not_authorized(self,page=None): raise HTTP(401) @@ -4604,7 +4604,7 @@ class Wiki(object): def fix_hostname(self,body): return body.replace('://HOSTNAME','://%s' % self.host) - + def read(self,slug): if slug in '_cloud': return self.cloud() elif slug in '_search': return self.search() @@ -4674,7 +4674,7 @@ class Wiki(object): def editmedia(self,slug): auth = self.auth - db = auth.db + db = auth.db page = db.wiki_page(slug=slug) if not (page and self.can_edit(page)): return self.not_authorized(page) self.auth.db.wiki_media.id.represent = lambda id,row:\ @@ -4739,9 +4739,9 @@ class Wiki(object): for match in regex.finditer(self.fix_hostname(menu_page.body)): base = match.group('base').replace(' ','') title = match.group('title') - link = match.group('link') + link = match.group('link') if link.startswith('@'): - items = link[1:].split('/') + items = link[2:].split('/') if len(items)>3: link = URL(a=items[0] or None,c=items[1] or None,f=items[2] or None, args=items[3:]) parent = tree.get(base[1:],tree['']) @@ -4863,3 +4863,4 @@ if __name__ == '__main__': + diff --git a/gluon/utf8.py b/gluon/utf8.py index 794489af..1af3fe15 100644 --- a/gluon/utf8.py +++ b/gluon/utf8.py @@ -654,3 +654,4 @@ if __name__ == '__main__': doctests() + diff --git a/gluon/utils.py b/gluon/utils.py index 963d89a0..92e58010 100644 --- a/gluon/utils.py +++ b/gluon/utils.py @@ -186,3 +186,4 @@ def is_valid_ip_address(address): + diff --git a/gluon/validators.py b/gluon/validators.py index 27fae504..eebf54ef 100644 --- a/gluon/validators.py +++ b/gluon/validators.py @@ -3153,3 +3153,4 @@ if __name__ == '__main__': + diff --git a/gluon/widget.py b/gluon/widget.py index a2b84ac2..13114466 100644 --- a/gluon/widget.py +++ b/gluon/widget.py @@ -929,10 +929,10 @@ def console(): scheduler.append(opt.split(':')) options.scheduler = ','.join([app[0] for app in scheduler]) options.scheduler_groups = scheduler - + if options.numthreads is not None and options.minthreads is None: - options.minthreads = options.numthreads # legacy - + options.minthreads = options.numthreads # legacy + if not options.cronjob: # If we have the applications package or if we should upgrade if not os.path.exists('applications/__init__.py'): @@ -1205,3 +1205,4 @@ end tell + diff --git a/gluon/winservice.py b/gluon/winservice.py index aa762a15..48b58e91 100644 --- a/gluon/winservice.py +++ b/gluon/winservice.py @@ -172,3 +172,4 @@ if __name__ == '__main__': + diff --git a/gluon/xmlrpc.py b/gluon/xmlrpc.py index 24fd8f9c..6bf931cb 100644 --- a/gluon/xmlrpc.py +++ b/gluon/xmlrpc.py @@ -25,3 +25,4 @@ def handler(request, response, methods): + diff --git a/isapiwsgihandler.py b/isapiwsgihandler.py index 9a5c891a..28973d2d 100644 --- a/isapiwsgihandler.py +++ b/isapiwsgihandler.py @@ -37,3 +37,4 @@ if __name__=='__main__': + diff --git a/modpythonhandler.py b/modpythonhandler.py index add46cd3..4ed135f1 100755 --- a/modpythonhandler.py +++ b/modpythonhandler.py @@ -226,3 +226,4 @@ def handler(req): + diff --git a/options_std.py b/options_std.py index feb0a48f..85cd071b 100644 --- a/options_std.py +++ b/options_std.py @@ -31,3 +31,4 @@ shutdown_timeout = 5 folder = os.getcwd() extcron = None nocron = None + diff --git a/router.example.py b/router.example.py index a98b5436..fef9737c 100644 --- a/router.example.py +++ b/router.example.py @@ -213,3 +213,4 @@ if __name__ == '__main__': + diff --git a/routes.example.py b/routes.example.py index c48bd282..ea7a8142 100644 --- a/routes.example.py +++ b/routes.example.py @@ -174,3 +174,4 @@ if __name__ == '__main__': + diff --git a/scgihandler.py b/scgihandler.py index dbadb1d4..e0dd6593 100755 --- a/scgihandler.py +++ b/scgihandler.py @@ -75,3 +75,4 @@ SCGIServer(application, port=4000).enable_sighandler().run() + diff --git a/setup.py b/setup.py index 25c4f173..3dbc628e 100644 --- a/setup.py +++ b/setup.py @@ -81,3 +81,4 @@ if __name__ == '__main__': + diff --git a/setup_app.py b/setup_app.py index 67e0da5b..cb57c8fc 100755 --- a/setup_app.py +++ b/setup_app.py @@ -56,3 +56,4 @@ setup(app=['web2py.py'], + diff --git a/setup_exe.py b/setup_exe.py index dda70ca0..9b6e88e0 100755 --- a/setup_exe.py +++ b/setup_exe.py @@ -186,3 +186,4 @@ print "Enjoy web2py " +web2py_version_line + diff --git a/setup_exe_2.6.py b/setup_exe_2.6.py index fcb49525..cec07199 100644 --- a/setup_exe_2.6.py +++ b/setup_exe_2.6.py @@ -168,3 +168,4 @@ print "Enjoy web2py " +web2py_version_line + diff --git a/web2py.py b/web2py.py index 3446da0a..fbd402e9 100755 --- a/web2py.py +++ b/web2py.py @@ -29,3 +29,4 @@ if __name__ == '__main__': + diff --git a/wsgihandler.py b/wsgihandler.py index 590f2b46..85368eb3 100644 --- a/wsgihandler.py +++ b/wsgihandler.py @@ -46,3 +46,4 @@ if SOFTCRON: + From 123832e528ce4ee0d1b0b1cdaac0975c81e0d264 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Sat, 25 Aug 2012 15:08:18 -0500 Subject: [PATCH 51/53] R-2.0.1-rc3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 296d274f..341d8827 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-25 11:29:08) dev +Version 2.00.0 (2012-08-25 15:08:15) dev From 35d728e0c91485066814d8fc7ac553869e9c08a6 Mon Sep 17 00:00:00 2001 From: mdipierro Date: Sat, 25 Aug 2012 15:50:01 -0500 Subject: [PATCH 52/53] typo in Storage, thanks Michele --- VERSION | 2 +- gluon/storage.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index 341d8827..7fc9260a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-25 15:08:15) dev +Version 2.00.0 (2012-08-25 15:49:58) dev diff --git a/gluon/storage.py b/gluon/storage.py index ce47381c..7ed1ed82 100644 --- a/gluon/storage.py +++ b/gluon/storage.py @@ -47,7 +47,7 @@ class Storage(dict): def __getitem__(self, key): return dict.get(self, key, None) def __repr__(self): - return '' + dict.__repr__(self) + return '' % dict.__repr__(self) def __getstate__(self): return dict(self) def __setstate__(self,values): From 71507f0ce0c91846ea8582a147992eaf851a2e1c Mon Sep 17 00:00:00 2001 From: mdipierro Date: Sat, 25 Aug 2012 16:19:50 -0500 Subject: [PATCH 53/53] major optimization in Storage, Table, Row (2x), thanks Michele --- VERSION | 2 +- gluon/dal.py | 20 ++++++++++---------- gluon/storage.py | 20 ++++++++++++-------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 7fc9260a..012b7f9c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.00.0 (2012-08-25 15:49:58) dev +Version 2.00.0 (2012-08-25 16:19:46) dev diff --git a/gluon/dal.py b/gluon/dal.py index 7c63d6d9..97088915 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -6289,11 +6289,9 @@ class Row(dict): this is only used to store a Row """ - def __getattr__(self, key): - return self[key] - - def __setattr__(self, key, value): - self[key] = value + __setattr__ = dict.__setitem__ + __getattr__ = dict.__getitem__ + __delattr__ = dict.__delitem__ def __getitem__(self, key): key=str(key) @@ -6307,8 +6305,10 @@ class Row(dict): key = m.group(2) return dict.__getitem__(self, key) - def __call__(self,key): - return self.__getitem__(key) + __call__ = __getitem__ + + #def __call__(self,key): + # return self.__getitem__(key) def __setitem__(self, key, value): dict.__setitem__(self, str(key), value) @@ -7498,15 +7498,15 @@ class Table(dict): 'value must be a dictionary: %s' % value dict.__setitem__(self, str(key), value) - def __getattr__(self, key): - return self[key] + __getattr__ = __getitem__ def __delitem__(self, key): if isinstance(key, dict): query = self._build_query(key) if not self._db(query).delete(): raise SyntaxError, 'No such record: %s' % key - elif not str(key).isdigit() or not self._db(self._id == key).delete(): + elif not str(key).isdigit() or \ + not self._db(self._id == key).delete(): raise SyntaxError, 'No such record: %s' % key def __setattr__(self, key, value): diff --git a/gluon/storage.py b/gluon/storage.py index 7ed1ed82..50c2b9f8 100644 --- a/gluon/storage.py +++ b/gluon/storage.py @@ -38,14 +38,18 @@ class Storage(dict): >>> print o.a None """ - def __getattr__(self, key): - return dict.get(self, key, None) - def __setattr__(self, key, value): - self[key] = value - def __delattr__(self, key): - del self[key] - def __getitem__(self, key): - return dict.get(self, key, None) + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ + __getitem__ = dict.get + __getattr__ = dict.get + # def __getattr__(self, key): + # return dict.get(self, key, None) + # def __setattr__(self, key, value): + # self[key] = value + # def __getitem__(self, key): + # return dict.get(self, key, None) + # def __delattr__(self, key): + # del self[key] def __repr__(self): return '' % dict.__repr__(self) def __getstate__(self):