text:
import imp
import os
import marshal
import struct
import sys
from cStringIO import StringIO

from compiler import ast, parse, walk, syntax
from compiler import pyassem, misc, future, symbols
from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,
     CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION,
     CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT)
from compiler.pyassem import TupleArg

# XXX The version-specific code can go, since this code only works with 2.x.
# Do we have Python 1.x or Python 2.x?
try:
    VERSION = sys.version_info[0]
except AttributeError:
    VERSION = 1

callfunc_opcode_info = {
    # (Have *args, Have **args) : opcode
    (0,0) : "CALL_FUNCTION",
    (1,0) : "CALL_FUNCTION_VAR",
    (0,1) : "CALL_FUNCTION_KW",
    (1,1) : "CALL_FUNCTION_VAR_KW",
}

LOOP = 1
EXCEPT = 2
TRY_FINALLY = 3
END_FINALLY = 4

def compileFile(filename, display=0):
    f = open(filename, 'U')
    buf = f.read()
    f.close()
    mod = Module(buf, filename)
    try:
        mod.compile(display)
    except SyntaxError:
        raise
    else:
        f = open(filename + "c", "wb")
        mod.dump(f)
        f.close()

def compile(source, filename, mode, flags=None, dont_inherit=None):
    """Replacement for builtin compile() function"""
    if flags is not None or dont_inherit is not None:
        raise RuntimeError, "not implemented yet"

    if mode == "single":
        gen = Interactive(source, filename)
    elif mode == "exec":
        gen = Module(source, filename)
    elif mode == "eval":
        gen = Expression(source, filename)
    else:
        raise ValueError("compile() 3rd arg must be 'exec' or "
                         "'eval' or 'single'")
    gen.compile()
    return gen.code

class AbstractCompileMode:

    mode = None # defined by subclass

    def __init__(self, source, filename):
        self.source = source
        self.filename = filename
        self.code = None

    def _get_tree(self):
        tree = parse(self.source, self.mode)
        misc.set_filename(self.filename, tree)
        syntax.check(tree)
        return tree

    def compile(self):
        pass # implemented by subclass

    def getCode(self):
        return self.code

class Expression(AbstractCompileMode):

    mode = "eval"

    def compile(self):
        tree = self._get_tree()
        gen = ExpressionCodeGenerator(tree)
        self.code = gen.getCode()

class Interactive(AbstractCompileMode):

    mode = "single"

    def compile(self):
        tree = self._get_tree()
        gen = InteractiveCodeGenerator(tree)
        self.code = gen.getCode()

class Module(AbstractCompileMode):

    mode = "exec"

    def compile(self, display=0):
        tree = self._get_tree()
        gen = ModuleCodeGenerator(tree)
        if display:
            import pprint
            print pprint.pprint(tree)
        self.code = gen.getCode()

    def dump(self, f):
        f.write(self.getPycHeader())
        marshal.dump(self.code, f)

    MAGIC = imp.get_magic()

    def getPycHeader(self):
        # compile.c uses marshal to write a long directly, with
        # calling the interface that would also generate a 1-byte code
        # to indicate the type of the value.  simplest way to get the
        # same effect is to call marshal and then skip the code.
        mtime = os.path.getmtime(self.filename)
        mtime = struct.pack('<i', mtime)
        return self.MAGIC + mtime

class LocalNameFinder:
    """Find local names in scope"""
    def __init__(self, names=()):
        self.names = misc.Set()
        self.globals = misc.Set()
        for name in names:
            self.names.add(name)

    # XXX list comprehensions and for loops

    def getLocals(self):
        for elt in self.globals.elements():
            if self.names.has_elt(elt):
                self.names.remove(elt)
        return self.names

    def visitDict(self, node):
        pass

    def visitGlobal(self, node):
        for name in node.names:
            self.globals.add(name)

    def visitFunction(self, node):
        self.names.add(node.name)

    def visitLambda(self, node):
        pass

    def visitImport(self, node):
        for name, alias in node.names:
            self.names.add(alias or name)

    def visitFrom(self, node):
        for name, alias in node.names:
            self.names.add(alias or name)

    def visitClass(self, node):
        self.names.add(node.name)

    def visitAssName(self, node):
        self.names.add(node.name)

def is_constant_false(node):
    if isinstance(node, ast.Const):
        if not node.value:
            return 1
    return 0

