"""Pure python implementation of the binary Tokyo Tyrant 1.1.17 protocol

Tokyo Cabinet <http://tokyocabinet.sourceforge.net/> is a "super hyper ultra
database manager" written and maintained by Mikio Hirabayashi and released
under the LGPL.

Tokyo Tyrant is the de facto database server for Tokyo Cabinet written and
maintained by the same author. It supports a REST HTTP protocol, memcached,
and its own simple binary protocol. This library implements the full binary
protocol for the Tokyo Tyrant 1.1.17 in pure Python as defined here::

    http://tokyocabinet.sourceforge.net/tyrantdoc/

Typical usage is with the PyTyrant class which provides a dict-like wrapper
for the raw Tyrant protocol::

    >>> import pytyrant
    >>> t = pytyrant.PyTyrant.open('127.0.0.1', 1978)
    >>> t['__test_key__'] = 'foo'
    >>> t.concat('__test_key__', 'bar')
    >>> print t['__test_key__']
    foobar
    >>> del t['__test_key__']

"""
import math
import socket
import struct
import UserDict

__version__ = '1.1.17'

__all__ = [
    'Tyrant', 'TyrantError', 'PyTyrant',
    'RDBMONOULOG', 'RDBXOLCKREC', 'RDBXOLCKGLB',
]

class TyrantError(Exception):
    pass

DEFAULT_PORT = 1978
MAGIC = 0xc8

RDBMONOULOG = 1 << 0
RDBXOLCKREC = 1 << 0
RDBXOLCKGLB = 1 << 1

class C(object):
    """
    Tyrant Protocol constants
    """
    put = 0x10
    putkeep = 0x11
    putcat = 0x12
    putshl = 0x13
    putnr = 0x18
    out = 0x20
    get = 0x30
    mget = 0x31
    vsiz = 0x38
    iterinit = 0x50
    iternext = 0x51
    fwmkeys = 0x58
    addint = 0x60
    adddouble = 0x61
    ext = 0x68
    sync = 0x70
    vanish = 0x71
    copy = 0x72
    restore = 0x73
    setmst = 0x78
    rnum = 0x80
    size = 0x81
    stat = 0x88
    misc = 0x90

def _t0(code):
    return [chr(MAGIC) + chr(code)]

def _t1(code, key):
    return [
        struct.pack('>BBI', MAGIC, code, len(key)),
        key,
    ]

def _t1FN(code, func, opts, args):
    outlst = [
        struct.pack('>BBIII', MAGIC, code, len(func), opts, len(args)),
        func,
    ]
    for k in args:
        outlst.extend([struct.pack('>I', len(k)), k])
    return outlst

def _t1R(code, key, msec):
    return [
        struct.pack('>BBIQ', MAGIC, code, len(key), msec),
        key,
    ]

def _t1M(code, key, count):
    return [
        struct.pack('>BBII', MAGIC, code, len(key), count),
        key,
    ]

def _tN(code, klst):
    outlst = [struct.pack('>BBI', MAGIC, code, len(klst))]
    for k in klst:
        outlst.extend([struct.pack('>I', len(k)), k])
    return outlst

def _t2(code, key, value):
    return [
        struct.pack('>BBII', MAGIC, code, len(key), len(value)),
        key,
        value,
    ]

def _t2W(code, key, value, width):
    return [
        struct.pack('>BBIII', MAGIC, code, len(key), len(value), width),
        key,
        value,
    ]

def _t3F(code, func, opts, key, value):
    return [
        struct.pack('>BBIIII', MAGIC, code, len(func), opts, len(key), len(value)),
        func,
        key,
        value,
    ]

def _tDouble(code, key, integ, fract):
    return [
        struct.pack('>BBIQQ', MAGIC, code, len(key), integ, fract),
        key,
    ]

def socksend(sock, lst):
    sock.sendall(''.join(lst))

def sockrecv(sock, bytes):
    d = ''
    while len(d) < bytes:
        c = sock.recv(min(8192, bytes - len(d)))
        if not c:
            raise TyrantError('Connection closed')
        d += c
    return d

def socksuccess(sock):
    fail_code = ord(sockrecv(sock, 1))
    if fail_code:
        raise TyrantError(fail_code)

def socklen(sock):
    return struct.unpack('>I', sockrecv(sock, 4))[0]

def socklong(sock):
    return struct.unpack('>Q', sockrecv(sock, 8))[0]

def sockstr(sock):
    return sockrecv(sock, socklen(sock))

def sockdouble(sock):
    intpart, fracpart = struct.unpack('>QQ', sockrecv(sock, 16))
    return intpart + (fracpart * 1e-12)

def sockstrpair(sock):
    klen = socklen(sock)
    vlen = socklen(sock)
    k = sockrecv(sock, klen)
    v = sockrecv(sock, vlen)
    return k, v

class PyTyrant(object, UserDict.DictMixin):
    """
    Dict-like proxy for a Tyrant instance
    """
    @classmethod
    def open(cls, *args, **kw):
        return cls(Tyrant.open(*args, **kw))

    def __init__(self, t):
        self.t = t

    def __repr__(self):
        # The __repr__ for UserDict.DictMixin isn't desirable
        # for a large KV store :)
        return object.__repr__(self)

    def has_key(self, key):
        return key in self

    def __contains__(self, key):
        try:
            self.t.vsiz(key)
        except TyrantError:
            return False
        else:
            return True

    def setdefault(self, key, value):
        try:
            self.t.putkeep(key, value)
        except TyrantError:
            return self[key]
        return value

    def __setitem__(self, key, value):
        self.t.put(key, value)

    def __getitem__(self, key):
        try:
            return self.t.get(key)
        except TyrantError:
            raise KeyError(key)

    def __delitem__(self, key):
        try:
            self.t.out(key)
        except TyrantError:
            raise KeyError(key)

    def __iter__(self):
        return self.iterkeys()

    def iterkeys(self):
        self.t.iterinit()
        try:
            while True:
                yield self.t.iternext()
        except TyrantError:
            pass

    def keys(self):
        return list(self.iterkeys())

    def __len__(self):
        return self.t.rnum()

    def clear(self):
        self.t.vanish()

    def update(self, other=None, **kwargs):
        # Make progressively weaker assumptions about "other"
        if other is None:
            pass
        elif hasattr(other, 'iteritems'):
            self.multi_set(other.iteritems())
        elif hasattr(other, 'keys'):
            self.multi_set([(k, other[k]) for k in other.keys()])
        else:
            self.multi_set(other)
        if kwargs:
            self.update(kwargs)

    def multi_del(self, keys, no_update_log=False):
        opts = (no_update_log and RDBMONOULOG or 0)
        if not isinstance(keys, (list, tuple)):
            keys = list(keys)
        self.t.misc("outlist", opts, keys)

    def multi_get(self, keys, no_update_log=False):
        opts = (no_update_log and RDBMONOULOG or 0)
        if not isinstance(keys, (list, tuple)):
            keys = list(keys)
        rval = self.t.misc("getlist", opts, keys)
        if len(rval) <= len(keys):
            # 1.1.10 protocol, may return invalid results
            if len(rval) < len(keys):
                raise KeyError("Missing a result, unusable response in 1.1.10")
            return rval
        # 1.1.11 protocol returns interleaved key, value list
        d = dict((rval[i], rval[i + 1]) for i in xrange(0, len(rval), 2))
        return map(d.get, keys)

    def multi_set(self, items, no_update_log=False):
        opts = (no_update_log and RDBMONOULOG or 0)
        lst = []
        for k, v in items:
            lst.extend((k, v))
        self.t.misc("putlist", opts, lst)

    def call_func(self, func, key, value, record_locking=False, global_locking=False):
        opts = (
            (record_locking and RDBXOLCKREC or 0) |
            (global_locking and RDBXOLCKGLB or 0))
        return self.t.ext(func, opts, key, value)

    def get_size(self, key):
        try:
            return self.t.vsiz(key)
        except TyrantError:
            raise KeyError(key)

    def get_stats(self):
        return dict(l.split('\t', 1) for l in self.t.stat().splitlines() if l)

    def prefix_keys(self, prefix, maxkeys=None):
        if maxkeys is None:
            maxkeys = len(self)
        return self.t.fwmkeys(prefix, maxkeys)

    def concat(self, key, value, width=None):
        if width is None:
            self.t.putcat(key, value)
        else:
            self.t.putshl(key, value, width)

    def sync(self):
        self.t.sync()

    def close(self):
        self.t.close()