class CodeGenerator:
    """Defines basic code generator for Python bytecode

    This class is an abstract base class.  Concrete subclasses must
    define an __init__() that defines self.graph and then calls the
    __init__() defined in this class.

    The concrete class must also define the class attributes
    NameFinder, FunctionGen, and ClassGen.  These attributes can be
    defined in the initClass() method, which is a hook for
    initializing these methods after all the classes have been
    defined.
    """

    optimized = 0 # is namespace access optimized?
    __initialized = None
    class_name = None # provide default for instance variable

    def __init__(self):
        if self.__initialized is None:
            self.initClass()
            self.__class__.__initialized = 1
        self.checkClass()
        self.locals = misc.Stack()
        self.setups = misc.Stack()
        self.last_lineno = None
        self._setupGraphDelegation()
        self._div_op = "BINARY_DIVIDE"

        # XXX set flags based on future features
        futures = self.get_module().futures
        for feature in futures:
            if feature == "division":
                self.graph.setFlag(CO_FUTURE_DIVISION)
                self._div_op = "BINARY_TRUE_DIVIDE"
            elif feature == "absolute_import":
                self.graph.setFlag(CO_FUTURE_ABSIMPORT)
            elif feature == "with_statement":
                self.graph.setFlag(CO_FUTURE_WITH_STATEMENT)

    def initClass(self):
        """This method is called once for each class"""

    def checkClass(self):
        """Verify that class is constructed correctly"""
        try:
            assert hasattr(self, 'graph')
            assert getattr(self, 'NameFinder')
            assert getattr(self, 'FunctionGen')
            assert getattr(self, 'ClassGen')
        except AssertionError, msg:
            intro = "Bad class construction for %s" % self.__class__.__name__
            raise AssertionError, intro

    def _setupGraphDelegation(self):
        self.emit = self.graph.emit
        self.newBlock = self.graph.newBlock
        self.startBlock = self.graph.startBlock
        self.nextBlock = self.graph.nextBlock
        self.setDocstring = self.graph.setDocstring

    def getCode(self):
        """Return a code object"""
        return self.graph.getCode()

    def mangle(self, name):
        if self.class_name is not None:
            return misc.mangle(name, self.class_name)
        else:
            return name

    def parseSymbols(self, tree):
        s = symbols.SymbolVisitor()
        walk(tree, s)
        return s.scopes

    def get_module(self):
        raise RuntimeError, "should be implemented by subclasses"

    # Next five methods handle name access

    def isLocalName(self, name):
        return self.locals.top().has_elt(name)

    def storeName(self, name):
        self._nameOp('STORE', name)

    def loadName(self, name):
        self._nameOp('LOAD', name)

    def delName(self, name):
        self._nameOp('DELETE', name)

    def _nameOp(self, prefix, name):
        name = self.mangle(name)
        scope = self.scope.check_name(name)
        if scope == SC_LOCAL:
            if not self.optimized:
                self.emit(prefix + '_NAME', name)
            else:
                self.emit(prefix + '_FAST', name)
        elif scope == SC_GLOBAL:
            if not self.optimized:
                self.emit(prefix + '_NAME', name)
            else:
                self.emit(prefix + '_GLOBAL', name)
        elif scope == SC_FREE or scope == SC_CELL:
            self.emit(prefix + '_DEREF', name)
        else:
            raise RuntimeError, "unsupported scope for var %s: %d" % \
                  (name, scope)

    def _implicitNameOp(self, prefix, name):
        """Emit name ops for names generated implicitly by for loops

        The interpreter generates names that start with a period or
        dollar sign.  The symbol table ignores these names because
        they aren't present in the program text.
        """
        if self.optimized:
            self.emit(prefix + '_FAST', name)
        else:
            self.emit(prefix + '_NAME', name)

    # The set_lineno() function and the explicit emit() calls for
    # SET_LINENO below are only used to generate the line number table.
    # As of Python 2.3, the interpreter does not have a SET_LINENO
    # instruction.  pyassem treats SET_LINENO opcodes as a special case.

    def set_lineno(self, node, force=False):
        """Emit SET_LINENO if necessary.

        The instruction is considered necessary if the node has a
        lineno attribute and it is different than the last lineno
        emitted.

        Returns true if SET_LINENO was emitted.

        There are no rules for when an AST node should have a lineno
        attribute.  The transformer and AST code need to be reviewed
        and a consistent policy implemented and documented.  Until
        then, this method works around missing line numbers.
        """
        lineno = getattr(node, 'lineno', None)
        if lineno is not None and (lineno != self.last_lineno
                                   or force):
            self.emit('SET_LINENO', lineno)
            self.last_lineno = lineno
            return True
        return False

    # The first few visitor methods handle nodes that generator new
    # code objects.  They use class attributes to determine what
    # specialized code generators to use.

    NameFinder = LocalNameFinder
    FunctionGen = None
    ClassGen = None

    def visitModule(self, node):
        self.scopes = self.parseSymbols(node)
        self.scope = self.scopes[node]
        self.emit('SET_LINENO', 0)
        if node.doc:
            self.emit('LOAD_CONST', node.doc)
            self.storeName('__doc__')
        lnf = walk(node.node, self.NameFinder(), verbose=0)
        self.locals.push(lnf.getLocals())
        self.visit(node.node)
        self.emit('LOAD_CONST', None)
        self.emit('RETURN_VALUE')

    def visitExpression(self, node):
        self.set_lineno(node)
        self.scopes = self.parseSymbols(node)
        self.scope = self.scopes[node]
        self.visit(node.node)
        self.emit('RETURN_VALUE')

    def visitFunction(self, node):
        self._visitFuncOrLambda(node, isLambda=0)
        if node.doc:
            self.setDocstring(node.doc)
        self.storeName(node.name)

    def visitLambda(self, node):
        self._visitFuncOrLambda(node, isLambda=1)

    def _visitFuncOrLambda(self, node, isLambda=0):
        if not isLambda and node.decorators:
            for decorator in node.decorators.nodes:
                self.visit(decorator)
            ndecorators = len(node.decorators.nodes)
        else:
            ndecorators = 0

        gen = self.FunctionGen(node, self.scopes, isLambda,
                               self.class_name, self.get_module())
        walk(node.code, gen)
        gen.finish()
        self.set_lineno(node)
        for default in node.defaults:
            self.visit(default)
        self._makeClosure(gen, len(node.defaults))
        for i in range(ndecorators):
            self.emit('CALL_FUNCTION', 1)

    def visitClass(self, node):
        gen = self.ClassGen(node, self.scopes,
                            self.get_module())
        walk(node.code, gen)
        gen.finish()
        self.set_lineno(node)
        self.emit('LOAD_CONST', node.name)
        for base in node.bases:
            self.visit(base)
        self.emit('BUILD_TUPLE', len(node.bases))
        self._makeClosure(gen, 0)
        self.emit('CALL_FUNCTION', 0)
        self.emit('BUILD_CLASS')
        self.storeName(node.name)

    # The rest are standard visitor methods

    # The next few implement control-flow statements

    def visitIf(self, node):
        end = self.newBlock()
        numtests = len(node.tests)
        for i in range(numtests):
            test, suite = node.tests[i]
            if is_constant_false(test):
                # XXX will need to check generator stuff here
                continue
            self.set_lineno(test)
            self.visit(test)
            nextTest = self.newBlock()
            self.emit('JUMP_IF_FALSE', nextTest)
            self.nextBlock()
            self.emit('POP_TOP')
            self.visit(suite)
            self.emit('JUMP_FORWARD', end)
            self.startBlock(nextTest)
            self.emit('POP_TOP')
        if node.else_:
            self.visit(node.else_)
        self.nextBlock(end)

    def visitWhile(self, node):
        self.set_lineno(node)

        loop = self.newBlock()
        else_ = self.newBlock()

        after = self.newBlock()
        self.emit('SETUP_LOOP', after)

        self.nextBlock(loop)
        self.setups.push((LOOP, loop))

        self.set_lineno(node, force=True)
        self.visit(node.test)
        self.emit('JUMP_IF_FALSE', else_ or after)

        self.nextBlock()
        self.emit('POP_TOP')
        self.visit(node.body)
        self.emit('JUMP_ABSOLUTE', loop)

        self.startBlock(else_) # or just the POPs if not else clause
        self.emit('POP_TOP')
        self.emit('POP_BLOCK')
        self.setups.pop()
        if node.else_:
            self.visit(node.else_)
        self.nextBlock(after)

    def visitFor(self, node):
        start = self.newBlock()
        anchor = self.newBlock()
        after = self.newBlock()
        self.setups.push((LOOP, start))

        self.set_lineno(node)
        self.emit('SETUP_LOOP', after)
        self.visit(node.list)
        self.emit('GET_ITER')

        self.nextBlock(start)
        self.set_lineno(node, force=1)
        self.emit('FOR_ITER', anchor)
        self.visit(node.assign)
        self.visit(node.body)
        self.emit('JUMP_ABSOLUTE', start)
        self.nextBlock(anchor)
        self.emit('POP_BLOCK')
        self.setups.pop()
        if node.else_:
            self.visit(node.else_)
        self.nextBlock(after)

    def visitBreak(self, node):
        if not self.setups:
            raise SyntaxError, "'break' outside loop (%s, %d)" % \
                  (node.filename, node.lineno)
        self.set_lineno(node)
        self.emit('BREAK_LOOP')

    def visitContinue(self, node):
        if not self.setups:
            raise SyntaxError, "'continue' outside loop (%s, %d)" % \
                  (node.filename, node.lineno)
        kind, block = self.setups.top()
        if kind == LOOP:
            self.set_lineno(node)
            self.emit('JUMP_ABSOLUTE', block)
            self.nextBlock()
        elif kind == EXCEPT or kind == TRY_FINALLY:
            self.set_lineno(node)
            # find the block that starts the loop
            top = len(self.setups)
            while top > 0:
                top = top - 1
                kind, loop_block = self.setups[top]
                if kind == LOOP:
                    break
            if kind != LOOP:
                raise SyntaxError, "'continue' outside loop (%s, %d)" % \
                      (node.filename, node.lineno)
            self.emit('CONTINUE_LOOP', loop_block)
            self.nextBlock()
        elif kind == END_FINALLY:
            msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
            raise SyntaxError, msg % (node.filename, node.lineno)

    def visitTest(self, node, jump):
        end = self.newBlock()
        for child in node.nodes[:-1]:
            self.visit(child)
            self.emit(jump, end)
            self.nextBlock()
            self.emit('POP_TOP')
        self.visit(node.nodes[-1])
        self.nextBlock(end)

    def visitAnd(self, node):
        self.visitTest(node, 'JUMP_IF_FALSE')

    def visitOr(self, node):
        self.visitTest(node, 'JUMP_IF_TRUE')

    def visitIfExp(self, node):
        endblock = self.newBlock()
        elseblock = self.newBlock()
        self.visit(node.test)
        self.emit('JUMP_IF_FALSE', elseblock)
        self.emit('POP_TOP')
        self.visit(node.then)
        self.emit('JUMP_FORWARD', endblock)
        self.nextBlock(elseblock)
        self.emit('POP_TOP')
        self.visit(node.else_)
        self.nextBlock(endblock)

    def visitCompare(self, node):
        self.visit(node.expr)
        cleanup = self.newBlock()
        for op, code in node.ops[:-1]:
            self.visit(code)
            self.emit('DUP_TOP')
            self.emit('ROT_THREE')
            self.emit('COMPARE_OP', op)
            self.emit('JUMP_IF_FALSE', cleanup)
            self.nextBlock()
            self.emit('POP_TOP')
        # now do the last comparison
        if node.ops:
            op, code = node.ops[-1]
            self.visit(code)
            self.emit('COMPARE_OP', op)
        if len(node.ops) > 1:
            end = self.newBlock()
            self.emit('JUMP_FORWARD', end)
            self.startBlock(cleanup)
            self.emit('ROT_TWO')
            self.emit('POP_TOP')
            self.nextBlock(end)

    # list comprehensions
    __list_count = 0

    def visitListComp(self, node):
        self.set_lineno(node)
        # setup list
        append = "$append%d" % self.__list_count
        self.__list_count = self.__list_count + 1
        self.emit('BUILD_LIST', 0)
        self.emit('DUP_TOP')
        self.emit('LOAD_ATTR', 'append')
        self._implicitNameOp('STORE', append)

        stack = []
        for i, for_ in zip(range(len(node.quals)), node.quals):
            start, anchor = self.visit(for_)
            cont = None
            for if_ in for_.ifs:
                if cont is None:
                    cont = self.newBlock()
                self.visit(if_, cont)
            stack.insert(0, (start, cont, anchor))

        self._implicitNameOp('LOAD', append)
        self.visit(node.expr)
        self.emit('CALL_FUNCTION', 1)
        self.emit('POP_TOP')

        for start, cont, anchor in stack:
            if cont:
                skip_one = self.newBlock()
                self.emit('JUMP_FORWARD', skip_one)
                self.startBlock(cont)
                self.emit('POP_TOP')
                self.nextBlock(skip_one)
            self.emit('JUMP_ABSOLUTE', start)
            self.startBlock(anchor)
        self._implicitNameOp('DELETE', append)

        self.__list_count = self.__list_count - 1

    def visitListCompFor(self, node):
        start = self.newBlock()
        anchor = self.newBlock()

        self.visit(node.list)
        self.emit('GET_ITER')
        self.nextBlock(start)
        self.set_lineno(node, force=True)
        self.emit('FOR_ITER', anchor)
        self.nextBlock()
        self.visit(node.assign)
        return start, anchor

    def visitListCompIf(self, node, branch):
        self.set_lineno(node, force=True)
        self.visit(node.test)
        self.emit('JUMP_IF_FALSE', branch)
        self.newBlock()
        self.emit('POP_TOP')

    def _makeClosure(self, gen, args):
        frees = gen.scope.get_free_vars()
        if frees:
            for name in frees:
                self.emit('LOAD_CLOSURE', name)
            self.emit('BUILD_TUPLE', len(frees))
            self.emit('LOAD_CONST', gen)
            self.emit('MAKE_CLOSURE', args)
        else:
            self.emit('LOAD_CONST', gen)
            self.emit('MAKE_FUNCTION', args)

    def visitGenExpr(self, node):
        gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
                                   self.get_module())
        walk(node.code, gen)
        gen.finish()
        self.set_lineno(node)
        self._makeClosure(gen, 0)
        # precomputation of outmost iterable
        self.visit(node.code.quals[0].iter)
        self.emit('GET_ITER')
        self.emit('CALL_FUNCTION', 1)

    def visitGenExprInner(self, node):
        self.set_lineno(node)
        # setup list

        stack = []
        for i, for_ in zip(range(len(node.quals)), node.quals):
            start, anchor, end = self.visit(for_)
            cont = None
            for if_ in for_.ifs:
                if cont is None:
                    cont = self.newBlock()
                self.visit(if_, cont)
            stack.insert(0, (start, cont, anchor, end))

        self.visit(node.expr)
        self.emit('YIELD_VALUE')
        self.emit('POP_TOP')

        for start, cont, anchor, end in stack:
            if cont:
                skip_one = self.newBlock()
                self.emit('JUMP_FORWARD', skip_one)
                self.startBlock(cont)
                self.emit('POP_TOP')
                self.nextBlock(skip_one)
            self.emit('JUMP_ABSOLUTE', start)
            self.startBlock(anchor)
            self.emit('POP_BLOCK')
            self.setups.pop()
            self.startBlock(end)

        self.emit('LOAD_CONST', None)

    def visitGenExprFor(self, node):
        start = self.newBlock()
        anchor = self.newBlock()
        end = self.newBlock()

        self.setups.push((LOOP, start))
        self.emit('SETUP_LOOP', end)

        if node.is_outmost:
            self.loadName('.0')
        else:
            self.visit(node.iter)
            self.emit('GET_ITER')

        self.nextBlock(start)
        self.set_lineno(node, force=True)
        self.emit('FOR_ITER', anchor)
        self.nextBlock()
        self.visit(node.assign)
        return start, anchor, end

    def visitGenExprIf(self, node, branch):
        self.set_lineno(node, force=True)
        self.visit(node.test)
        self.emit('JUMP_IF_FALSE', branch)
        self.newBlock()
        self.emit('POP_TOP')

    # exception related

    def visitAssert(self, node):
        # XXX would be interesting to implement this via a
        # transformation of the AST before this stage
        if __debug__:
            end = self.newBlock()
            self.set_lineno(node)
            # XXX AssertionError appears to be special case -- it is always
            # loaded as a global even if there is a local name.  I guess this
            # is a sort of renaming op.
            self.nextBlock()
            self.visit(node.test)
            self.emit('JUMP_IF_TRUE', end)
            self.nextBlock()
            self.emit('POP_TOP')
            self.emit('LOAD_GLOBAL', 'AssertionError')
            if node.fail:
                self.visit(node.fail)
                self.emit('RAISE_VARARGS', 2)
            else:
                self.emit('RAISE_VARARGS', 1)
            self.nextBlock(end)
            self.emit('POP_TOP')

    def visitRaise(self, node):
        self.set_lineno(node)
        n = 0
        if node.expr1:
            self.visit(node.expr1)
            n = n + 1
        if node.expr2:
            self.visit(node.expr2)
            n = n + 1
        if node.expr3:
            self.visit(node.expr3)
            n = n + 1
        self.emit('RAISE_VARARGS', n)

    def visitTryExcept(self, node):
        body = self.newBlock()
        handlers = self.newBlock()
        end = self.newBlock()
        if node.else_:
            lElse = self.newBlock()
        else:
            lElse = end
        self.set_lineno(node)
        self.emit('SETUP_EXCEPT', handlers)
        self.nextBlock(body)
        self.setups.push((EXCEPT, body))
        self.visit(node.body)
        self.emit('POP_BLOCK')
        self.setups.pop()
        self.emit('JUMP_FORWARD', lElse)
        self.startBlock(handlers)

        last = len(node.handlers) - 1
        for i in range(len(node.handlers)):
            expr, target, body = node.handlers[i]
            self.set_lineno(expr)
            if expr:
                self.emit('DUP_TOP')
                self.visit(expr)
                self.emit('COMPARE_OP', 'exception match')
                next = self.newBlock()
                self.emit('JUMP_IF_FALSE', next)
                self.nextBlock()
                self.emit('POP_TOP')
            self.emit('POP_TOP')
            if target:
                self.visit(target)
            else:
                self.emit('POP_TOP')
            self.emit('POP_TOP')
            self.visit(body)
            self.emit('JUMP_FORWARD', end)
            if expr:
                self.nextBlock(next)
            else:
                self.nextBlock()
            if expr: # XXX
                self.emit('POP_TOP')
        self.emit('END_FINALLY')
        if node.else_:
            self.nextBlock(lElse)
            self.visit(node.else_)
        self.nextBlock(end)

    def visitTryFinally(self, node):
        body = self.newBlock()
        final = self.newBlock()
        self.set_lineno(node)
        self.emit('SETUP_FINALLY', final)
        self.nextBlock(body)
        self.setups.push((TRY_FINALLY, body))
        self.visit(node.body)
        self.emit('POP_BLOCK')
        self.setups.pop()
        self.emit('LOAD_CONST', None)
        self.nextBlock(final)
        self.setups.push((END_FINALLY, final))
        self.visit(node.final)
        self.emit('END_FINALLY')
        self.setups.pop()

    __with_count = 0

    def visitWith(self, node):
        body = self.newBlock()
        final = self.newBlock()
        exitvar = "$exit%d" % self.__with_count
        valuevar = "$value%d" % self.__with_count
        self.__with_count += 1
        self.set_lineno(node)
        self.visit(node.expr)
        self.emit('DUP_TOP')
        self.emit('LOAD_ATTR', '__exit__')
        self._implicitNameOp('STORE', exitvar)
        self.emit('LOAD_ATTR', '__enter__')
        self.emit('CALL_FUNCTION', 0)
        if node.vars is None:
            self.emit('POP_TOP')
        else:
            self._implicitNameOp('STORE', valuevar)
        self.emit('SETUP_FINALLY', final)
        self.nextBlock(body)
        self.setups.push((TRY_FINALLY, body))
        if node.vars is not None:
            self._implicitNameOp('LOAD', valuevar)
            self._implicitNameOp('DELETE', valuevar)
            self.visit(node.vars)
        self.visit(node.body)
        self.emit('POP_BLOCK')
        self.setups.pop()
        self.emit('LOAD_CONST', None)
        self.nextBlock(final)
        self.setups.push((END_FINALLY, final))
        self._implicitNameOp('LOAD', exitvar)
        self._implicitNameOp('DELETE', exitvar)
        self.emit('WITH_CLEANUP')
        self.emit('END_FINALLY')
        self.setups.pop()
        self.__with_count -= 1

    # misc

    def visitDiscard(self, node):
        self.set_lineno(node)
        self.visit(node.expr)
        self.emit('POP_TOP')

    def visitConst(self, node):
        self.emit('LOAD_CONST', node.value)

    def visitKeyword(self, node):
        self.emit('LOAD_CONST', node.name)
        self.visit(node.expr)

    def visitGlobal(self, node):
        # no code to generate
        pass

    def visitName(self, node):
        self.set_lineno(node)
        self.loadName(node.name)

    def visitPass(self, node):
        self.set_lineno(node)

    def visitImport(self, node):
        self.set_lineno(node)
        level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1
        for name, alias in node.names:
            if VERSION > 1:
                self.emit('LOAD_CONST', level)
                self.emit('LOAD_CONST', None)
            self.emit('IMPORT_NAME', name)
            mod = name.split(".")[0]
            if alias:
                self._resolveDots(name)
                self.storeName(alias)
            else:
                self.storeName(mod)

    def visitFrom(self, node):
        self.set_lineno(node)
        level = node.level
        if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT):
            level = -1
        fromlist = map(lambda (name, alias): name, node.names)
        if VERSION > 1:
            self.emit('LOAD_CONST', level)
            self.emit('LOAD_CONST', tuple(fromlist))
        self.emit('IMPORT_NAME', node.modname)
        for name, alias in node.names:
            if VERSION > 1:
                if name == '*':
                    self.namespace = 0
                    self.emit('IMPORT_STAR')
                    # There can only be one name w/ from ... import *
                    assert len(node.names) == 1
                    return
                else:
                    self.emit('IMPORT_FROM', name)
                    self._resolveDots(name)
                    self.storeName(alias or name)
            else:
                self.emit('IMPORT_FROM', name)
        self.emit('POP_TOP')

    def _resolveDots(self, name):
        elts = name.split(".")
        if len(elts) == 1:
            return
        for elt in elts[1:]:
            self.emit('LOAD_ATTR', elt)

    def visitGetattr(self, node):
        self.visit(node.expr)
        self.emit('LOAD_ATTR', self.mangle(node.attrname))

    # next five implement assignments

    def visitAssign(self, node):
        self.set_lineno(node)
        self.visit(node.expr)
        dups = len(node.nodes) - 1
        for i in range(len(node.nodes)):
            elt = node.nodes[i]
            if i < dups:
                self.emit('DUP_TOP')
            if isinstance(elt, ast.Node):
                self.visit(elt)

    def visitAssName(self, node):
        if node.flags == 'OP_ASSIGN':
            self.storeName(node.name)
        elif node.flags == 'OP_DELETE':
            self.set_lineno(node)
            self.delName(node.name)
        else:
            print "oops", node.flags

    def visitAssAttr(self, node):
        self.visit(node.expr)
        if node.flags == 'OP_ASSIGN':
            self.emit('STORE_ATTR', self.mangle(node.attrname))
        elif node.flags == 'OP_DELETE':
            self.emit('DELETE_ATTR', self.mangle(node.attrname))
        else:
            print "warning: unexpected flags:", node.flags
            print node

    def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
        if findOp(node) != 'OP_DELETE':
            self.emit(op, len(node.nodes))
        for child in node.nodes:
            self.visit(child)

    if VERSION > 1:
        visitAssTuple = _visitAssSequence
        visitAssList = _visitAssSequence
    else:
        def visitAssTuple(self, node):
            self._visitAssSequence(node, 'UNPACK_TUPLE')

        def visitAssList(self, node):
            self._visitAssSequence(node, 'UNPACK_LIST')

    # augmented assignment

    def visitAugAssign(self, node):
        self.set_lineno(node)
        aug_node = wrap_aug(node.node)
        self.visit(aug_node, "load")
        self.visit(node.expr)
        self.emit(self._augmented_opcode[node.op])
        self.visit(aug_node, "store")

    _augmented_opcode = {
        '+=' : 'INPLACE_ADD',
        '-=' : 'INPLACE_SUBTRACT',
        '*=' : 'INPLACE_MULTIPLY',
        '/=' : 'INPLACE_DIVIDE',
        '//=': 'INPLACE_FLOOR_DIVIDE',
        '%=' : 'INPLACE_MODULO',
        '**=': 'INPLACE_POWER',
        '>>=': 'INPLACE_RSHIFT',
        '<<=': 'INPLACE_LSHIFT',
        '&=' : 'INPLACE_AND',
        '^=' : 'INPLACE_XOR',
        '|=' : 'INPLACE_OR',
        }

    def visitAugName(self, node, mode):
        if mode == "load":
            self.loadName(node.name)
        elif mode == "store":
            self.storeName(node.name)

    def visitAugGetattr(self, node, mode):
        if mode == "load":
            self.visit(node.expr)
            self.emit('DUP_TOP')
            self.emit('LOAD_ATTR', self.mangle(node.attrname))
        elif mode == "store":
            self.emit('ROT_TWO')
            self.emit('STORE_ATTR', self.mangle(node.attrname))

    def visitAugSlice(self, node, mode):
        if mode == "load":
            self.visitSlice(node, 1)
        elif mode == "store":
            slice = 0
            if node.lower:
                slice = slice | 1
            if node.upper:
                slice = slice | 2
            if slice == 0:
                self.emit('ROT_TWO')
            elif slice == 3:
                self.emit('ROT_FOUR')
            else:
                self.emit('ROT_THREE')
            self.emit('STORE_SLICE+%d' % slice)

    def visitAugSubscript(self, node, mode):
        if mode == "load":
            self.visitSubscript(node, 1)
        elif mode == "store":
            self.emit('ROT_THREE')
            self.emit('STORE_SUBSCR')

    def visitExec(self, node):
        self.visit(node.expr)
        if node.locals is None:
            self.emit('LOAD_CONST', None)
        else:
            self.visit(node.locals)
        if node.globals is None:
            self.emit('DUP_TOP')
        else:
            self.visit(node.globals)
        self.emit('EXEC_STMT')

    def visitCallFunc(self, node):
        pos = 0
        kw = 0
        self.set_lineno(node)
        self.visit(node.node)
        for arg in node.args:
            self.visit(arg)
            if isinstance(arg, ast.Keyword):
                kw = kw + 1
            else:
                pos = pos + 1
        if node.star_args is not None:
            self.visit(node.star_args)
        if node.dstar_args is not None:
            self.visit(node.dstar_args)
        have_star = node.star_args is not None
        have_dstar = node.dstar_args is not None
        opcode = callfunc_opcode_info[have_star, have_dstar]
        self.emit(opcode, kw << 8 | pos)

    def visitPrint(self, node, newline=0):
        self.set_lineno(node)
        if node.dest:
            self.visit(node.dest)
        for child in node.nodes:
            if node.dest:
                self.emit('DUP_TOP')
            self.visit(child)
            if node.dest:
                self.emit('ROT_TWO')
                self.emit('PRINT_ITEM_TO')
            else:
                self.emit('PRINT_ITEM')
        if node.dest and not newline:
            self.emit('POP_TOP')

    def visitPrintnl(self, node):
        self.visitPrint(node, newline=1)
        if node.dest:
            self.emit('PRINT_NEWLINE_TO')
        else:
            self.emit('PRINT_NEWLINE')

    def visitReturn(self, node):
        self.set_lineno(node)
        self.visit(node.value)
        self.emit('RETURN_VALUE')

    def visitYield(self, node):
        self.set_lineno(node)
        self.visit(node.value)
        self.emit('YIELD_VALUE')

    # slice and subscript stuff

    def visitSlice(self, node, aug_flag=None):
        # aug_flag is used by visitAugSlice
        self.visit(node.expr)
        slice = 0
        if node.lower:
            self.visit(node.lower)
            slice = slice | 1
        if node.upper:
            self.visit(node.upper)
            slice = slice | 2
        if aug_flag:
            if slice == 0:
                self.emit('DUP_TOP')
            elif slice == 3:
                self.emit('DUP_TOPX', 3)
            else:
                self.emit('DUP_TOPX', 2)
        if node.flags == 'OP_APPLY':
            self.emit('SLICE+%d' % slice)
        elif node.flags == 'OP_ASSIGN':
            self.emit('STORE_SLICE+%d' % slice)
        elif node.flags == 'OP_DELETE':
            self.emit('DELETE_SLICE+%d' % slice)
        else:
            print "weird slice", node.flags
            raise

    def visitSubscript(self, node, aug_flag=None):
        self.visit(node.expr)
        for sub in node.subs:
            self.visit(sub)
        if len(node.subs) > 1:
            self.emit('BUILD_TUPLE', len(node.subs))
        if aug_flag:
            self.emit('DUP_TOPX', 2)
        if node.flags == 'OP_APPLY':
            self.emit('BINARY_SUBSCR')
        elif node.flags == 'OP_ASSIGN':
            self.emit('STORE_SUBSCR')
        elif node.flags == 'OP_DELETE':
            self.emit('DELETE_SUBSCR')

    # binary ops

    def binaryOp(self, node, op):
        self.visit(node.left)
        self.visit(node.right)
        self.emit(op)

    def visitAdd(self, node):
        return self.binaryOp(node, 'BINARY_ADD')

    def visitSub(self, node):
        return self.binaryOp(node, 'BINARY_SUBTRACT')

    def visitMul(self, node):
        return self.binaryOp(node, 'BINARY_MULTIPLY')

    def visitDiv(self, node):
        return self.binaryOp(node, self._div_op)

    def visitFloorDiv(self, node):
        return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE')

    def visitMod(self, node):
        return self.binaryOp(node, 'BINARY_MODULO')

    def visitPower(self, node):
        return self.binaryOp(node, 'BINARY_POWER')

    def visitLeftShift(self, node):
        return self.binaryOp(node, 'BINARY_LSHIFT')

    def visitRightShift(self, node):
        return self.binaryOp(node, 'BINARY_RSHIFT')

    # unary ops

    def unaryOp(self, node, op):
        self.visit(node.expr)
        self.emit(op)

    def visitInvert(self, node):
        return self.unaryOp(node, 'UNARY_INVERT')

    def visitUnarySub(self, node):
        return self.unaryOp(node, 'UNARY_NEGATIVE')

    def visitUnaryAdd(self, node):
        return self.unaryOp(node, 'UNARY_POSITIVE')

    def visitUnaryInvert(self, node):
        return self.unaryOp(node, 'UNARY_INVERT')

    def visitNot(self, node):
        return self.unaryOp(node, 'UNARY_NOT')

    def visitBackquote(self, node):
        return self.unaryOp(node, 'UNARY_CONVERT')

    # bit ops

    def bitOp(self, nodes, op):
        self.visit(nodes[0])
        for node in nodes[1:]:
            self.visit(node)
            self.emit(op)

    def visitBitand(self, node):
        return self.bitOp(node.nodes, 'BINARY_AND')

    def visitBitor(self, node):
        return self.bitOp(node.nodes, 'BINARY_OR')

    def visitBitxor(self, node):
        return self.bitOp(node.nodes, 'BINARY_XOR')

    # object constructors

    def visitEllipsis(self, node):
        self.emit('LOAD_CONST', Ellipsis)

    def visitTuple(self, node):
        self.set_lineno(node)
        for elt in node.nodes:
            self.visit(elt)
        self.emit('BUILD_TUPLE', len(node.nodes))

    def visitList(self, node):
        self.set_lineno(node)
        for elt in node.nodes:
            self.visit(elt)
        self.emit('BUILD_LIST', len(node.nodes))

    def visitSliceobj(self, node):
        for child in node.nodes:
            self.visit(child)
        self.emit('BUILD_SLICE', len(node.nodes))

    def visitDict(self, node):
        self.set_lineno(node)
        self.emit('BUILD_MAP', 0)
        for k, v in node.items:
            self.emit('DUP_TOP')
            self.visit(k)
            self.visit(v)
            self.emit('ROT_THREE')
            self.emit('STORE_SUBSCR')

class NestedScopeMixin:
    """Defines initClass() for nested scoping (Python 2.2-compatible)"""
    def initClass(self):
        self.__class__.NameFinder = LocalNameFinder
        self.__class__.FunctionGen = FunctionCodeGenerator
        self.__class__.ClassGen = ClassCodeGenerator

class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
    __super_init = CodeGenerator.__init__

    scopes = None

    def __init__(self, tree):
        self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
        self.futures = future.find_futures(tree)
        self.__super_init()
        walk(tree, self)

    def get_module(self):
        return self

class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
    __super_init = CodeGenerator.__init__

    scopes = None
    futures = ()

    def __init__(self, tree):
        self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
        self.__super_init()
        walk(tree, self)

    def get_module(self):
        return self

class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):

    __super_init = CodeGenerator.__init__

    scopes = None
    futures = ()

    def __init__(self, tree):
        self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
        self.__super_init()
        self.set_lineno(tree)
        walk(tree, self)
        self.emit('RETURN_VALUE')

    def get_module(self):
        return self

    def visitDiscard(self, node):
        # XXX Discard means it's an expression.  Perhaps this is a bad
        # name.
        self.visit(node.expr)
        self.emit('PRINT_EXPR')

class AbstractFunctionCode:
    optimized = 1
    lambdaCount = 0

    def __init__(self, func, scopes, isLambda, class_name, mod):
        self.class_name = class_name
        self.module = mod
        if isLambda:
            klass = FunctionCodeGenerator
            name = "<lambda.%d>" % klass.lambdaCount
            klass.lambdaCount = klass.lambdaCount + 1
        else:
            name = func.name

        args, hasTupleArg = generateArgList(func.argnames)
        self.graph = pyassem.PyFlowGraph(name, func.filename, args,
                                         optimized=1)
        self.isLambda = isLambda
        self.super_init()

        if not isLambda and func.doc:
            self.setDocstring(func.doc)

        lnf = walk(func.code, self.NameFinder(args), verbose=0)
        self.locals.push(lnf.getLocals())
        if func.varargs:
            self.graph.setFlag(CO_VARARGS)
        if func.kwargs:
            self.graph.setFlag(CO_VARKEYWORDS)
        self.set_lineno(func)
        if hasTupleArg:
            self.generateArgUnpack(func.argnames)

    def get_module(self):
        return self.module

    def finish(self):
        self.graph.startExitBlock()
        if not self.isLambda:
            self.emit('LOAD_CONST', None)
        self.emit('RETURN_VALUE')

    def generateArgUnpack(self, args):
        for i in range(len(args)):
            arg = args[i]
            if isinstance(arg, tuple):
                self.emit('LOAD_FAST', '.%d' % (i * 2))
                self.unpackSequence(arg)

    def unpackSequence(self, tup):
        if VERSION > 1:
            self.emit('UNPACK_SEQUENCE', len(tup))
        else:
            self.emit('UNPACK_TUPLE', len(tup))
        for elt in tup:
            if isinstance(elt, tuple):
                self.unpackSequence(elt)
            else:
                self._nameOp('STORE', elt)

    unpackTuple = unpackSequence