class Tyrant(object):
    @classmethod
    def open(cls, host='127.0.0.1', port=DEFAULT_PORT, timeout=3.0):
        sock = socket.socket()
        sock.settimeout(timeout)
        sock.connect((host, port))
        sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
        return cls(sock)

    def __init__(self, sock):
        self.sock = sock

    def close(self):
        self.sock.close()

    def put(self, key, value):
        """Unconditionally set key to value
        """
        socksend(self.sock, _t2(C.put, key, value))
        socksuccess(self.sock)

    def putkeep(self, key, value):
        """Set key to value if key does not already exist
        """
        socksend(self.sock, _t2(C.putkeep, key, value))
        socksuccess(self.sock)

    def putcat(self, key, value):
        """Append value to the existing value for key, or set key to
        value if it does not already exist
        """
        socksend(self.sock, _t2(C.putcat, key, value))
        socksuccess(self.sock)

    def putshl(self, key, value, width):
        """Equivalent to::

            self.putcat(key, value)
            self.put(key, self.get(key)[-width:])
        """
        socksend(self.sock, _t2W(C.putshl, key, value, width))
        socksuccess(self.sock)

    def putnr(self, key, value):
        """Set key to value without waiting for a server response
        """
        socksend(self.sock, _t2(C.putnr, key, value))

    def out(self, key):
        """Remove key from server
        """
        socksend(self.sock, _t1(C.out, key))
        socksuccess(self.sock)

    def get(self, key):
        """Get the value of a key from the server
        """
        socksend(self.sock, _t1(C.get, key))
        socksuccess(self.sock)
        return sockstr(self.sock)

    def _mget(self, klst):
        socksend(self.sock, _tN(C.mget, klst))
        socksuccess(self.sock)
        numrecs = socklen(self.sock)
        for i in xrange(numrecs):
            k, v = sockstrpair(self.sock)
            yield k, v

    def mget(self, klst):
        """Get key,value pairs from the server for the given list of keys
        """
        return list(self._mget(klst))

    def vsiz(self, key):
        """Get the size of a value for key
        """
        socksend(self.sock, _t1(C.vsiz, key))
        socksuccess(self.sock)
        return socklen(self.sock)

    def iterinit(self):
        """Begin iteration over all keys of the database
        """
        socksend(self.sock, _t0(C.iterinit))
        socksuccess(self.sock)

    def iternext(self):
        """Get the next key after iterinit
        """
        socksend(self.sock, _t0(C.iternext))
        socksuccess(self.sock)
        return sockstr(self.sock)

    def _fwmkeys(self, prefix, maxkeys):
        socksend(self.sock, _t1M(C.fwmkeys, prefix, maxkeys))
        socksuccess(self.sock)
        numkeys = socklen(self.sock)
        for i in xrange(numkeys):
            yield sockstr(self.sock)

    def fwmkeys(self, prefix, maxkeys):
        """Get up to the first maxkeys starting with prefix
        """
        return list(self._fwmkeys(prefix, maxkeys))

    def addint(self, key, num):
        socksend(self.sock, _t1M(C.addint, key, num))
        socksuccess(self.sock)
        return socklen(self.sock)

    def adddouble(self, key, num):
        fracpart, intpart = math.modf(num)
        fracpart, intpart = int(fracpart * 1e12), int(intpart)
        socksend(self.sock, _tDouble(C.adddouble, key, fracpart, intpart))
        socksuccess(self.sock)
        return sockdouble(self.sock)

    def ext(self, func, opts, key, value):
        # tcrdbext opts are RDBXOLCKREC, RDBXOLCKGLB
        """Call func(key, value) with opts

        opts is a bitflag that can be RDBXOLCKREC for record locking
        and/or RDBXOLCKGLB for global locking"""
        socksend(self.sock, _t3F(C.ext, func, opts, key, value))
        socksuccess(self.sock)
        return sockstr(self.sock)

    def sync(self):
        """Synchronize the database
        """
        socksend(self.sock, _t0(C.sync))
        socksuccess(self.sock)

    def vanish(self):
        """Remove all records
        """
        socksend(self.sock, _t0(C.vanish))
        socksuccess(self.sock)

    def copy(self, path):
        """Hot-copy the database to path
        """
        socksend(self.sock, _t1(C.copy, path))
        socksuccess(self.sock)

    def restore(self, path, msec):
        """Restore the database from path at timestamp (in msec)
        """
        socksend(self.sock, _t1R(C.copy, path, msec))
        socksuccess(self.sock)

    def setmst(self, host, port):
        """Set master to host:port
        """
        socksend(self.sock, _t1M(C.setmst, host, port))
        socksuccess(self.sock)

    def rnum(self):
        """Get the number of records in the database
        """
        socksend(self.sock, _t0(C.rnum))
        socksuccess(self.sock)
        return socklong(self.sock)

    def size(self):
        """Get the size of the database
        """
        socksend(self.sock, _t0(C.size))
        socksuccess(self.sock)
        return socklong(self.sock)

    def stat(self):
        """Get some statistics about the database
        """
        socksend(self.sock, _t0(C.stat))
        socksuccess(self.sock)
        return sockstr(self.sock)

    def _misc(self, func, opts, args):
        # tcrdbmisc opts are RDBMONOULOG
        socksend(self.sock, _t1FN(C.misc, func, opts, args))
        try:
            socksuccess(self.sock)
        finally:
            numrecs = socklen(self.sock)
        for i in xrange(numrecs):
            yield sockstr(self.sock)

    def misc(self, func, opts, args):
        """All databases support "putlist", "outlist", and "getlist".
        "putlist" is to store records. It receives keys and values one after the other, and returns an empty list.
        "outlist" is to remove records. It receives keys, and returns an empty list.
        "getlist" is to retrieve records. It receives keys, and returns values.

        Table database supports "setindex", "search", "genuid".

        opts is a bitflag that can be RDBMONOULOG to prevent writing to the update log
        """
        return list(self._misc(func, opts, args))

def main():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    main()


from datetime import datetime, timedelta

import curator

from . import CuratorTestCase

class TestTimeBasedDeletion(CuratorTestCase):
    def test_curator_will_properly_delete_indices(self):
        self.create_indices(10)
        self.run_curator(delete_older=3)
        mtd = self.client.cluster.state(index=self.args['prefix'] + '*', metric='metadata')
        self.assertEquals(4, len(mtd['metadata']['indices'].keys()))

    def test_curator_will_properly_delete_hourly_indices(self):
        self.create_indices(10, 'hours')
        self.run_curator(delete_older=3, time_unit='hours')
        mtd = self.client.cluster.state(index=self.args['prefix'] + '*', metric='metadata')
        self.assertEquals(4, len(mtd['metadata']['indices'].keys()))

class TestFindExpiredIndices(CuratorTestCase):
    def test_find_indices_ignores_indices_with_different_prefix_or_time_unit(self):
        self.create_index('logstash-2012.01.01')        # wrong precision
        self.create_index('not-logstash-2012.01.01.00') # wrong prefix
        self.create_index('logstash-2012.01.01.00')

        expired = list(curator.find_expired_indices(self.client, 'hours', 1))
        self.assertEquals(1, len(expired))
        self.assertEquals('logstash-2012.01.01.00', expired[0][0])

    def test_find_reports_correct_time_interval_from_cutoff(self):
        self.create_index('l-2014.01.01')
        self.create_index('l-2014.01.02')
        # yesterday is always save since we reset to mignight and do <, not <=
        self.create_index('l-2014.01.03')

        expired = list(curator.find_expired_indices(self.client, 'days', 1,
            utc_now=datetime(2014, 1, 4, 3, 45, 50), prefix='l-'))
        self.assertEquals(
            [
                (u'l-2014.01.01', timedelta(2)),
                (u'l-2014.01.02', timedelta(1))
            ],
            expired
        )


from __future__ import print_function, absolute_import, nested_scopes, generators, division, with_statement, unicode_literals
import logging

from hytra.core.ilastik_project_options import IlastikProjectOptions
from hytra.jst.conflictingsegmentsprobabilitygenerator import ConflictingSegmentsProbabilityGenerator
from hytra.core.ilastikhypothesesgraph import IlastikHypothesesGraph
from hytra.core.fieldofview import FieldOfView

try:
    import multiHypoTracking_with_cplex as mht
except ImportError:
    try:
        import multiHypoTracking_with_gurobi as mht
    except ImportError:
        mht = None
        import dpct

def constructFov(shape, t0, t1, scale=[1, 1, 1]):
    [xshape, yshape, zshape] = shape
    [xscale, yscale, zscale] = scale

    fov = FieldOfView(t0, 0, 0, 0, t1, xscale * (xshape - 1), yscale * (yshape - 1),
                      zscale * (zshape - 1))
    return fov

# def test_twoSegmentations():
#     # set up ConflictingSegmentsProbabilityGenerator
#     ilpOptions = IlastikProjectOptions()
#     ilpOptions.divisionClassifierPath = None
#     ilpOptions.divisionClassifierFilename = None

#     ilpOptions.rawImageFilename = 'tests/multiSegmentationHypothesesTestDataset/Raw.h5'
#     ilpOptions.rawImagePath = 'exported_data'
#     ilpOptions.rawImageAxes = 'txyzc'

#     ilpOptions.labelImageFilename = 'tests/multiSegmentationHypothesesTestDataset/segmentation.h5'

#     ilpOptions.objectCountClassifierFilename = 'tests/multiSegmentationHypothesesTestDataset/tracking.ilp'

#     additionalLabelImageFilenames = ['tests/multiSegmentationHypothesesTestDataset/segmentationAlt.h5']
#     additionalLabelImagePaths = [ilpOptions.labelImagePath]

#     probabilityGenerator = ConflictingSegmentsProbabilityGenerator(
#         ilpOptions,
#         additionalLabelImageFilenames,
#         additionalLabelImagePaths,
#         useMultiprocessing=False,
#         verbose=False)
#     probabilityGenerator.fillTraxels(usePgmlink=False)

#     assert(len(probabilityGenerator.TraxelsPerFrame[0]) == 4)
#     assert(len(probabilityGenerator.TraxelsPerFrame[1]) == 3)
#     assert(len(probabilityGenerator.TraxelsPerFrame[2]) == 3)
#     assert(len(probabilityGenerator.TraxelsPerFrame[3]) == 4)
#     filenamesPerTraxel = [t.segmentationFilename for t in probabilityGenerator.TraxelsPerFrame[3].values()]
#     idsPerTraxel = [t.idInSegmentation for t in probabilityGenerator.TraxelsPerFrame[3].values()]
#     assert(idsPerTraxel.count(1) == 2)
#     assert(idsPerTraxel.count(2) == 2)
#     assert(filenamesPerTraxel.count('tests/multiSegmentationHypothesesTestDataset/segmentation.h5') == 2)
#     assert(filenamesPerTraxel.count('tests/multiSegmentationHypothesesTestDataset/segmentationAlt.h5') == 2)

#     # build hypotheses graph, check that conflicting traxels are properly detected
#     fieldOfView = constructFov(probabilityGenerator.shape,
#                                probabilityGenerator.timeRange[0],
#                                probabilityGenerator.timeRange[1],
#                                [probabilityGenerator.x_scale,
#                                 probabilityGenerator.y_scale,
#                                 probabilityGenerator.z_scale])

#     hypotheses_graph = IlastikHypothesesGraph(
#         probabilityGenerator=probabilityGenerator,
#         timeRange=probabilityGenerator.timeRange,
#         maxNumObjects=1,
#         numNearestNeighbors=2,
#         fieldOfView=fieldOfView,
#         withDivisions=False,
#         divisionThreshold=0.1
#     )

#     assert(hypotheses_graph.countNodes() == 14)
#     assert(hypotheses_graph.countArcs() == 23)
#     assert(hypotheses_graph._graph.node[(0, 1)]['traxel'].conflictingTraxelIds == [3])
#     assert(hypotheses_graph._graph.node[(0, 3)]['traxel'].conflictingTraxelIds == [1])
#     assert(hypotheses_graph._graph.node[(0, 2)]['traxel'].conflictingTraxelIds == [4])
#     assert(hypotheses_graph._graph.node[(0, 4)]['traxel'].conflictingTraxelIds == [2])
#     assert(hypotheses_graph._graph.node[(1, 1)]['traxel'].conflictingTraxelIds == [2, 3])
#     assert(hypotheses_graph._graph.node[(1, 2)]['traxel'].conflictingTraxelIds == [1])
#     assert(hypotheses_graph._graph.node[(1, 3)]['traxel'].conflictingTraxelIds == [1])