class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
                            CodeGenerator):
    super_init = CodeGenerator.__init__ # call be other init
    scopes = None

    __super_init = AbstractFunctionCode.__init__

    def __init__(self, func, scopes, isLambda, class_name, mod):
        self.scopes = scopes
        self.scope = scopes[func]
        self.__super_init(func, scopes, isLambda, class_name, mod)
        self.graph.setFreeVars(self.scope.get_free_vars())
        self.graph.setCellVars(self.scope.get_cell_vars())
        if self.scope.generator is not None:
            self.graph.setFlag(CO_GENERATOR)

class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
                           CodeGenerator):
    super_init = CodeGenerator.__init__ # call be other init
    scopes = None

    __super_init = AbstractFunctionCode.__init__

    def __init__(self, gexp, scopes, class_name, mod):
        self.scopes = scopes
        self.scope = scopes[gexp]
        self.__super_init(gexp, scopes, 1, class_name, mod)
        self.graph.setFreeVars(self.scope.get_free_vars())
        self.graph.setCellVars(self.scope.get_cell_vars())
        self.graph.setFlag(CO_GENERATOR)

class AbstractClassCode:

    def __init__(self, klass, scopes, module):
        self.class_name = klass.name
        self.module = module
        self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
                                           optimized=0, klass=1)
        self.super_init()
        lnf = walk(klass.code, self.NameFinder(), verbose=0)
        self.locals.push(lnf.getLocals())
        self.graph.setFlag(CO_NEWLOCALS)
        if klass.doc:
            self.setDocstring(klass.doc)

    def get_module(self):
        return self.module

    def finish(self):
        self.graph.startExitBlock()
        self.emit('LOAD_LOCALS')
        self.emit('RETURN_VALUE')

class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
    super_init = CodeGenerator.__init__
    scopes = None

    __super_init = AbstractClassCode.__init__

    def __init__(self, klass, scopes, module):
        self.scopes = scopes
        self.scope = scopes[klass]
        self.__super_init(klass, scopes, module)
        self.graph.setFreeVars(self.scope.get_free_vars())
        self.graph.setCellVars(self.scope.get_cell_vars())
        self.set_lineno(klass)
        self.emit("LOAD_GLOBAL", "__name__")
        self.storeName("__module__")
        if klass.doc:
            self.emit("LOAD_CONST", klass.doc)
            self.storeName('__doc__')

def generateArgList(arglist):
    """Generate an arg list marking TupleArgs"""
    args = []
    extra = []
    count = 0
    for i in range(len(arglist)):
        elt = arglist[i]
        if isinstance(elt, str):
            args.append(elt)
        elif isinstance(elt, tuple):
            args.append(TupleArg(i * 2, elt))
            extra.extend(misc.flatten(elt))
            count = count + 1
        else:
            raise ValueError, "unexpect argument type:", elt
    return args + extra, count