#     # track, but check that the right exclusion constraints are present
#     hypotheses_graph.insertEnergies()
#     trackingGraph = hypotheses_graph.toTrackingGraph()

#     assert(len(trackingGraph.model['exclusions']) == 8)
#     for exclusionSet in trackingGraph.model['exclusions']:
#         assert(len(exclusionSet) == 2)

#     # use multiHypoTracking, insert exclusion constraints!
#     if mht is not None:
#         result = mht.track(trackingGraph.model, {"weights": [10, 10, 500, 500]})
#     else:
#         return
#         # standard dpct cannot handle exclusion constraints yet
#         result = dpct.trackFlowBased(trackingGraph.model, {"weights": [10, 10, 500, 500]})

#     hypotheses_graph.insertSolution(result)
#     # hypotheses_graph.computeLineage()

#     numActivePerFrame = {}

#     for node in hypotheses_graph.nodeIterator():
#         timeframe = node[0]
#         if 'value' in hypotheses_graph._graph.node[node]:
#             value = hypotheses_graph._graph.node[node]['value']
#         else:
#             value = 0
#         numActivePerFrame.setdefault(timeframe, []).append(value)

#     for _, v in numActivePerFrame.items():
#         assert(sum(v) == 2)

#     edgeFlow = 0
#     for edge in hypotheses_graph.arcIterator():
#         if 'value' in hypotheses_graph._graph.edge[edge[0]][edge[1]]:
#             edgeFlow += hypotheses_graph._graph.edge[edge[0]][edge[1]]['value']
#     assert(edgeFlow == 6)

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)
    test_twoSegmentations()


from dis import dis
from io import StringIO
from itertools import product, chain
import random
import sys

import pytest

from codetransformer.code import Code, Flag, pycode
from codetransformer.instructions import LOAD_CONST, LOAD_FAST, uses_free

@pytest.fixture(scope='module')
def sample_flags(request):
    random.seed(8025816322119661921)  # ayy lmao
    nflags = len(Flag.__members__)
    return tuple(
        dict(zip(Flag.__members__.keys(), case)) for case in chain(
            random.sample(list(product((True, False), repeat=nflags)), 1000),
            [[True] * nflags],
            [[False] * nflags],
        )
    )

def test_lnotab_roundtrip():
    # DO NOT ADD EXTRA LINES HERE
    def f():  # pragma: no cover
        a = 1
        b = 2
        c = 3
        d = 4
        a, b, c, d

    start_line = test_lnotab_roundtrip.__code__.co_firstlineno + 3
    lines = [start_line + n for n in range(5)]
    code = Code.from_pycode(f.__code__)
    lnotab = code.lnotab
    assert lnotab.keys() == set(lines)
    assert isinstance(lnotab[lines[0]], LOAD_CONST)
    assert lnotab[lines[0]].arg == 1
    assert isinstance(lnotab[lines[1]], LOAD_CONST)
    assert lnotab[lines[1]].arg == 2
    assert isinstance(lnotab[lines[2]], LOAD_CONST)
    assert lnotab[lines[2]].arg == 3
    assert isinstance(lnotab[lines[3]], LOAD_CONST)
    assert lnotab[lines[3]].arg == 4
    assert isinstance(lnotab[lines[4]], LOAD_FAST)
    assert lnotab[lines[4]].arg == 'a'
    assert f.__code__.co_lnotab == code.py_lnotab == code.to_pycode().co_lnotab

def test_lnotab_really_dumb_whitespace():
    ns = {}
    exec('def f():\n    lol = True' + '\n' * 1024 + '    wut = True', ns)
    f = ns['f']
    code = Code.from_pycode(f.__code__)
    lines = [2, 1026]
    lnotab = code.lnotab
    assert lnotab.keys() == set(lines)
    assert isinstance(lnotab[lines[0]], LOAD_CONST)
    assert lnotab[lines[0]].arg
    assert isinstance(lnotab[lines[1]], LOAD_CONST)
    assert lnotab[lines[1]].arg
    assert f.__code__.co_lnotab == code.py_lnotab == code.to_pycode().co_lnotab

def test_flag_packing(sample_flags):
    for flags in sample_flags:
        assert Flag.unpack(Flag.pack(**flags)) == flags

def test_flag_unpack_too_big():
    assert all(Flag.unpack(Flag.max).values())
    with pytest.raises(ValueError):
        Flag.unpack(Flag.max + 1)

def test_flag_max():
    assert Flag.pack(
        CO_OPTIMIZED=True,
        CO_NEWLOCALS=True,
        CO_VARARGS=True,
        CO_VARKEYWORDS=True,
        CO_NESTED=True,
        CO_GENERATOR=True,
        CO_NOFREE=True,
        CO_COROUTINE=True,
        CO_ITERABLE_COROUTINE=True,
        CO_FUTURE_DIVISION=True,
        CO_FUTURE_ABSOLUTE_IMPORT=True,
        CO_FUTURE_WITH_STATEMENT=True,
        CO_FUTURE_PRINT_FUNCTION=True,
        CO_FUTURE_UNICODE_LITERALS=True,
        CO_FUTURE_BARRY_AS_BDFL=True,
        CO_FUTURE_GENERATOR_STOP=True,
    ) == Flag.max

def test_flag_max_immutable():
    with pytest.raises(AttributeError):
        Flag.CO_OPTIMIZED.max = None

def test_code_multiple_varargs():
    with pytest.raises(ValueError) as e:
        Code(
            (), (
                '*args',
                '*other',
            ),
        )

    assert str(e.value) == 'cannot specify *args more than once'

def test_code_multiple_kwargs():
    with pytest.raises(ValueError) as e:
        Code(
            (), (
                '**kwargs',
                '**kwargs',
            ),
        )

    assert str(e.value) == 'cannot specify **kwargs more than once'

@pytest.mark.parametrize('cls', uses_free)
def test_dangling_var(cls):
    instr = cls('dangling')
    with pytest.raises(ValueError) as e:
        Code((instr,))

    assert (
        str(e.value) ==
        "Argument to %r is not in cellvars or freevars." % instr
    )

def test_code_flags(sample_flags):
    attr_map = {
        'CO_NESTED': 'is_nested',
        'CO_GENERATOR': 'is_generator',
        'CO_COROUTINE': 'is_coroutine',
        'CO_ITERABLE_COROUTINE': 'is_iterable_coroutine',
        'CO_NEWLOCALS': 'constructs_new_locals',
    }
    for flags in sample_flags:
        if sys.version_info < (3, 6):
            codestring = b'd\x00\x00S'  # return None
        else:
            codestring = b'd\x00S'  # return None

        code = Code.from_pycode(pycode(
            argcount=0,
            kwonlyargcount=0,
            nlocals=2,
            stacksize=0,
            flags=Flag.pack(**flags),
            codestring=codestring,
            constants=(None,),
            names=(),
            varnames=('a', 'b'),
            filename='',
            name='',
            firstlineno=0,
            lnotab=b'',
        ))
        assert code.flags == flags
        for flag, attr in attr_map.items():
            if flags[flag]:
                assert getattr(code, attr)

@pytest.fixture
def abc_code():
    a = LOAD_CONST('a')
    b = LOAD_CONST('b')
    c = LOAD_CONST('c')  # not in instrs
    code = Code((a, b), argnames=())

    return (a, b, c), code

def test_instr_index(abc_code):
    (a, b, c), code = abc_code

    assert code.index(a) == 0
    assert code.index(b) == 1

    with pytest.raises(ValueError):
        code.index(c)

def test_code_contains(abc_code):
    (a, b, c), code = abc_code

    assert a in code
    assert b in code
    assert c not in code

def test_code_dis(capsys):
    @Code.from_pyfunc
    def code():  # pragma: no cover
        a = 1
        b = 2
        return a, b

    buf = StringIO()
    dis(code.to_pycode(), file=buf)
    expected = buf.getvalue()

    code.dis()
    out, err = capsys.readouterr()
    assert not err
    assert out == expected

    buf = StringIO()
    code.dis(file=buf)
    assert buf.getvalue() == expected


# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------

from enum import Enum, EnumMeta
from six import with_metaclass

class _CaseInsensitiveEnumMeta(EnumMeta):
    def __getitem__(self, name):
        return super().__getitem__(name.upper())

    def __getattr__(cls, name):
        """Return the enum member matching `name`
        We use __getattr__ instead of descriptors or inserting into the enum
        class' __dict__ in order to support `name` and `value` being both
        properties for enum members (which live in the class' __dict__) and
        enum members themselves.
        """
        try:
            return cls._member_map_[name.upper()]
        except KeyError:
            raise AttributeError(name)

class LockLevel(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)):
    """The lock level of the management lock.
    """

    NOT_SPECIFIED = "NotSpecified"
    CAN_NOT_DELETE = "CanNotDelete"
    READ_ONLY = "ReadOnly"


from sourcer import Grammar

# This is work in progress.
# See: https://help.salesforce.com/articleView?id=customize_functions.htm&type=5

g = Grammar(r'''
    ```
    import ast
    ```

    start = Expression

    Expression = OperatorPrecedence(
        Atom | "(" >> Expression << ")",
        Postfix(ArgumentList | FieldAccess),
        Prefix("-" | "+" | "!"),
        RightAssoc("^"),
        LeftAssoc("*" | "/"),
        LeftAssoc("+" | "-" | "&"),
        NonAssoc("<=" | "<" | ">=" | ">"),
        NonAssoc("!=" | "<>" | "==" | "="),
        LeftAssoc("&&"),
        LeftAssoc("||"),
    )

    class ArgumentList {
        arguments: "(" >> (Expression /? ",") << ")"
    }

    class FieldAccess {
        field: "." >> Word
    }

    Atom = Global | Identifier | Rational | Integer | String

    class Global {
        name: "$" >> Word
    }

    class Identifier {
        name: Word
    }

    # ASK: What is the real syntax for these things?
    Word = /[_a-zA-Z][_a-zA-Z0-9]*/
    Rational = /(\d+\.\d*)|(\d*\.\d+)/ |> `float`
    Integer = /\d+/ |> `int`
    StringLiteral = /("([^"\\]|\\.)*")/ | /('([^'\\]|\\.)*')/

    # For now, just use ast module to evaluate string literals.
    class String {
        value: StringLiteral |> `ast.literal_eval`
    }

    ignore /\s+/

''', include_source=True)

aliases = {
    '=': '==',
    '<>': '!=',
}

constants = {
    'NULL': None,
    'TRUE': True,
    'FALSE': False,
}

# Incomplete collection of evaluators.
evaluators = {
    '*': lambda x, y: x * y if x is not None and y is not None else None,
    '/': lambda x, y: x / y if x is not None and y is not None else None,
    '+': lambda x, y: x + y if x is not None and y is not None else None,
    '-': lambda x, y: x - y if x is not None and y is not None else None,
    '==': lambda x, y: x == y,
    '!=': lambda x, y: x != y,
    '&&': lambda x, y: x and y,
    '||': lambda x, y: x or y,
    '>': lambda x, y: x > y if x is not None and y is not None else False,
    '<': lambda x, y: x < y if x is not None and y is not None else False,
    '>=': lambda x, y: x >= y if x is not None and y is not None else False,
    '<=': lambda x, y: x <= y if x is not None and y is not None else False,
    'AND': lambda *a: all(a),
    'CONTAINS': lambda x, y: str(y) in str(x) if x is not None else True,
    'IF': lambda x, y, z: y if x else z,
    'ISBLANK': lambda x: x is None,
    'LOG': lambda x: log10(x) if x is not None else None,
    'MAX': lambda *a: max(*a),
    'MIN': lambda *a: min(*a),
    'MOD': lambda x, y: (x % y) if x is not None and y is not None else None,
    'NOT': lambda x: not(x),
    'OR': lambda *a: any(a),
    'SQRT': lambda x: sqrt(x) if x is not None else None,
    'TEXT': lambda x: str(x),
}

def evaluate(node, bindings):
    # Look up identifiers.
    if isinstance(node, g.Identifier):
        if node.name in bindings:
            return bindings[node.name]

        name = node.name.upper()
        return bindings.get(name, name)

    # Look up fields.
    if isinstance(node, g.Postfix) and isinstance(node.operator, g.FieldAccess):
        obj, field = node.left, node.operator.field
        if hasattr(obj, field):
            return getattr(obj, field)
        elif isinstance(obj, dict):
            return obj.get(field)
        else:
            return node

    # Evaluate function calls and operators.
    if isinstance(node, g.Infix):
        x, func, y = node.left, node.operator, node.right
        args = (x, y)
    elif isinstance(node, g.Postfix) and isinstance(node.operator, g.ArgumentList):
        func, args = node.left, node.operator.arguments
    else:
        return node

    # Check if we're using an alias.
    func = aliases.get(func, func)

    if func in evaluators:
        return evaluators[func](*args)
    else:
        return node

def run(formula, bindings=None):
    updated_bindings = dict(constants)
    updated_bindings.update(bindings or {})
    tree = g.parse(formula)
    return g.transform(tree, lambda node: evaluate(node, updated_bindings))

def test_some_simple_formulas():
    result = run('1 + 2 * 3')
    assert result == 7

    result = run('foo == bar && fiz == buz', bindings={
        'foo': 1, 'bar': 1, 'fiz': 2, 'buz': 2,
    })
    assert result == True

    result = run('foo == bar && fiz == buz', bindings={
        'foo': 1, 'bar': 1, 'fiz': 2, 'buz': 3,
    })
    assert result == False

    result = run('1 <= 2 && (false || true)')
    assert result == True # Explicitly compare to True.

    result = run('1 > 2 || (true && false)')
    assert result == False # Explicitly compare to False.

    result = run('foo != bar', bindings={'foo': 10, 'bar': 10})
    assert not result

    result = run('foo != bar', bindings={'foo': 1, 'bar': 2})
    assert result

    result = run('foo.bar', bindings={'foo': {'bar': 10}})
    assert result == 10

    result = run('foo.bar.baz', bindings={'foo': {'bar': {'baz': 100}}})
    assert result == 100

    result = run('MIN(20, 10, 30)')
    assert result == 10

    result = run('MIN(20, 10, 30) + MAX(11, 12, 13)')
    assert result == 23


## Copyright 2003-2009 Luc Saffre
## This file is part of the TimTools project.
## TimTools is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## TimTools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with TimTools; if not, see <http://www.gnu.org/licenses/>.

import re

def plain2xml(txt):
   txt = txt.replace("&","&")
   txt = txt.replace("<","<")
   return txt

memocommands = (
   ( re.compile('\[url\s+(\S+)\s*(.*?)\]',re.DOTALL),
     lambda m : ''+m.group(2)+' (' + m.group(1)+ ')'),
   )
# urlfind =
# urlrepl = re.compile('\2 (\1)')

# def urlrepl(m):

def memo2xml(txt):
   txt = plain2xml(txt)
   txt = txt.replace('[B]','')
   txt = txt.replace('[b]','')
   txt = txt.replace('[U]','')
   txt = txt.replace('[u]','')
   for find,repl in memocommands:
      txt = re.sub(find,repl,txt)
   return txt

def rst2xml(txt):
   raise "doesn't work"
   import docutils.parsers.rst
   import docutils.utils
   parser = docutils.parsers.rst.Parser()
   doc = docutils.utils.new_document("feed")
   parser.parse(txt, doc)
   raise "and now?"

_feeders={
   'xml' : lambda x : x,
   'plain' : plain2xml,
   'rst' : rst2xml,
   'memo' : memo2xml,
   }

def getFeeder(name):
   return _feeders[name]


from __future__ import absolute_import
from typing import Any, List, Dict, Optional, Text

from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse, HttpRequest
from django.shortcuts import redirect
from django.utils import translation
from django.utils.cache import patch_cache_control
from six.moves import zip_longest, zip, range

from zerver.decorator import zulip_login_required, process_client
from zerver.forms import ToSForm
from zerver.lib.realm_icon import realm_icon_url
from zerver.models import Message, UserProfile, Stream, Subscription, Huddle, \
    Recipient, Realm, UserMessage, DefaultStream, RealmEmoji, RealmAlias, \
    RealmFilter, PreregistrationUser, UserActivity, \
    UserPresence, get_recipient, name_changes_disabled, email_to_username, \
    list_of_domains_for_realm
from zerver.lib.events import do_events_register
from zerver.lib.actions import update_user_presence, do_change_tos_version, \
    do_update_pointer, get_cross_realm_dicts, realm_user_count
from zerver.lib.avatar import avatar_url
from zerver.lib.i18n import get_language_list, get_language_name, \
    get_language_list_for_templates
from zerver.lib.push_notifications import num_push_devices_for_user
from zerver.lib.streams import access_stream_by_name
from zerver.lib.utils import statsd, get_subdomain
from zproject.backends import password_auth_enabled
from zproject.jinja2 import render_to_response

import calendar
import datetime
import logging
import os
import re
import simplejson
import time

@zulip_login_required
def accounts_accept_terms(request):
    # type: (HttpRequest) -> HttpResponse
    if request.method == "POST":
        form = ToSForm(request.POST)
        if form.is_valid():
            do_change_tos_version(request.user, settings.TOS_VERSION)
            return redirect(home)
    else:
        form = ToSForm()

    email = request.user.email
    special_message_template = None
    if request.user.tos_version is None and settings.FIRST_TIME_TOS_TEMPLATE is not None:
        special_message_template = 'zerver/' + settings.FIRST_TIME_TOS_TEMPLATE
    return render_to_response(
        'zerver/accounts_accept_terms.html',
        {'form': form,
         'email': email,
         'special_message_template': special_message_template},
        request=request)

def approximate_unread_count(user_profile):
    # type: (UserProfile) -> int
    not_in_home_view_recipients = [sub.recipient.id for sub in
                                   Subscription.objects.filter(
                                       user_profile=user_profile, in_home_view=False)]

    # TODO: We may want to exclude muted messages from this count.
    #       It was attempted in the past, but the original attempt
    #       was broken.  When we re-architect muting, we may
    #       want to to revisit this (see git issue #1019).
    return UserMessage.objects.filter(
        user_profile=user_profile, message_id__gt=user_profile.pointer).exclude(
        message__recipient__type=Recipient.STREAM,
        message__recipient__id__in=not_in_home_view_recipients).exclude(
        flags=UserMessage.flags.read).count()

def sent_time_in_epoch_seconds(user_message):
    # type: (UserMessage) -> Optional[float]
    # user_message is a UserMessage object.
    if not user_message:
        return None
    # We have USE_TZ = True, so our datetime objects are timezone-aware.
    # Return the epoch seconds in UTC.
    return calendar.timegm(user_message.message.pub_date.utctimetuple())

def home(request):
    # type: (HttpRequest) -> HttpResponse
    if settings.DEVELOPMENT and os.path.exists('var/handlebars-templates/compile.error'):
        response = render_to_response('zerver/handlebars_compilation_failed.html',
                                      request=request)
        response.status_code = 500
        return response
    if not settings.SUBDOMAINS_HOMEPAGE:
        return home_real(request)

    # If settings.SUBDOMAINS_HOMEPAGE, sends the user the landing
    # page, not the login form, on the root domain

    subdomain = get_subdomain(request)
    if subdomain != "":
        return home_real(request)

    return render_to_response('zerver/hello.html',
                              request=request)