def findOp(node):
    """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
    v = OpFinder()
    walk(node, v, verbose=0)
    return v.op

class OpFinder:
    def __init__(self):
        self.op = None
    def visitAssName(self, node):
        if self.op is None:
            self.op = node.flags
        elif self.op != node.flags:
            raise ValueError, "mixed ops in stmt"
    visitAssAttr = visitAssName
    visitSubscript = visitAssName

class Delegator:
    """Base class to support delegation for augmented assignment nodes

    To generator code for augmented assignments, we use the following
    wrapper classes.  In visitAugAssign, the left-hand expression node
    is visited twice.  The first time the visit uses the normal method
    for that node .  The second time the visit uses a different method
    that generates the appropriate code to perform the assignment.
    These delegator classes wrap the original AST nodes in order to
    support the variant visit methods.
    """
    def __init__(self, obj):
        self.obj = obj

    def __getattr__(self, attr):
        return getattr(self.obj, attr)

class AugGetattr(Delegator):
    pass

class AugName(Delegator):
    pass

class AugSlice(Delegator):
    pass

class AugSubscript(Delegator):
    pass

wrapper = {
    ast.Getattr: AugGetattr,
    ast.Name: AugName,
    ast.Slice: AugSlice,
    ast.Subscript: AugSubscript,
    }

def wrap_aug(node):
    return wrapper[node.__class__](node)

if __name__ == "__main__":
    for file in sys.argv[1:]:
        compileFile(file)


With many couples today choosing to decorate their event with stunning floral arrangements, finding the perfect florist has become one of the most important elements of planning a wedding. If you are searching for a wedding florist in Adelaide, South Australia, you've come to the right place! To kick start your hunt, we've compiled a list of the best wedding florists in Adelaide ranked by their customer reviews on Easy Weddings.
Boasting an impressive 44 five-star customer reviews on Easy Weddings, Fabulous Functions is easily one of the most popular wedding florists Adelaide has to offer. This florist works closely with their clients to ensure all needs, requirements and dreams are catered for within the agreed budget. Whatever you envision for your wedding flowers, the dedicated team behind Fabulous Functions is sure to create something worth remembering for many years to come. Click here to find out more about this reputable florist.
At Fabulous Functions we love flowers.
Following closely behind with 29 five-star customer reviews, Viva The Flower Store is up there with Adelaide's favourite wedding florists. Specialising in weddings, this florist sources their blooms from local, national and even international suppliers to ensure the best quality floral arrangements are created. The team behind Viva The Flower Store work closely with the clients to create something they can be proud of on their special day. For more information and to view their photo gallery, we recommend taking a look at Viva The Flower Store's Easy Weddings storefront. See more here.
With over 22 years of industry experience, Just Wedding Flowers is renowned as one of the most sought-after florists Adelaide has to offer. This flower provider is known for creating stunning floral arrangements to suit weddings of all themes, sizes and budgets. Only the best quality flowers are used, and these are personally sourced from Australian and overseas growers. If you are searching for a reputable florist to service your wedding, we cannot recommend Just Wedding Flowers enough. But don't just take our word for it – read their glowing five-star customer reviews and find out for yourself why so many newlyweds chose Just Wedding Flowers to design their floral arrangements. See more here.
Angelik Blossoms could be everything you've been searching for and more. This boutique floral design studio has over 10 years of experience bringing wedding dreams to life. Angelik Blossoms creates bouquets, boutonniere, flower crowns, centrepieces, backdrops, bridal set ups, hanging floral arrangements and more. Whatever you envision for your event flowers, Angelik Blossoms can create it for you. Click here to find out more.
With over 25 years of experience in the floral industry, Zofi Brzezinski from Flowers by Zofi is up there with the most sought-after florists Adelaide has to offer. This wedding flower provider specialises in creating bouquets, ceremony flowers, and floral arrangements for the reception. Flowers by Zofi offers couples the choice between fresh and realistic artificial flowers, so there's even something for those with allergies or those who wish to keep their bouquets looking fresh the entire day. For more information on Flowers by Zofi, be sure to visit their Easy Weddings storefront here.
With 16 five-star customer reviews on Easy Weddings, Simply Sublime Events is up there with the most popular wedding florists Adelaide has to offer. This supplier offers a number of services, including wedding flowers, cakes, reception decor, invitations, Bomboniere, centrepieces, and ceremony decor. To find out if Simply Sublime Events is the florist you've been searching for, we recommend visiting their Easy Weddings storefront. See more here.
Wedding flowers, wedding cakes, chair covers & sashes, invitations printed and DIY, table centers and ceremonies.
Blackwood Florist could be everything you've been searching for and more. This wedding flower provider takes the time to get to know their clients to ensure all their needs, requirements and dreams for their floral arrangements are catered for. All blooms are sourced from local and international flower suppliers, ensuring only the freshest are used in event floral arrangements. If you are searching for a highly sought-after Adelaide florist to service your wedding, we cannot recommend Blackwood Florist enough. But don't just take our word for it – check out their photo gallery and find out for yourself why so many newlyweds chose Blackwood Florist to create their wedding flowers. See more here.
Blush Blooms and Events could be exactly what you've been searching for. With 10 five-star customer reviews backing them, this supplier offers a range of services to ensure a spectacular event. Blush Blooms and Events services include fresh and silk floral arrangements, event decor for hire, and hair, makeup and tanning to get brides and their bridesmaids wedding-day ready. To find out more about Blush Blooms and Events, be sure to take a look at their Easy Weddings storefront here.
With over 13 years of floristry experience, Chloe from Flowers Of Envy is up there with the most sought-after florists Adelaide has to offer. This wedding florist specialises in wedding bouquets, floral arrangements, flower crown parties, event styling and more. Whatever your wedding vision and budget, Chloe from Flowers Of Envy is sure to create something spectacular out of your event. Click here to find out more about this reputable florist.
My name is Chloe and I really love flowers. I love making wedding bouquets and all that comes with the wedding styling and set up!
A five-star supplier on Easy Weddings, Hayley's Flower Shop could be everything you've been searching for in a florist. Based in Adelaide, South Australia, this online wedding florist specialises in all things flowers. Whatever you envision for your event, Hayley's Flower Shop is sure to get guests talking and leave them with something to remember for years to come. Click here to find out more about Hayley's Flower Shop.
No matter the occasion, big or small, Hayley's Flower Shop is dedicated to deliver a personalised service, quality flowers and bespoke balloons for your event.
For thousands of couples across Australia, finding the perfect florist is up there with the most important elements of planning a wedding. If you are located in Adelaide, South Australia, these 10 wedding florists are the ones to start with.
Click here to discover the best wedding florists Adelaide has to offer!


text:
Die Abkürzung HHD steht für:

 HandHeldDevice, die vom Anwender benutzte Hardware zum Erzeugen der Transaktionsnummer beim chipTAN-Verfahren
 Heimhämodialyse
 Hybrid Hard Drive, siehe Solid-State-Drive#Hybridfestplatte

Abkürzung

redpajama_set_name: RedPajamaWikipedia


It could be just a small pile of electronics you want to rid your office of or a large quantity of items such computers, copiers, phones and more out of a building. In any case, Clean Out Your Office has the resources to both pick up and recycle these electronics in the proper and most environmentally-friendly way.
Incorporated in 1826 and known as the Cradle of Industrial Revolution in the US, Lowell, MA has many historic sites and is the fourth largest city in the state.
Clean Out Your Office proudly serves Lowell, MA and its residents for numerous electronics recycling services. We promise prompt and professional service, pick-up and removal of your old electronics, environmentally safe recycling, certified disk-drive destruction, and revenue sharing when possible. We will save what we can and recycling the rest in the proper way.


Prime Minister of New Zealand Jacinda Ardern has spoken out about the mosque attacks in Christchurch.
Ms Ardern said has this devastating act of violence is being treated as a terrorist incident.
She also confirmed how none of the suspects arrested had been on terror watch lists. Following the attacks, Ms Ardern has now upgraded New Zealand's terror threat level from low to high.
Ms Ardern stated this is 'one of New Zealand's darkest days', emphasizing 'there is no place in New Zealand for such acts of extreme and unprecedented violence'.
I want to send a message to those directly affected…For many this may have not been the place they were born. For many New Zealand was their choice, a place they actively came to and committed themselves to…it was a place where many came to for their safety. A place where it was safe to practice their culture and religion.
We represent diversity and compassion, a home for those who share our values, a refuge for those who need it. And those values will not and can not be shaken by this attack. We are a proud nation of more than 200 ethnicities and 160 languages.
[This is] the strongest possible condemnation of the ideology of the people who did this.
This is not who we are. This act was not a reflection of who we are as a nation. It will take time to heal and tonight our thoughts and our prayers need to be with those affected.
As reported by the BBC, this is the deadliest attack in the history of New Zealand, with 49 people killed and at least 20 others injured.
A man in his late twenties has been charged with murder and will reportedly appear in court on the morning of Saturday, March 16.
Two other men and one woman were reportedly detained close by and had their firearms seized by police.
Our thoughts are with all those who have been affected by these horrific attacks.


text:
require 'chef/application'
require 'digest/sha2'

class Manipulator
  attr_reader :node

  # Create a new Manipulator object (aka an /etc/hosts manipulator). If a
  # hostsfile is not found, a Chef::Application.fatal is risen, causing
  # the process to terminate on the node and the converge will fail.
  #
  # @param [Chef::node] node
  #   the current Chef node
  # @return [Manipulator]
  #   a class designed to manipulate the node's /etc/hosts file
  def initialize(node)
    @node = node.to_hash

    # Fail if no hostsfile is found
    unless ::File.exists?(hostsfile_path)
      Chef::Application.fatal! "No hostsfile exists at '#{hostsfile_path}'!"
    end

    @entries = []
    collect_and_flatten(::File.readlines(hostsfile_path))
  end

  # Return a list of all IP Addresses for this hostsfile.
  #
  # @return [Array<IPAddr>]
  #   the list of IP Addresses
  def ip_addresses
    @entries.collect do |entry|
      entry.ip_address
    end.compact || []
  end

  # Add a new record to the hostsfile.
  #
  # @param [Hash] options
  #   a list of options to create the entry with
  # @option options [String] :ip_address
  #   the IP Address for this entry
  # @option options [String] :hostname
  #   the hostname for this entry
  # @option options [String, Array<String>] :aliases
  #   a alias or array of aliases for this entry
  # @option options[String] :comment
  #   an optional comment for this entry
  # @option options [Fixnum] :priority
  #   the relative priority of this entry (compared to others)
  def add(options = {})
    @entries << Entry.new(
      :ip_address => options[:ip_address],
      :hostname   => options[:hostname],
      :aliases    => options[:aliases],
      :comment    => options[:comment],
      :priority   => options[:priority],
    )
  end

  # Update an existing entry. This method will do nothing if the entry
  # does not exist.
  #
  # @param (see #add)
  def update(options = {})
    if entry = find_entry_by_ip_address(options[:ip_address])
      entry.hostname  = options[:hostname]
      entry.aliases   = options[:aliases]
      entry.comment   = options[:comment]
      entry.priority  = options[:priority]
    end
  end

  # Append content to an existing entry. This method will add a new entry
  # if one does not already exist.
  #
  # @param (see #add)
  def append(options = {})
    if entry = find_entry_by_ip_address(options[:ip_address])
      hosts          = normalize(entry.hostname, entry.aliases, options[:hostname], options[:aliases])
      entry.hostname = hosts.shift
      entry.aliases  = hosts

      unless entry.comment && options[:comment] && entry.comment.include?(options[:comment])
        entry.comment = normalize(entry.comment, options[:comment]).join(', ')
      end
    else
      add(options)
    end
  end

  # Remove an entry by it's IP Address
  #
  # @param [String] ip_address
  #   the IP Address of the entry to remove
  def remove(ip_address)
    if entry = find_entry_by_ip_address(ip_address)
      @entries.delete(entry)
    end
  end

  # Safe save the entry file.
  # @see #save!
  #
  # @return [Boolean]
  #   true if the record was successfully saved, false otherwise
  def save
    save!
    true
  rescue Exception
    false
  end

  # Save the new hostsfile to the target machine. This method will only write the
  # hostsfile if the current version has changed. In other words, it is convergent.
  def save!
    entries = []
    entries << "#"
    entries << "# This file is managed by Chef, using the hostsfile cookbook."
    entries << "# Editing this file by hand is highly discouraged!"
    entries << "#"
    entries << "# Comments containing an @ sign should not be modified or else"
    entries << "# hostsfile will be unable to guarantee relative priority in"
    entries << "# future Chef runs!"
    entries << "#"
    entries << ""
    entries += unique_entries.map(&:to_line)
    entries << ""

    contents = entries.join("\n")
    contents_sha = Digest::SHA512.hexdigest(contents)

    # Only write out the file if the contents have changed...
    if contents_sha != current_sha
      ::File.open(hostsfile_path, 'w') do |f|
        f.write(contents)
      end
    end
  end

  # Find an entry by the given IP Address.
  #
  # @param [String] ip_address
  #   the IP Address of the entry to detect
  # @return [Entry, nil]
  #   the corresponding entry object, or nil if it does not exist
  def find_entry_by_ip_address(ip_address)
    @entries.detect do |entry|
      !entry.ip_address.nil? && entry.ip_address == ip_address
    end
  end

  private

    # The path to the current hostsfile.
    #
    # @return [String]
    #   the full path to the hostsfile, depending on the operating system
    def hostsfile_path
      @hostsfile_path ||= case node['platform_family']
        when 'windows'
          "#{node['kernel']['os_info']['system_directory']}\\drivers\\etc\\hosts"
        else
          # debian, rhel, fedora, suse, gentoo, slackware, arch, mac_os_x, windows
          '/etc/hosts'
        end
    end

    # The current sha of the system hostsfile.
    #
    # @return [String]
    #   the sha of the current hostsfile
    def current_sha
      @current_sha ||= Digest::SHA512.hexdigest(File.read(hostsfile_path))
    end

    # Normalize the given list of elements into a single array with no nil
    # values and no duplicate values.
    #
    # @param [Object] things
    #
    # @return [Array]
    #   a normalized array of things
    def normalize(*things)
      things.flatten.compact.uniq
    end

    # This is a crazy way of ensuring unique objects in an array using a Hash.
    #
    # @return [Array]
    #   the sorted list of entires that are unique
    def unique_entries
      entries = Hash[*@entries.map{ |entry| [entry.ip_address, entry] }.flatten].values
      entries.sort_by { |e| [-e.priority.to_i, e.hostname.to_s] }
    end

    # Takes /etc/hosts file contents and builds a flattened entries
    # array so that each IP address has only one line and multiple hostnames
    # are flattened into a list of aliases.
    #
    # @param [Array] contents
    #   Array of lines from /etc/hosts file
    def collect_and_flatten(contents)
      contents.each do |line|
        entry = Entry.parse(line)
        next if entry.nil?

        append(
          :ip_address => entry.ip_address,
          :hostname   => entry.hostname,
          :aliases    => entry.aliases,
          :comment    => entry.comment,
          :priority   => entry.priority,
        )
      end
    end
end

redpajama_set_name: RedPajamaGithub


Burton has no prior starts at CTMP. He was able to test there earlier this year and has experience on road courses running in the NASCAR K&N Pro Series East. In six road course starts, he has two top-five and three top-10 finishes. His best finishes came at New Jersey Motorsports Park in Millville and Watkins Glen (N.Y.) International where he finished third in 2017.
In three NCWTS starts this season Burton has earned two top-five, three top-10 finishes, one pole and led 30 laps. He scored his best career finish in the NCWTS at Iowa Speedway in Newton on June 16 when he won the pole, led 30 laps and finished third.
The No. 51 team is the fourth seed in the NCWTS Owner's Championship point standings. With multiple drivers throughout the season, the team is not eligible for the driver's championship. KBM has won the owner's championship six times in the past eight seasons.
For Sunday's race north of the border, Burton will be sponsored by Hunt Brothers Pizza and FIELDS. Hunt Brothers Pizza was started by four brothers from Indiana with a goal to build America's No. 1 convenience store pizza brand. FIELDS is an award-winning sports general contractor whose projects include natural grass and synthetic turf sports field construction for professional sports teams, universities and municipalities. Headed by principals with a combined 100+ years of industry experience, expertise and creativity is applied to every project that's undertaken. FIELDS is part of the Sports Fields Inc., family of companies which also includes FIELDS Maintenance, The Sports Force and Sports Force Parks. Learn more at sficompanies.com.
How are you feeling after missing Bristol due to illness?
You were able to test at CTMP a few months ago. How did that go?


Old thread (no matter how good it was has gotten too large, so you can continue here..
Where are all the 1D-X pix?
Here's one of the last from the 7D. I still own it, but it's relegated to second-body.
Come on guys. Find the thread and start posting again.
Here's a hand held moon shot that worked out really nicely. Usually, when the moon is so low to the horizon that its orange, your shots will not be sharp because of smog, moisture, etc. in the atmosphere. For this shot, a front had just gone through and blew out all the bad stuff and I got a good, clean shot at a low moon.
wondered why the old one was so quiet.
Dave/anyone else you gonna shoot this?
I don't think I can get far enough away from Chicago that night to do it.
I should. One of my grand daughters is visiting and I could take her out into the plains of Colorado, or maybe even up a mountain to shoot this.
Thanks for mentioning it. I might give the ole 5D MkIII its first long-exposure test.
It's gonna be northeast facing so shooting off the mountains into the plains would be kinda cool. Too bad its not NW facing so you could shoot back at the mountains (assuming you live around Denver).
I'll probably go South, into the plains and just get away from light, keeping the exposure simple.
I may have to buy some stacking software, but I don't have a astromomy head. I will try some high ISO.
Do a google search on tutorials, I read some good tips on how to do it right.
its the night of august 11 to 12th this year. Im actually about 20 mins from the city with not much lighting around. I might give it a shot this year.
I don't shoot a lot of vehicles normally, but this one had the roundel. This was taken two days ago on the Old Mission Peninsula in Michigan. At the top of my blog (link in the signature below) there are two posts with a total of 30 varied images from this area. More are likely to be added as several days are left to the trip.
Great travel shots Diver. I particularly like the Breakfast/Beer shot on your blog.
What a weird looking sidecar, Ron.


text:
NSString * TSSTKeyboardEquivalents	= @"keyboardEquivalents";

NSString * TSSTMenuTag				= @"menuTag";
NSString * TSSTMenuAction			= @"menuAction";
NSString * TSSTMenuKeyEquivalent	= @"menuKeyEquivalent";
NSString * TSSTMenuModifierKey		= @"menuModifierKey";
NSString * TSSTActionDescription	= @"actionDescription";
NSString * TSSTPreferenceKey		= @"preferenceKey";

NSString * TSSTFullscreenShortcut		= @"fullscreenShortcut";
NSString * TSSTRotateRightShortcut		= @"rotateRightShortcut";
NSString * TSSTRotateLeftShortcut		= @"rotateLeftShortcut";
NSString * TSSTToggleLoupeShortcut		= @"toggleLoupeShortcut";
NSString * TSSTPageOrderShortcut		= @"pageOrderShortcut";
NSString * TSSTTwoPageShortcut			= @"twoPageShortcut";
NSString * TSSTOriginalSizeShortcut		= @"originalSizeShortcut";
NSString * TSSTHorizontalFitShortcut	= @"horizontalFitShortcut";
NSString * TSSTWindowFitShortcut		= @"windowFitShortcut";
NSString * TSSTThumbnailShortcut		= @"thumbnailShortcut";
NSString * TSSTZoomInShortcut			= @"zoomInShortcut";
NSString * TSSTZoomOutShortcut			= @"zoomOutShortcut";
NSString * TSSTPageRightShortcut		= @"pageRightShortcut";
NSString * TSSTPageLeftShortcut			= @"pageLeftShortcut";
NSString * TSSTFirstPageShortcut		= @"firstPageShortcut";
NSString * TSSTLastPageShortcut			= @"lastPageShortcut";
NSString * TSSTSkipRightShortcut		= @"skipRightShortcut";
NSString * TSSTSkipLeftShortcut			= @"skipLeftShortcut";
NSString * TSSTShiftRightShortcut		= @"shiftRightShortcut";
NSString * TSSTShiftLeftShortcut		= @"shiftLeftShortcut";
NSString * TSSTPageJumpShortcut			= @"pageJumpShortcut";

static NSMutableArray * forbiddenShortcuts = nil;

@implementation TSSTShortcutController

+ (void)initialize
{
	forbiddenShortcuts = [NSMutableArray new];

	NSDictionary * singleShortcut;
	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  [NSString stringWithFormat: @"%C", NSLeftArrowFunctionKey], TSSTMenuKeyEquivalent, nil];
	[forbiddenShortcuts addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  [NSString stringWithFormat: @"%C", NSRightArrowFunctionKey], TSSTMenuKeyEquivalent, nil];
	[forbiddenShortcuts addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  [NSString stringWithFormat: @"%C", NSDownArrowFunctionKey], TSSTMenuKeyEquivalent, nil];
	[forbiddenShortcuts addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  [NSString stringWithFormat: @"%C", NSUpArrowFunctionKey], TSSTMenuKeyEquivalent, nil];
	[forbiddenShortcuts addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"b", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[forbiddenShortcuts addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"B", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[forbiddenShortcuts addObject: singleShortcut];
	[singleShortcut release];
}

+ (void)scrapeMenuKeyEquivalentsForMenu:(NSMenu *)menu
{
	NSArray * menuItems = [menu itemArray];
	BOOL match;
	NSDictionary * itemDescription;
	NSMenu * subMenu;
	for(NSMenuItem * menuItem in menuItems)
	{
		itemDescription = nil;
		match = NO;
		subMenu = [menuItem submenu];
		if(subMenu)
		{
			[TSSTShortcutController scrapeMenuKeyEquivalentsForMenu: subMenu];
		}
		else
		{
			if([menuItem keyEquivalent] && [menuItem keyEquivalentModifierMask])
			{
				itemDescription = [NSDictionary dictionaryWithObjectsAndKeys:
								   [menuItem keyEquivalent], TSSTMenuKeyEquivalent,
								   [NSNumber numberWithUnsignedInt: [menuItem keyEquivalentModifierMask]], TSSTMenuModifierKey, nil];
			}
			else if([menuItem keyEquivalent])
			{
				itemDescription = [NSDictionary dictionaryWithObjectsAndKeys:
								   [menuItem keyEquivalent], TSSTMenuKeyEquivalent, nil];
			}

			if(itemDescription)
			{
				[forbiddenShortcuts addObject: itemDescription];
			}
		}
	}
}

+ (NSArray *)availableActions
{
	NSMutableArray * actions = [NSMutableArray new];
	NSDictionary * singleShortcut;
	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"changePageOrder:", TSSTMenuAction,
					  @"Change page order", TSSTActionDescription,
					  @"d", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey,
					  @"pageOrderShortcut", TSSTPreferenceKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"setArchiveIcon:", TSSTMenuAction,
					  @"Set selected page as icon", TSSTActionDescription,
					  @"defaultIcon", TSSTPreferenceKey,
					  @"c", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"changeTwoPage:", TSSTMenuAction,
					  @"Toggle two page spread", TSSTActionDescription,
					  @"twoPageShortcut", TSSTPreferenceKey,
					  @"p", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"changeFullscreen:", TSSTMenuAction,
					  @"Toggle fullscreen", TSSTActionDescription,
					  @"fullscreenShortcut", TSSTPreferenceKey,
					  @"f", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"togglePageExpose:", TSSTMenuAction,
					  @"Thumbnail exposé", TSSTActionDescription,
					  @"thumbnailShortcut", TSSTPreferenceKey,
					  @"t", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"toggleLoupe:", TSSTMenuAction,
					  @"Toggle loupe", TSSTActionDescription,
					  @"toggleLoupeShortcut", TSSTPreferenceKey,
					  @"u", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"zoomIn:", TSSTMenuAction,
					  @"Zoom in", TSSTActionDescription,
					  @"zoomInShortcut", TSSTPreferenceKey,
					  @"=", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"zoomOut:", TSSTMenuAction,
					  @"Zoom out", TSSTActionDescription,
					  @"zoomOutShortcut", TSSTPreferenceKey,
					  @"-", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"zoomReset:", TSSTMenuAction,
					  @"Zoom reset", TSSTActionDescription,
					  @"zoomResetShortcut", TSSTPreferenceKey,
					  @"0", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"rotateLeft:", TSSTMenuAction,
					  @"Rotate left", TSSTActionDescription,
					  @"rotateLeftShortcut", TSSTPreferenceKey,
					  @"l", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"rotateRight:", TSSTMenuAction,
					  @"Rotate right", TSSTActionDescription,
					  @"rotateRightShortcut", TSSTPreferenceKey,
					  @"r", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"noRotation:", TSSTMenuAction,
					  @"No Rotation", TSSTActionDescription,
					  @"n", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey,
					  @"noRotationShortcut", TSSTPreferenceKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"changeScaling:", TSSTMenuAction,
					  [NSNumber numberWithInt: 400], TSSTMenuTag,
					  @"Original size mode", TSSTActionDescription,
					  @"originalSizeShortcut", TSSTPreferenceKey,
					  @"1", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"changeScaling:", TSSTMenuAction,
					  [NSNumber numberWithInt: 401], TSSTMenuTag,
					  @"Scale pages to fit window", TSSTActionDescription,
					  @"windowFitShortcut", TSSTPreferenceKey,
					  @"2", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"changeScaling:", TSSTMenuAction,
					  [NSNumber numberWithInt: 402], TSSTMenuTag,
					  @"Scale pages to fit window width", TSSTActionDescription,
					  @"horizontalFitShortcut", TSSTPreferenceKey,
					  @"3", TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"pageRight:", TSSTMenuAction,
					  @"Page right", TSSTActionDescription,
					  TSSTPageRightShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSRightArrowFunctionKey], TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"pageLeft:", TSSTMenuAction,
					  @"Page left", TSSTActionDescription,
					  TSSTPageLeftShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSLeftArrowFunctionKey], TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"firstPage:", TSSTMenuAction,
					  @"Jump to first page", TSSTActionDescription,
					  TSSTFirstPageShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSHomeFunctionKey], TSSTMenuKeyEquivalent, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"lastPage:", TSSTMenuAction,
					  @"Jump to last page", TSSTActionDescription,
					  TSSTLastPageShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSEndFunctionKey], TSSTMenuKeyEquivalent,  nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"shiftPageRight:", TSSTMenuAction,
					  @"Shift one page right", TSSTActionDescription,
					  TSSTShiftRightShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSRightArrowFunctionKey], TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSAlternateKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"shiftPageLeft:", TSSTMenuAction,
					  @"Shift one page left", TSSTActionDescription,
					  TSSTShiftLeftShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSLeftArrowFunctionKey], TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSAlternateKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"skipRight:", TSSTMenuAction,
					  @"Skip ten pages right", TSSTActionDescription,
					  TSSTSkipRightShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSRightArrowFunctionKey], TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask | NSAlternateKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"skipLeft:", TSSTMenuAction,
					  @"Skip ten pages left", TSSTActionDescription,
					  TSSTSkipLeftShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSLeftArrowFunctionKey], TSSTMenuKeyEquivalent,
					  [NSNumber numberWithUnsignedInt: NSCommandKeyMask | NSAlternateKeyMask], TSSTMenuModifierKey, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	singleShortcut = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
					  @"launchJumpPanel:", TSSTMenuAction,
					  @"Jump to specific page", TSSTActionDescription,
					  TSSTPageJumpShortcut, TSSTPreferenceKey,
					  [NSString stringWithFormat: @"%C", NSCarriageReturnCharacter], TSSTMenuKeyEquivalent, nil];
	[actions addObject: singleShortcut];
	[singleShortcut release];

	return [actions autorelease];
}

+ (NSArray *)forbiddenShortcuts
{
	return forbiddenShortcuts;
}

+ (NSMutableDictionary *)defaultShortcutMapping
{
	NSMutableDictionary * shortcutDefaults = [NSMutableDictionary new];
	NSMutableDictionary * singleShortcut;

	NSArray * actions = [TSSTShortcutController availableActions];
	for(NSDictionary * action in actions)
	{
		singleShortcut = [NSMutableDictionary dictionaryWithObjectsAndKeys:
						  [action objectForKey: TSSTMenuKeyEquivalent], TSSTMenuKeyEquivalent,
						  [action objectForKey: TSSTMenuModifierKey], TSSTMenuModifierKey, nil];
		[shortcutDefaults setObject: singleShortcut forKey: [action objectForKey: TSSTPreferenceKey]];
	}

	return [shortcutDefaults autorelease];
}

+ (void)applyEquivalentWithDescription:(NSDictionary *)description toMenu:(NSMenu *)menu
{
//	NSLog([description description]);

	NSArray * menuItems = [menu itemArray];
	BOOL match;
	NSString * selectorString;

	for(NSMenuItem * menuItem in menuItems)
	{
		match = NO;
		NSMenu * subMenu = [menuItem submenu];
		if(subMenu)
		{
			[[self class] applyEquivalentWithDescription: description toMenu: subMenu];
		}
		else
		{
			selectorString = NSStringFromSelector([menuItem action]);
			if([[description valueForKey: TSSTMenuAction] isEqualToString: selectorString])
			{
				match = YES;
			}

			if([description valueForKey: TSSTMenuTag] && match)
			{
				match = [[description valueForKey: TSSTMenuTag] intValue] == [menuItem tag] ? YES : NO;
			}

			if(match)
			{
				[menuItem setKeyEquivalent: [description valueForKey: TSSTMenuKeyEquivalent]];
				[menuItem setKeyEquivalentModifierMask: [[description valueForKey: TSSTMenuModifierKey] unsignedIntValue]];
			}
		}
	}
}

- (void) dealloc
{
	NSUserDefaultsController * sharedDefaults = [NSUserDefaultsController sharedUserDefaultsController];

	NSArray * actions = [[self class] availableActions];
	for(NSMutableDictionary * action in actions)
	{
		[[sharedDefaults defaults] removeObserver: self forKeyPath: [action objectForKey: TSSTPreferenceKey]];
	}

	[super dealloc];
}

- (void)awakeFromNib
{
	NSMenu * applicationMenu = [[NSApplication sharedApplication] mainMenu];
	[[self class] scrapeMenuKeyEquivalentsForMenu: applicationMenu];

	NSUserDefaultsController * sharedDefaults = [NSUserDefaultsController sharedUserDefaultsController];
	NSDictionary * savedKey;
	NSArray * actions = [[self class] availableActions];
	for(NSMutableDictionary * action in actions)
	{
		savedKey = [[sharedDefaults values] valueForKey: [action objectForKey: TSSTPreferenceKey]];
		[action setValuesForKeysWithDictionary: savedKey];
		[[self class] applyEquivalentWithDescription: action toMenu: applicationMenu];

//		NSString * keyPath = [NSString stringWithFormat: @"values.%@", [action objectForKey: TSSTPreferenceKey]];
		[[sharedDefaults defaults] addObserver: self forKeyPath: [action objectForKey: TSSTPreferenceKey] options: 0 context: nil];
	}
}

- (void)observeValueForKeyPath:(NSString *)keyPath
					  ofObject:(id)object
						change:(NSDictionary *)change
					   context:(void *)context
{
//	NSLog(keyPath);
	NSMenu * applicationMenu = [[NSApplication sharedApplication] mainMenu];
	NSUserDefaultsController * sharedDefaults = [NSUserDefaultsController sharedUserDefaultsController];
	NSArray * actions = [[self class] availableActions];
	NSArray * keys = [actions valueForKey: TSSTPreferenceKey];
	NSInteger index = [keys indexOfObject: keyPath];

	if(index != NSNotFound)
	{
		NSMutableDictionary * shortcutDescription = [NSMutableDictionary dictionaryWithDictionary: [actions objectAtIndex: index]];
		[shortcutDescription setValuesForKeysWithDictionary: [[sharedDefaults values] valueForKey: keyPath]];
//		NSLog([shortcutDescription description]);
		[[self class] applyEquivalentWithDescription: shortcutDescription toMenu: applicationMenu];
	}
}

@end


Garmin ECHOMAP Plus 65cv chartplotter features a 6-inch touchscreen with keyed-assist buttons for use in wet conditions. The Garmin ECHOMAP Plus 65cv when purchased from ActiveGPS comes preloaded with Bluechart with coverage for UK and Ireland.
The Garmin ECHOMAP Plus 65cv when purchased from ActiveGPS comes preloaded with Garmin Bluechart g2 HD UK and Ireland. The BlueChart coverage includes coasts for UK, Ireland, and Northern France coastal waters.
There is built-in support for Garmin high wide CHIRP traditional sonar plus CHIRP ClearVu and scanning sonars and Panoptix all-seeing sonar. (transducer sold separately). You will get crisp, clear images below your boat (ClearVu). Quickdraw Contours mapping software enables you to create personalised fishing maps on-screen with 1-foot contours as you fish. The sonar capabilities of the ECHOMAP 65cv enables you to see structure, submerged objects and fish. Clear target separation and definition provides more energy onto target than traditional sonar making sonar more effective.
To find the perfect transducer to partner your Garmin ECHOMAP Plus 65cv and your boat please complete our online transducer form. Alternatively, if you know which transducer your require (we do however recommend that you complete our online form to find the perfect transducer) you can view the comprehensive range of transducers available buy from ActiveGPS. Pictured below, transom mounted transducer, thru-hull transducer and in-hull transducer.
The Garmin ECHOMAP Plus 65cv when purchased from ActiveGPS comes preloaded with BlueChart g2 marine charts with coverage for UK and Ireland coastal waters. In addition customers buying the ECHOMAP Plus 65cv from ActiveGPS are entitled to one Free BlueChart g3 download within 12 months of purchase under Garmin's New Chart Guarantee.
Additional Garmin g3 Vision Bluecharts with more detailed information (than the standard BlueChart g3 charts) e.g. high resolution satellite imagery of harbours, ports, etc and auto guidance among other premium features are also available to buy from ActiveGPS and use with Garmin ECHOMAP Plus 65cv.
The Garmin ECHOMAP Plus 65cv comes complete with Tilt/Swivel Mount with Quick-release Cradle. The tilt/swivel mount surface mounts against most flat surfaces on your boat.
If required additional tilt/swivel mounts and other Garmin ECHOMAP Plus 65cv accessories can be purchased from ActiveGPS.
Garmin ECHOMAP Plus 65cv marine chartplotter is preloaded with BlueChart g2 marine charts with coverage for UK and Ireland. In addition, customers buying the ECHOMAP Plus 65cv from ActiveGPS are entitled to one Free BlueChart download within 12 months of purchase under Garmin's New Chart Guarantee.
Looking for Garmin ECHOMAP Plus 65cv accessories? Accessories available to purchase include 6-inch protective cover, flush mount kit and tilt/swivel mount. If you'd like to add a transducer to your ECHOMAP Plus 65cv please see the Garmin transducers buyer's guide.
Add Garmin BlueChart g3 and g3 Vision marine charts to your Garmin ECHOMAP Plus 65cv, view the different Garmin Bluecharts you can buy from ActiveGPS.


This 88 page, complete color, glossy travel guide is published annually and attributes a pull out map of the location. Whether you happen to be hunting for a 5-star hotel, or maybe more a 5-euro hostel, this pocket guide will set out all your alternatives in detail. Parents who want to prepare their children and teenagers for travels anywhere in the planet will find child-sufficient information in our Children Planet Travel Guide. Baedeker's ultimate aim was to free of charge the traveller from getting to appear for information anyplace outdoors the travel guide whether about routes, transport, accommodation, restaurants, tipping, sights, walks or costs. No glove box is full without it. Complimentary Travel Guide and Roadway Map incorporated. Prime members enjoy Totally free Two-Day Shipping and exclusive access to music, movies, Television shows, original audio series, and Kindle books.
Furthermore attempting to create something to cover all eventualities within the price range / independent travel context would be not possible. The official Nevada Visitor's Guide is an crucial tool for arranging your best trip ever to the Silver State. A 40-page, full color guide to 500+ Wisconsin events from September 1, 2016, via March 31, 2017. The travel guide is made for individual travellers, and tends to make arranging your vacation easier. Or try listening to audio travel books while touring to generate your personal, customized walking tour of a new city. This guide gives you the info you need to have to cruise through the state with the wind in your face.
If you are unable to total this type simply because of a disability or for any other explanation, please contact Discover Minnesota Tourism by email (explore@) or telephone (888-868-7476) to order any of our publications, or for further travel preparing help. The 2016 Official Ohio Travel Guide is available as a digital edition of the content material of both the Ohio Travel Guide and the Ohio Calendar of Events.
If you are totally new to travel or beginning to program a trip and just have no thought where to start off – this 1 web page guide is most likely the location for you. The Luxury Travel Awards recognise and celebrate excellence across all sectors of the affluent travel and tourism industry. Read Travel Illinois magazine on-line or download the PDF and commence exploring trip suggestions about Illinois. Call 1-800-561-0123 to speak one-on-a single with one of our beneficial New Brunswick travel consultants.
Travel to Africa and give in to the wild charm of the cradle of humanity, exactly where you are going to learn lively local populations and cultures that are every more fascinating than the last. All DK Eyewitness Travel city guidebooks include a pull-out map with street index, transportation maps, and even a lot more data on receiving around your next vacation location. Eugene Fodor , a Hungarian-born author of travel articles , who had emigrated to the United States prior to the war, wrote guidebooks which introduced English-reading audiences to continental Europe. Soon after Klein died, he decided to publish a new edition in 1839, to which he added several of his personal suggestions on what he believed a travel guide should supply the traveller. Our 120-page Visitor Guide provides insider guidelines and inventive concepts for enjoying the sports, dining and attractions that set Indy apart.


text:
Tryggare kan ingen vara är en psalm skriven av Lina Sandell cirka 1850 som hon bearbetade 1855, då den trycktes i Andeliga daggdroppar som hon gav ut anonymt. Inspirationen kom då hon som liten flicka en gång kröp upp i ett träd och såg fåglarnas väl dolda bon ("trygga nästet"). Kort efter att texten skrevs drunknade Lina Sandells far under en båtresa i hennes närvaro. Oscar Lövgren anger i sin bok om Lina Sandell att texten genom faderns oväntade död strax efter, symboliserade en slags föraning om vad som komma skulle, som kännetecknade Lina Sandell och även fadern vid flera tillfällen.

Tryggare kan ingen vara hette i den första versionen den Trygghet och i en andra version Guds barns trygghet. Enligt legenden satt hon upp i ett stort askträd intill prästgården när hon skrev sången.

Den publicerades i Herde-Rösten 1892 med fem verser, utan angiven författare. De i andra publikationer ingående sex verserna har kortats till fem från och med 1937 års psalmbok.

Psalmen är sannolikt den mest använda doppsalmen och den är också ganska vanlig som begravningspsalm.

Melodin uppges vara en svensk variant av tysk folkmelodi, men i Koralbok för Nya psalmer, 1921 anges två olika melodier, en a-melodi av Ivar Widéen från 1919 och den andra som "folkmelodi".

1925 fick sången en text på engelska, som heter Children of the Heavenly Father.

Inspelningar
Sången finns insjungen av Carola Häggkvist på albumet "Blott en dag" 1998.

Filmmusik
Sången används som filmmusik i filmen "Mer om oss barn i Bullerbyn" från 1987 .

Publikation
Lovsånger och andeliga visor 1877 som nr 87 med 10 verser och titeln "Guds barns trygghet".
Stockholms söndagsskolförenings sångbok 1882 som nr 51 under rubriken Sånger af allmänt innehåll, med fem verser och titeln "Guds barns trygghet".
Metodistkyrkans psalmbok 1896 nr 393, 6 verser, under rubriken "Kristi kyrka" i en version signerad Fr. Engelke.
Herde-Rösten 1892 som nr 45 under rubriken "Guds barns trygghet".
Svensk söndagsskolsångbok 1908 som nr 194 under rubriken "Guds barns trygghet"
Lilla Psalmisten 1909 som nr 89 under rubriken "Frälsningen".
Svenska Missionsförbundets sångbok 1920 som nr 326 under rubriken "Guds barns trygghet".
Nya psalmer 1921 som nr 622, tillägget till 1819 års psalmbok under rubriken "Det Kristliga Troslivet: Troslivet i hem och samhälle: Det kristna hemmet: Äkta makar + några okända rubriker".
Svensk söndagsskolsångbok 1929 som nr 134 under rubriken "Guds barns glädje och trygghet"
Frälsningsarméns sångbok 1929 som nr 356 under rubriken "Jubel, erfarenhet och vittnesbörd"
Psalm och Sång 1929/31, som nr 130 under rubriken "Trosvisshet och barnaskap"
Musik till Frälsningsarméns sångbok 1930 som nr 356
Segertoner 1930 som nr 345
Sionstoner 1935 som nr 352 under rubriken "Nådens ordning: Trosliv och helgelse".
Guds lov 1935 som nr 540 under rubriken "Barnsånger".
1937 års psalmbok som nr 513 under rubriken "Barn".
Segertoner 1960 som nr 344
Psalmer för bruk vid krigsmakten 1961 som nr 513, verserna 1-5.
Frälsningsarméns sångbok 1968 som nr 423 under rubriken " - Erfarenhet och vittnesbörd"
1986 års psalmbok 1986 års Cecilia-psalmbok, Psalmer och Sånger 1987, Segertoner 1988 och Frälsningsarméns sångbok 1990 under rubriken "Förtröstan - trygghet" som nr 248.
Lova Herren 1988 som nr 750 under rubriken "Barn och ungdom".
Svensk psalmbok för den evangelisk-lutherska kyrkan i Finland (1986) som nr 390 under rubriken "Tro och trygghet"
Barnens svenska sångbok, 1999, under rubriken "Hemma i världen".
Hela familjens psalmbok 2013 som nummer 22 under rubriken "Gud tycker om oss".

Missuppfattningar
Enligt boken Det är saligt att samla citron har en del barn trott att texten varit:
Bryggare kan ingen vara
Trygga räkan (kan) ingen vara
Tryggare kan ingen vara, än Guds lilla barn i Skara

Referenser

Externa länkar
Hos Svenska Akademien återfinns psalmtexten från 1937 i "Den gamla psalmboken" i PDF
Hos Cyber hymnal finns den engelska översättningen samt ljudfil till melodin:
 Engelsk version
 Svensk version
Hos Projekt Runeberg finns noterna till melodin.
Hos Youtube finns film- och ljudinspelningar

Filmlåtar
Svenska barnvisor
Svenska psalmer
Barnpsalmer
Verk av Lina Sandell
1850-talets sånger