@zulip_login_required
def home_real(request):
    # type: (HttpRequest) -> HttpResponse
    # We need to modify the session object every two weeks or it will expire.
    # This line makes reloading the page a sufficient action to keep the
    # session alive.
    request.session.modified = True

    user_profile = request.user

    # If a user hasn't signed the current Terms of Service, send them there
    if settings.TERMS_OF_SERVICE is not None and settings.TOS_VERSION is not None and \
       int(settings.TOS_VERSION.split('.')[0]) > user_profile.major_tos_version():
        return accounts_accept_terms(request)

    narrow = [] # type: List[List[Text]]
    narrow_stream = None
    narrow_topic = request.GET.get("topic")
    if request.GET.get("stream"):
        try:
            narrow_stream_name = request.GET.get("stream")
            (narrow_stream, ignored_rec, ignored_sub) = access_stream_by_name(
                user_profile, narrow_stream_name)
            narrow = [["stream", narrow_stream.name]]
        except Exception:
            logging.exception("Narrow parsing")
        if narrow_stream is not None and narrow_topic is not None:
            narrow.append(["topic", narrow_topic])

    register_ret = do_events_register(user_profile, request.client,
                                      apply_markdown=True, narrow=narrow)
    user_has_messages = (register_ret['max_message_id'] != -1)

    # Reset our don't-spam-users-with-email counter since the
    # user has since logged in
    if user_profile.last_reminder is not None:
        user_profile.last_reminder = None
        user_profile.save(update_fields=["last_reminder"])

    # Brand new users get the tutorial
    needs_tutorial = settings.TUTORIAL_ENABLED and \
        user_profile.tutorial_status != UserProfile.TUTORIAL_FINISHED

    first_in_realm = realm_user_count(user_profile.realm) == 1
    # If you are the only person in the realm and you didn't invite
    # anyone, we'll continue to encourage you to do so on the frontend.
    prompt_for_invites = first_in_realm and \
        not PreregistrationUser.objects.filter(referred_by=user_profile).count()

    if user_profile.pointer == -1 and user_has_messages:
        # Put the new user's pointer at the bottom
        #
        # This improves performance, because we limit backfilling of messages
        # before the pointer.  It's also likely that someone joining an
        # organization is interested in recent messages more than the very
        # first messages on the system.

        register_ret['pointer'] = register_ret['max_message_id']
        user_profile.last_pointer_updater = request.session.session_key

    if user_profile.pointer == -1:
        latest_read = None
    else:
        try:
            latest_read = UserMessage.objects.get(user_profile=user_profile,
                                                  message__id=user_profile.pointer)
        except UserMessage.DoesNotExist:
            # Don't completely fail if your saved pointer ID is invalid
            logging.warning("%s has invalid pointer %s" % (user_profile.email, user_profile.pointer))
            latest_read = None

    desktop_notifications_enabled = user_profile.enable_desktop_notifications
    if narrow_stream is not None:
        desktop_notifications_enabled = False

    if user_profile.realm.notifications_stream:
        notifications_stream = user_profile.realm.notifications_stream.name
    else:
        notifications_stream = ""

    # Set default language and make it persist
    default_language = register_ret['default_language']
    url_lang = '/{}'.format(request.LANGUAGE_CODE)
    if not request.path.startswith(url_lang):
        translation.activate(default_language)

    request.session[translation.LANGUAGE_SESSION_KEY] = default_language

    # Pass parameters to the client-side JavaScript code.
    # These end up in a global JavaScript Object named 'page_params'.
    page_params = dict(
        # Server settings.
        share_the_love        = settings.SHARE_THE_LOVE,
        development_environment = settings.DEVELOPMENT,
        debug_mode            = settings.DEBUG,
        test_suite            = settings.TEST_SUITE,
        poll_timeout          = settings.POLL_TIMEOUT,
        login_page            = settings.HOME_NOT_LOGGED_IN,
        server_uri            = settings.SERVER_URI,
        maxfilesize           = settings.MAX_FILE_UPLOAD_SIZE,
        max_avatar_file_size  = settings.MAX_AVATAR_FILE_SIZE,
        server_generation     = settings.SERVER_GENERATION,
        use_websockets        = settings.USE_WEBSOCKETS,
        save_stacktraces      = settings.SAVE_FRONTEND_STACKTRACES,

        # realm data.
        # TODO: Move all of these data to register_ret and pull from there
        realm_uri             = user_profile.realm.uri,
        password_auth_enabled = password_auth_enabled(user_profile.realm),
        domains               = list_of_domains_for_realm(user_profile.realm),
        name_changes_disabled = name_changes_disabled(user_profile.realm),
        mandatory_topics      = user_profile.realm.mandatory_topics,
        show_digest_email     = user_profile.realm.show_digest_email,
        realm_presence_disabled = user_profile.realm.presence_disabled,
        is_zephyr_mirror_realm = user_profile.realm.is_zephyr_mirror_realm,

        # user_profile data.
        # TODO: Move all of these data to register_ret and pull from there
        fullname              = user_profile.full_name,
        email                 = user_profile.email,
        enter_sends           = user_profile.enter_sends,
        user_id               = user_profile.id,
        is_admin              = user_profile.is_realm_admin,
        can_create_streams    = user_profile.can_create_streams(),
        autoscroll_forever = user_profile.autoscroll_forever,
        default_desktop_notifications = user_profile.default_desktop_notifications,
        avatar_url            = avatar_url(user_profile),
        avatar_url_medium     = avatar_url(user_profile, medium=True),
        avatar_source         = user_profile.avatar_source,
        timezone              = user_profile.timezone,

        # Stream message notification settings:
        stream_desktop_notifications_enabled = user_profile.enable_stream_desktop_notifications,
        stream_sounds_enabled = user_profile.enable_stream_sounds,

        # Private message and @-mention notification settings:
        desktop_notifications_enabled = desktop_notifications_enabled,
        sounds_enabled = user_profile.enable_sounds,
        enable_offline_email_notifications = user_profile.enable_offline_email_notifications,
        pm_content_in_desktop_notifications = user_profile.pm_content_in_desktop_notifications,
        enable_offline_push_notifications = user_profile.enable_offline_push_notifications,
        enable_online_push_notifications = user_profile.enable_online_push_notifications,
        enable_digest_emails  = user_profile.enable_digest_emails,

        # Realm foreign key data from register_ret.
        # TODO: Rename these to match register_ret values.
        subbed_info           = register_ret['subscriptions'],
        unsubbed_info         = register_ret['unsubscribed'],
        neversubbed_info      = register_ret['never_subscribed'],
        people_list           = register_ret['realm_users'],
        bot_list              = register_ret['realm_bots'],
        initial_pointer       = register_ret['pointer'],
        initial_presences     = register_ret['presences'],
        event_queue_id        = register_ret['queue_id'],

        # Misc. extra data.
        have_initial_messages = user_has_messages,
        initial_servertime    = time.time(), # Used for calculating relative presence age
        default_language_name = get_language_name(register_ret['default_language']),
        language_list_dbl_col = get_language_list_for_templates(register_ret['default_language']),
        language_list         = get_language_list(),
        needs_tutorial        = needs_tutorial,
        first_in_realm        = first_in_realm,
        prompt_for_invites    = prompt_for_invites,
        notifications_stream  = notifications_stream,
        cross_realm_bots      = list(get_cross_realm_dicts()),
        unread_count          = approximate_unread_count(user_profile),
        furthest_read_time    = sent_time_in_epoch_seconds(latest_read),
        has_mobile_devices    = num_push_devices_for_user(user_profile) > 0,
    )

    # These fields will be automatically copied from register_ret into
    # page_params.  It is a goal to move more of the page_params list
    # into this sort of cleaner structure.
    page_params_core_fields = [
        'alert_words',
        'attachments',
        'default_language',
        'emoji_alt_code',
        'last_event_id',
        'left_side_userlist',
        'max_icon_file_size',
        'max_message_id',
        'muted_topics',
        'realm_add_emoji_by_admins_only',
        'realm_allow_message_editing',
        'realm_authentication_methods',
        'realm_bot_domain',
        'realm_create_stream_by_admins_only',
        'realm_default_language',
        'realm_default_streams',
        'realm_email_changes_disabled',
        'realm_emoji',
        'realm_filters',
        'realm_icon_source',
        'realm_icon_url',
        'realm_invite_by_admins_only',
        'realm_invite_required',
        'realm_message_content_edit_limit_seconds',
        'realm_name',
        'realm_name_changes_disabled',
        'realm_restricted_to_domain',
        'realm_waiting_period_threshold',
        'referrals',
        'twenty_four_hour_time',
        'zulip_version',
    ]

    for field_name in page_params_core_fields:
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = get_recipient(Recipient.STREAM, narrow_stream.id)
        try:
            initial_pointer = Message.objects.filter(recipient=recipient).order_by('id').reverse()[0].id
        except IndexError:
            initial_pointer = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [dict(operator=term[0], operand=term[1]) for term in narrow]
        page_params["max_message_id"] = initial_pointer
        page_params["initial_pointer"] = initial_pointer
        page_params["have_initial_messages"] = (initial_pointer != -1)

    statsd.incr('views.home')
    show_invites = True

    # Some realms only allow admins to invite users
    if user_profile.realm.invite_by_admins_only and not user_profile.is_realm_admin:
        show_invites = False

    request._log_data['extra'] = "[%s]" % (register_ret["queue_id"],)
    response = render_to_response('zerver/index.html',
                                  {'user_profile': user_profile,
                                   'page_params': simplejson.encoder.JSONEncoderForHTML().encode(page_params),
                                   'nofontface': is_buggy_ua(request.META.get("HTTP_USER_AGENT", "Unspecified")),
                                   'avatar_url': avatar_url(user_profile),
                                   'show_debug':
                                       settings.DEBUG and ('show_debug' in request.GET),
                                   'pipeline': settings.PIPELINE_ENABLED,
                                   'show_invites': show_invites,
                                   'is_admin': user_profile.is_realm_admin,
                                   'show_webathena': user_profile.realm.webathena_enabled,
                                   'enable_feedback': settings.ENABLE_FEEDBACK,
                                   'embedded': narrow_stream is not None,
                                   },
                                  request=request)
    patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
    return response

@zulip_login_required
def desktop_home(request):
    # type: (HttpRequest) -> HttpResponse
    return HttpResponseRedirect(reverse('zerver.views.home.home'))

def is_buggy_ua(agent):
    # type: (str) -> bool
    """Discrimiate CSS served to clients based on User Agent

    Due to QTBUG-3467, @font-face is not supported in QtWebKit.
    This may get fixed in the future, but for right now we can
    just serve the more conservative CSS to all our desktop apps.
    """
    return ("Humbug Desktop/" in agent or "Zulip Desktop/" in agent or "ZulipDesktop/" in agent) and \
        "Mac" not in agent


i start to feel emotional


i believe feeling duality suffering soul growth tells of an ending or a decline or a change of direction often one associated with emotions and it offers one possible response to that decline or change moving on


i hostage negotiator on her case has her feeling hopeful about her future


im feeling a little dirty


i can cope with his presence without feeling distressed if i can force myself into a quiet and resigned friendship


i had the feeling that it might not have been taken as the truthful and sincere compliment it would have been


i asked some girls what it meant to them to be valued and for the most part the response was that they felt valued when the people around them made them feel valued and treated them in a loving and caring manner


i feel if i completely hated things i d exercise my democratic right speak my mind in what ever ways possible and try to enact a change


i could almost feel her gentle touch in the moonbeam she sent to shine over me he added touching his face dreamily


i woke up very early this morning feeling joyful


Wow ... u sent me a confirmation this AM . but u could n't send me that u had a family emergency ??? Lisa Demelfi


This was canceled . Thank you !


150.00 is that the amount


I will be there at {time} with Nichol . Thanks !


Ok see you 11


Hi . I 'm so sorry . I have to cancel . I have work calls today ( on a Saturday ) no less !! I 'm so disappointed to not be to come today !! Can we postpone ?


Yes


The number you are sending an SMS to , currently has no SMS capabilities .


I 'm going to be ten min late


Hello ! I am so sorry - I need to cancel my appointment tomorrow . I 've been sick all weekend and am still feeling pretty terrible ! Please cancel my appointment .


!!! RT @mayasolovely: As a woman you shouldn't complain about cleaning up your house. & as a man you should always take the trash out...


!!!!! RT @mleew17: boy dats cold...tyga dwn bad for cuffin dat hoe in the 1st place!!


!!!!!!! RT @UrKindOfBrand Dawg!!!! RT @80sbaby4life: You ever fuck a bitch and she start to cry? You be confused as shit


!!!!!!!!! RT @C_G_Anderson: @viva_based she look like a tranny


!!!!!!!!!!!!! RT @ShenikaRoberts: The shit you hear about me might be true or it might be faker than the bitch who told it to ya 


!!!!!!!!!!!!!!!!!!"@T_Madison_x: The shit just blows me..claim you so faithful and down for somebody but still fucking with hoes! 😂😂😂"


!!!!!!"@__BrighterDays: I can not just sit up and HATE on another bitch .. I got too much shit going on!"


!!!!“@selfiequeenbri: cause I'm tired of you big bitches coming for us skinny girls!!”


" & you might not get ya bitch back & thats that "


" @rhythmixx_ :hobbies include: fighting Mariam"

bitch


Premise: yeah but well they vary from from place to place it's hard to tell you know how well they've been kept up how old they are and these are probably oh one of the nicest that i found and uh

Hypothesis: It's hard to tell how things have been kept up and their age because they vary so much from place to place.


Premise: If food and medical care tripled in cost, people would of necessity spend less on other things to pay for the increase or cut down on the food and medical care they purchased.

Hypothesis: People would have to cut spending in other areas if food and medical care increased.


Premise: I think you should have talked to the hostel management to help you out on this as well

Hypothesis: You should forget about it and not tell any one about this incident.


Premise: That's neat. What else do you do for fun?

Hypothesis: Thats a boring book. Its boring and not fun


Premise: Guess whoever did it thought Johnny was wolf meat, jus' took his hoss an' left him there.

Hypothesis: Suppose whoever did it thought Johnny was dead, took his horse, and left him.


Premise: Johnny was throwing his weight around again last night.

Hypothesis: Johnny was expressing his authority last night.


Premise: You think it will be a big success?

Hypothesis: You think it will be a failure?


Premise: Prudie would suggest, however, since you are on your way up the corporate ladder in a buttoned-up industry that your ladyfriend not dress them up so that undue attention is directed their way.

Hypothesis: Don't dress oddly in a corporate setting.


Premise: I've never sailed on the ocean because i have an irrational fear that ill be eaten by a squid.

Hypothesis: Yeah, isn't it fun, though, I loved it.


Premise: stick on the subject well interesting thing that i do is with gardening uh my sister grows flowers that you can dry

Hypothesis: My sister grows flowers you can dry.


Best Performance by a Leading Actor in a Musical

Best Performance by a Leading Actress in a Musical

The show received six Tony Award nominations, but won only one Tony (Best Conductor and Musical Director, for Salvatore Dell'Isola).

The show received six Tony Award nominations, but won only one (Best Conductor and Musical Director, for Salvatore Dell'Isola).

The Flower Drum Song received six Tony Award nominations, but won only one for the Best Conductor and Musical Director, for Salvatore Dell'Isola.


Chapter  12

Summary: Mrs. Dashwood and her daughters are busy attending parties and balls. Marianne is in her element. She is overjoyed in the company of Willoughby, who showers much affection and attention on her. Elinor even feels left out at times. Deprived of friends of her own age, she is often thrown in the company of Mrs. Jennings and Lady Middleton. At such times she welcomes the presence of Colonel Brandon. Brandon often talks of Marianne and asks Elinor about her sister's preferences.

Notes Jane Austen paints the picture of an eighteenth-century upper middle-class society. The Dashwoods and Middletons are shown to be busy attending parties and balls. Their main occupation is socializing, and they take pleasure in entertaining people. Every young girl waits for a respectable young man to woo her, and her parents hope for a match between them. They lead a leisurely life, perhaps unusual to the modern reader. Marianne is exhilarated by the looks and manners of her lover. She does not care to understand his essential nature. Obsessed with Willoughby, she ignores Colonel Brandon and unconsciously hurts him. Blinded by her infatuation for Willoughby, she is not able to realize the worth of the Colonel or detect the intensity of his feelings. This chapter again emphasizes the difference in attitudes between Willoughby and Colonel Brandon. Both men are attracted to Marianne. Willoughby displays his affection by wooing Marianne, like a dashing hero would, while Colonel Brandon admires his lady love from a distance and silently hopes to win her favor. Willoughby is interested only in flirting with Marianne, but the Colonel, like a sincere person, looks forward to a lasting relationship. CHAPTER 12 Summary Marianne gets carried away by Willoughby's showy gestures. When he offers her a horse, she accepts it readily and talks about it to her sister. Elinor is shocked to learn this and asks Marianne to decline the offer, as it would prove too costly for them. Elinor observes Willoughby's behavior towards her sister and detects a note of intimacy in it. Margaret tells Elinor about her suspicion of an engagement between Marianne and Willoughby. Later, at Mrs. Jennings' insistence, Margaret gives a hint about Elinor's attachment to Edward, much to Elinor's embarrassment. Notes The chapter hints at the extent of the involvement of Marianne with Willoughby. Willoughby tries to impress Marianne by offering her a horse as a gift, and Marianne foolishly accepts the offer without giving a thought to the expenditure involved. Willoughby's superficiality and Marianne's gullibility are exposed in this episode. Chapter 12 also reveals the character of the youngest of the Dashwood girls. Margaret, one of the minor characters in the novel, is otherwise ignored by Austen. Only a few chapters give a glimpse into her personality. Margaret, like a typical teenager, gets excited over little things and jumps to conclusions easily. She derives pleasure from revealing secrets. She informs Elinor about the impending marriage between Marianne and Willoughby because she saw the young man taking a lock of hair from her sister . At the Park, she gives hints about the relationship between Elinor and Edward to Mrs. Jennings, much to the embarrassment of her sister. Like a reckless teenager, she is always in a hurry to impart information not meant to be disclosed publicly. CHAPTER 13 Summary Everyone is eagerly looking forward to their picnic at Whitewell. However, on the morning of the outing, a letter arrives for Colonel Brandon and alters the situation. The letter disturbs Brandon, and he informs the others about his decision to leave immediately for the town. The picnic is canceled, much to the disappointment of all, since it is not possible to proceed to Whitewell without the assistance of the Colonel. Sir John Middleton suggests that they should go for a ride in the carriage around the countryside. Marianne and Willoughby take a separate carriage. They visit Allenham on the sly. When Elinor learns about their visit, she is angry with Marianne for not observing the rules of propriety. Marianne justifies her action. Notes An element of suspense is introduced in this chapter. After the Colonel reads the letter, he turns grave and decides to leave for the town immediately. He evades the questions of Mrs. Jennings and declines to postpone his visit. After he leaves, Mrs. Jennings hints at the possibility of his visiting his illegitimate daughter, Miss Williams. Through this bit of information, Austen arouses the curiosity of the reader regarding the mysterious past of Colonel Brandon. Marianne and Willoughby are insensitive to the feelings of the Colonel and fail to sympathize with his plight. They criticize Brandon for spoiling the afternoon. Colonel Brandon comes across as a man in control of his emotions. Even though he is disturbed by the contents of the letter, he does not reveal his misery to others. Like a gentleman, he excuses himself from the party and bows to Marianne before taking his leave. His silence speaks volumes. The chapter relates one more incident which creates a clash between the good sense of Elinor and the sensibility of Marianne. Marianne makes a secret visit to Allenham with Willoughby but does not feel guilty about what she has done. Elinor's sense of decorum causes her to condemn her sister's actions, as she does not approve of Marianne's visiting a stranger's house with a man to whom she is not even engaged, at least not openly.

As Elinor and Marianne were walking together the next morning the
latter communicated a piece of news to her sister, which in spite of
all that she knew before of Marianne's imprudence and want of thought,
surprised her by its extravagant testimony of both.  Marianne told her,
with the greatest delight, that Willoughby had given her a horse, one
that he had bred himself on his estate in Somersetshire, and which was
exactly calculated to carry a woman.  Without considering that it was
not in her mother's plan to keep any horse, that if she were to alter
her resolution in favour of this gift, she must buy another for the
servant, and keep a servant to ride it, and after all, build a stable
to receive them, she had accepted the present without hesitation, and
told her sister of it in raptures.

"He intends to send his groom into Somersetshire immediately for it,"
she added, "and when it arrives we will ride every day.  You shall
share its use with me.  Imagine to yourself, my dear Elinor, the
delight of a gallop on some of these downs."

Most unwilling was she to awaken from such a dream of felicity to
comprehend all the unhappy truths which attended the affair; and for
some time she refused to submit to them.  As to an additional servant,
the expense would be a trifle; Mama she was sure would never object to
it; and any horse would do for HIM; he might always get one at the
park; as to a stable, the merest shed would be sufficient.  Elinor then
ventured to doubt the propriety of her receiving such a present from a
man so little, or at least so lately known to her.  This was too much.

"You are mistaken, Elinor," said she warmly, "in supposing I know very
little of Willoughby.  I have not known him long indeed, but I am much
better acquainted with him, than I am with any other creature in the
world, except yourself and mama.  It is not time or opportunity that is
to determine intimacy;--it is disposition alone.  Seven years would be
insufficient to make some people acquainted with each other, and seven
days are more than enough for others.  I should hold myself guilty of
greater impropriety in accepting a horse from my brother, than from
Willoughby.  Of John I know very little, though we have lived together
for years; but of Willoughby my judgment has long been formed."

Elinor thought it wisest to touch that point no more.  She knew her
sister's temper.  Opposition on so tender a subject would only attach
her the more to her own opinion.  But by an appeal to her affection for
her mother, by representing the inconveniences which that indulgent
mother must draw on herself, if (as would probably be the case) she
consented to this increase of establishment, Marianne was shortly
subdued; and she promised not to tempt her mother to such imprudent
kindness by mentioning the offer, and to tell Willoughby when she saw
him next, that it must be declined.

She was faithful to her word; and when Willoughby called at the
cottage, the same day, Elinor heard her express her disappointment to
him in a low voice, on being obliged to forego the acceptance of his
present.  The reasons for this alteration were at the same time
related, and they were such as to make further entreaty on his side
impossible.  His concern however was very apparent; and after
expressing it with earnestness, he added, in the same low voice,--"But,
Marianne, the horse is still yours, though you cannot use it now.  I
shall keep it only till you can claim it.  When you leave Barton to
form your own establishment in a more lasting home, Queen Mab shall
receive you."

This was all overheard by Miss Dashwood; and in the whole of the
sentence, in his manner of pronouncing it, and in his addressing her
sister by her Christian name alone, she instantly saw an intimacy so
decided, a meaning so direct, as marked a perfect agreement between
them.  From that moment she doubted not of their being engaged to each
other; and the belief of it created no other surprise than that she, or
any of their friends, should be left by tempers so frank, to discover
it by accident.

Margaret related something to her the next day, which placed this
matter in a still clearer light.  Willoughby had spent the preceding
evening with them, and Margaret, by being left some time in the parlour
with only him and Marianne, had had opportunity for observations,
which, with a most important face, she communicated to her eldest
sister, when they were next by themselves.

"Oh, Elinor!" she cried, "I have such a secret to tell you about
Marianne.  I am sure she will be married to Mr. Willoughby very soon."

"You have said so," replied Elinor, "almost every day since they first
met on High-church Down; and they had not known each other a week, I
believe, before you were certain that Marianne wore his picture round
her neck; but it turned out to be only the miniature of our great
uncle."

"But indeed this is quite another thing.  I am sure they will be
married very soon, for he has got a lock of her hair."

"Take care, Margaret.  It may be only the hair of some great uncle of
HIS."

"But, indeed, Elinor, it is Marianne's. I am almost sure it is, for I
saw him cut it off.  Last night after tea, when you and mama went out
of the room, they were whispering and talking together as fast as could
be, and he seemed to be begging something of her, and presently he took
up her scissors and cut off a long lock of her hair, for it was all
tumbled down her back; and he kissed it, and folded it up in a piece of
white paper; and put it into his pocket-book."

For such particulars, stated on such authority, Elinor could not
withhold her credit; nor was she disposed to it, for the circumstance
was in perfect unison with what she had heard and seen herself.

Margaret's sagacity was not always displayed in a way so satisfactory
to her sister.  When Mrs. Jennings attacked her one evening at the
park, to give the name of the young man who was Elinor's particular
favourite, which had been long a matter of great curiosity to her,
Margaret answered by looking at her sister, and saying, "I must not
tell, may I, Elinor?"

This of course made every body laugh; and Elinor tried to laugh too.
But the effort was painful.  She was convinced that Margaret had fixed
on a person whose name she could not bear with composure to become a
standing joke with Mrs. Jennings.

Marianne felt for her most sincerely; but she did more harm than good
to the cause, by turning very red and saying in an angry manner to
Margaret,

"Remember that whatever your conjectures may be, you have no right to
repeat them."

"I never had any conjectures about it," replied Margaret; "it was you
who told me of it yourself."

This increased the mirth of the company, and Margaret was eagerly
pressed to say something more.

"Oh! pray, Miss Margaret, let us know all about it," said Mrs.
Jennings.  "What is the gentleman's name?"

"I must not tell, ma'am. But I know very well what it is; and I know
where he is too."

"Yes, yes, we can guess where he is; at his own house at Norland to be
sure.  He is the curate of the parish I dare say."

"No, THAT he is not.  He is of no profession at all."

"Margaret," said Marianne with great warmth, "you know that all this is
an invention of your own, and that there is no such person in
existence."

"Well, then, he is lately dead, Marianne, for I am sure there was such
a man once, and his name begins with an F."

Most grateful did Elinor feel to Lady Middleton for observing, at this
moment, "that it rained very hard," though she believed the
interruption to proceed less from any attention to her, than from her
ladyship's great dislike of all such inelegant subjects of raillery as
delighted her husband and mother.  The idea however started by her, was
immediately pursued by Colonel Brandon, who was on every occasion
mindful of the feelings of others; and much was said on the subject of
rain by both of them.  Willoughby opened the piano-forte, and asked
Marianne to sit down to it; and thus amidst the various endeavours of
different people to quit the topic, it fell to the ground.  But not so
easily did Elinor recover from the alarm into which it had thrown her.

A party was formed this evening for going on the following day to see a
very fine place about twelve miles from Barton, belonging to a
brother-in-law of Colonel Brandon, without whose interest it could not
be seen, as the proprietor, who was then abroad, had left strict orders
on that head.  The grounds were declared to be highly beautiful, and
Sir John, who was particularly warm in their praise, might be allowed
to be a tolerable judge, for he had formed parties to visit them, at
least, twice every summer for the last ten years.  They contained a
noble piece of water; a sail on which was to a form a great part of the
morning's amusement; cold provisions were to be taken, open carriages
only to be employed, and every thing conducted in the usual style of a
complete party of pleasure.

To some few of the company it appeared rather a bold undertaking,
considering the time of year, and that it had rained every day for the
last fortnight;--and Mrs. Dashwood, who had already a cold, was
persuaded by Elinor to stay at home.


finished_summaries/gradesaver/Tess of the D'Urbervilles/section_2_part_5.txt

Chapter 20

Summary: Tess had never in her recent life been so happy and would possibly never be so happy again. She and Tess stand between predilection and love. For Angel, Tess represents a visionary essence of woman, and calls her Artemis, Demeter, and other fanciful names, but she insists that he call her simply Tess. Tess seems to exhibit a dignified largeness of disposition and physique. The two are always the first to awake at the dairy house, where they feel an impressive isolation, as if they are Adam and Eve.

Hardy makes explicit that Tess's time at Talbothays dairy is an idyllic respite from her normal toil and hardship, yet states that this happiness will be short-lived, foreshadowing greater adversity for Tess Durbeyfield. Hardy compares Angel and Tess to Adam and Eve in the mornings, thus foreshadowing a later fall from perfection. It is the idealism and perfection that Tess finds at Talbothays that leads to this shaky foundation for her happiness; Angel Clare adores Tess as a representation of perfection. To Angel, Tess is a goddess such as Artemis or Demeter, a symbol of perfection rather than a person with obvious faults and foibles. There is a great irony in Angel's adoration for Tess; Angel exalts Tess as a goddess for her strength and disposition, yet this perfection comes from the adversity stemming from her greatest weakness

The season developed and matured.  Another year's instalment of
flowers, leaves, nightingales, thrushes, finches, and such ephemeral
creatures, took up their positions where only a year ago others had
stood in their place when these were nothing more than germs and
inorganic particles.  Rays from the sunrise drew forth the buds and
stretched them into long stalks, lifted up sap in noiseless streams,
opened petals, and sucked out scents in invisible jets and
breathings.

Dairyman Crick's household of maids and men lived on comfortably,
placidly, even merrily.  Their position was perhaps the happiest of
all positions in the social scale, being above the line at which
neediness ends, and below the line at which the _convenances_ begin
to cramp natural feelings, and the stress of threadbare modishness
makes too little of enough.

Thus passed the leafy time when arborescence seems to be the one
thing aimed at out of doors.  Tess and Clare unconsciously studied
each other, ever balanced on the edge of a passion, yet apparently
keeping out of it.  All the while they were converging, under an
irresistible law, as surely as two streams in one vale.

Tess had never in her recent life been so happy as she was now,
possibly never would be so happy again.  She was, for one thing,
physically and mentally suited among these new surroundings.  The
sapling which had rooted down to a poisonous stratum on the spot of
its sowing had been transplanted to a deeper soil.  Moreover she, and
Clare also, stood as yet on the debatable land between predilection
and love; where no profundities have been reached; no reflections
have set in, awkwardly inquiring, "Whither does this new current tend
to carry me?  What does it mean to my future?  How does it stand
towards my past?"

Tess was the merest stray phenomenon to Angel Clare as yet--a rosy,
warming apparition which had only just acquired the attribute of
persistence in his consciousness.  So he allowed his mind to be
occupied with her, deeming his preoccupation to be no more than a
philosopher's regard of an exceedingly novel, fresh, and interesting
specimen of womankind.

They met continually; they could not help it.  They met daily in that
strange and solemn interval, the twilight of the morning, in the
violet or pink dawn; for it was necessary to rise early, so very
early, here.  Milking was done betimes; and before the milking came
the skimming, which began at a little past three.  It usually fell
to the lot of some one or other of them to wake the rest, the first
being aroused by an alarm-clock; and, as Tess was the latest arrival,
and they soon discovered that she could be depended upon not to sleep
though the alarm as others did, this task was thrust most frequently
upon her.  No sooner had the hour of three struck and whizzed,
than she left her room and ran to the dairyman's door; then up the
ladder to Angel's, calling him in a loud whisper; then woke her
fellow-milkmaids.  By the time that Tess was dressed Clare was
downstairs and out in the humid air.  The remaining maids and the
dairyman usually gave themselves another turn on the pillow, and did
not appear till a quarter of an hour later.

The gray half-tones of daybreak are not the gray half-tones of the
day's close, though the degree of their shade may be the same.  In
the twilight of the morning, light seems active, darkness passive;
in the twilight of evening it is the darkness which is active and
crescent, and the light which is the drowsy reverse.

Being so often--possibly not always by chance--the first two persons
to get up at the dairy-house, they seemed to themselves the first
persons up of all the world.  In these early days of her residence
here Tess did not skim, but went out of doors at once after rising,
where he was generally awaiting her.  The spectral, half-compounded,
aqueous light which pervaded the open mead impressed them with
a feeling of isolation, as if they were Adam and Eve.  At this
dim inceptive stage of the day Tess seemed to Clare to exhibit a
dignified largeness both of disposition and physique, an almost
regnant power, possibly because he knew that at that preternatural
time hardly any woman so well endowed in person as she was likely to
be walking in the open air within the boundaries of his horizon; very
few in all England.  Fair women are usually asleep at mid-summer
dawns.  She was close at hand, and the rest were nowhere.

The mixed, singular, luminous gloom in which they walked along
together to the spot where the cows lay often made him think of the
Resurrection hour.  He little thought that the Magdalen might be
at his side.  Whilst all the landscape was in neutral shade his
companion's face, which was the focus of his eyes, rising above the
mist stratum, seemed to have a sort of phosphorescence upon it.  She
looked ghostly, as if she were merely a soul at large.  In reality
her face, without appearing to do so, had caught the cold gleam of
day from the north-east; his own face, though he did not think of
it, wore the same aspect to her.

It was then, as has been said, that she impressed him most deeply.
She was no longer the milkmaid, but a visionary essence of woman--a
whole sex condensed into one typical form.  He called her Artemis,
Demeter, and other fanciful names half teasingly, which she did not
like because she did not understand them.

"Call me Tess," she would say askance; and he did.

Then it would grow lighter, and her features would become simply
feminine; they had changed from those of a divinity who could confer
bliss to those of a being who craved it.

At these non-human hours they could get quite close to the waterfowl.
Herons came, with a great bold noise as of opening doors and
shutters, out of the boughs of a plantation which they frequented at
the side of the mead; or, if already on the spot, hardily maintained
their standing in the water as the pair walked by, watching them by
moving their heads round in a slow, horizontal, passionless wheel,
like the turn of puppets by clockwork.

They could then see the faint summer fogs in layers, woolly, level,
and apparently no thicker than counterpanes, spread about the meadows
in detached remnants of small extent.  On the gray moisture of the
grass were marks where the cows had lain through the night--dark-green
islands of dry herbage the size of their carcasses, in the general
sea of dew. From each island proceeded a serpentine trail, by which
the cow had rambled away to feed after getting up, at the end of
which trail they found her; the snoring puff from her nostrils, when
she recognized them, making an intenser little fog of her own amid
the prevailing one.  Then they drove the animals back to the barton,
or sat down to milk them on the spot, as the case might require.

Or perhaps the summer fog was more general, and the meadows lay like
a white sea, out of which the scattered trees rose like dangerous
rocks.  Birds would soar through it into the upper radiance, and
hang on the wing sunning themselves, or alight on the wet rails
subdividing the mead, which now shone like glass rods.  Minute
diamonds of moisture from the mist hung, too, upon Tess's eyelashes,
and drops upon her hair, like seed pearls.  When the day grew quite
strong and commonplace these dried off her; moreover, Tess then
lost her strange and ethereal beauty; her teeth, lips, and eyes
scintillated in the sunbeams and she was again the dazzlingly fair
dairymaid only, who had to hold her own against the other women of
the world.

About this time they would hear Dairyman Crick's voice, lecturing the
non-resident milkers for arriving late, and speaking sharply to old
Deborah Fyander for not washing her hands.

"For Heaven's sake, pop thy hands under the pump, Deb!  Upon my soul,
if the London folk only knowed of thee and thy slovenly ways, they'd
swaller their milk and butter more mincing than they do a'ready; and
that's saying a good deal."

The milking progressed, till towards the end Tess and Clare, in
common with the rest, could hear the heavy breakfast table dragged
out from the wall in the kitchen by Mrs Crick, this being the
invariable preliminary to each meal; the same horrible scrape
accompanying its return journey when the table had been cleared.


Chapter 9

Summary: Rulers that come to power because of the support of the people are the total opposite of bloody conquers. Everyone loves 'em. They're not too smart, or even extra lucky, but just enough to get by. Our new ruler has three options for his new place: a monarchy where power goes to the nobles, a republic where power goes to the people, and anarchy. In monarchies, either the nobles or the people decide to concentrate all the power in one person, the king. Seems simple enough, but a king who comes to power because of the nobles will have a hard time. After all, the nobles have lots of power to throw around, too. Remember, you don't want anyone who can compete with you around, and these are the people with the weapons. What are the regular people going to do to you? Poke you with their potatoes? Bottom line: be friends with the people, because the nobles have too many tricks up their sleeves. More on nobles. There are two kinds, those who are totally 100% loyally part of your fan club and those who aren't. Out of those who aren't, there are two kinds. Those who are just scaredy-cats , and those who are planning something. The latter are the ones to watch out for because they will turn on you at the drop of a hat. Okay, back to the people. You need to be on their side. It's pretty easy, actually, because they basically just don't want to be oppressed and tortured. Also, if they thought you were going to be super mean, and you turn out to be okay, they will love you even more than if they loved you from the start. They're easy to please. Some people say that it's a bad idea to depend on the support of the people. Machiavelli just doesn't agree--he says that's only the case if you're stupid and think they'll fight for you or rescue you. That's not going to happen. But they can support you and not turn against you. Problems for the ruler supported by the people? When they want to become an absolute ruler, they need either give direct command or rule though other people who they give power to. The problem is, these people aren't always the most trustworthy--before you know it, everything is up in flames. So, make sure your people always need not only your government , but you specifically, and everything will be okay.

But coming to the other point--where a leading citizen becomes the
prince of his country, not by wickedness or any intolerable violence,
but by the favour of his fellow citizens--this may be called a civil
principality: nor is genius or fortune altogether necessary to attain to
it, but rather a happy shrewdness. I say then that such a principality
is obtained either by the favour of the people or by the favour of the
nobles. Because in all cities these two distinct parties are found,
and from this it arises that the people do not wish to be ruled nor
oppressed by the nobles, and the nobles wish to rule and oppress the
people; and from these two opposite desires there arises in cities one
of three results, either a principality, self-government, or anarchy.

A principality is created either by the people or by the nobles,
accordingly as one or other of them has the opportunity; for the nobles,
seeing they cannot withstand the people, begin to cry up the reputation
of one of themselves, and they make him a prince, so that under his
shadow they can give vent to their ambitions. The people, finding
they cannot resist the nobles, also cry up the reputation of one of
themselves, and make him a prince so as to be defended by his authority.
He who obtains sovereignty by the assistance of the nobles maintains
himself with more difficulty than he who comes to it by the aid of
the people, because the former finds himself with many around him who
consider themselves his equals, and because of this he can neither rule
nor manage them to his liking. But he who reaches sovereignty by popular
favour finds himself alone, and has none around him, or few, who are not
prepared to obey him.

Besides this, one cannot by fair dealing, and without injury to others,
satisfy the nobles, but you can satisfy the people, for their object is
more righteous than that of the nobles, the latter wishing to oppress,
while the former only desire not to be oppressed. It is to be added also
that a prince can never secure himself against a hostile people, because
of there being too many, whilst from the nobles he can secure himself,
as they are few in number. The worst that a prince may expect from a
hostile people is to be abandoned by them; but from hostile nobles he
has not only to fear abandonment, but also that they will rise against
him; for they, being in these affairs more far-seeing and astute, always
come forward in time to save themselves, and to obtain favours from him
whom they expect to prevail. Further, the prince is compelled to live
always with the same people, but he can do well without the same nobles,
being able to make and unmake them daily, and to give or take away
authority when it pleases him.

Therefore, to make this point clearer, I say that the nobles ought to
be looked at mainly in two ways: that is to say, they either shape their
course in such a way as binds them entirely to your fortune, or they do
not. Those who so bind themselves, and are not rapacious, ought to be
honoured and loved; those who do not bind themselves may be dealt
with in two ways; they may fail to do this through pusillanimity and a
natural want of courage, in which case you ought to make use of them,
especially of those who are of good counsel; and thus, whilst in
prosperity you honour them, in adversity you do not have to fear them.
But when for their own ambitious ends they shun binding themselves, it
is a token that they are giving more thought to themselves than to you,
and a prince ought to guard against such, and to fear them as if they
were open enemies, because in adversity they always help to ruin him.

Therefore, one who becomes a prince through the favour of the people
ought to keep them friendly, and this he can easily do seeing they
only ask not to be oppressed by him. But one who, in opposition to
the people, becomes a prince by the favour of the nobles, ought, above
everything, to seek to win the people over to himself, and this he may
easily do if he takes them under his protection. Because men, when they
receive good from him of whom they were expecting evil, are bound more
closely to their benefactor; thus the people quickly become more devoted
to him than if he had been raised to the principality by their favours;
and the prince can win their affections in many ways, but as these vary
according to the circumstances one cannot give fixed rules, so I omit
them; but, I repeat, it is necessary for a prince to have the people
friendly, otherwise he has no security in adversity.

Nabis,(*) Prince of the Spartans, sustained the attack of all Greece,
and of a victorious Roman army, and against them he defended his country
and his government; and for the overcoming of this peril it was only
necessary for him to make himself secure against a few, but this would
not have been sufficient had the people been hostile. And do not let any
one impugn this statement with the trite proverb that "He who builds on
the people, builds on the mud," for this is true when a private citizen
makes a foundation there, and persuades himself that the people will
free him when he is oppressed by his enemies or by the magistrates;
wherein he would find himself very often deceived, as happened to the
Gracchi in Rome and to Messer Giorgio Scali(+) in Florence. But granted
a prince who has established himself as above, who can command, and is
a man of courage, undismayed in adversity, who does not fail in other
qualifications, and who, by his resolution and energy, keeps the whole
people encouraged--such a one will never find himself deceived in them,
and it will be shown that he has laid his foundations well.

     (*) Nabis, tyrant of Sparta, conquered by the Romans under
     Flamininus in 195 B.C.; killed 192 B.C.

     (+) Messer Giorgio Scali. This event is to be found in
     Machiavelli's "Florentine History," Book III.

These principalities are liable to danger when they are passing from the
civil to the absolute order of government, for such princes either rule
personally or through magistrates. In the latter case their government
is weaker and more insecure, because it rests entirely on the goodwill
of those citizens who are raised to the magistracy, and who, especially
in troubled times, can destroy the government with great ease, either
by intrigue or open defiance; and the prince has not the chance amid
tumults to exercise absolute authority, because the citizens and
subjects, accustomed to receive orders from magistrates, are not of
a mind to obey him amid these confusions, and there will always be in
doubtful times a scarcity of men whom he can trust. For such a prince
cannot rely upon what he observes in quiet times, when citizens have
need of the state, because then every one agrees with him; they all
promise, and when death is far distant they all wish to die for him;
but in troubled times, when the state has need of its citizens, then
he finds but few. And so much the more is this experiment dangerous,
inasmuch as it can only be tried once. Therefore a wise prince ought to
adopt such a course that his citizens will always in every sort and
kind of circumstance have need of the state and of him, and then he will
always find them faithful.