# Path: opentaxforms/ut.py
# NL = '\n'
# TAB = '\t'
# def merge(bb1, bb2):
# def numerify(s):
# def compactify(multilineRegex):
#     def crunch(seg):
# def pickle(data, pickleFilePrefix):
# def unpickle(pickleFilePrefix, default=None):
# def flattened(l):
# def hasdups(l, key=None):
# def uniqify(l):
# def uniqify2(l):
# def setupLogging(loggerId, args=None):
# def unsetupLogging():
# def logg(msg, outputs=None):
# def jj(*args, **kw):
# def jdb(*args, **kw):
# def run0(cmd):
# def run(cmd, logprefix='run', loglevel='INFO'):
#     def __init__(self, pkgname, fpath=None):
#     def path(self):
#     def content(self):
#     def keys(cls):
#     def vals(cls):
#     def items(cls):
#     def __init__(self):
#     def __call__(self, **kw):
#     def __init__(self, *maps, **kw):
#     def _getGetitems(self, mapp):
#     def __getitem__(self, key):
#     def __setitem__(self, key, val):
#     def __len__(self):
#     def __call__(self, *keys):
#     def clear(self):
#     def update(self, *maps):
#     def __add__(self, *maps):
#     def __iadd__(self, *maps):
#     def __iter__(self):
#     def iterkeys(self):
#     def keys(self):
#     def values(self):
#     def items(self):
#     def iteritems(self):
#     def get(self, key, dflt=None):
#     def __str__(self):
#     def __repr__(self):
# def notequalpatch(self, o):
#     def fromstring(cls, s):
#     def __hash__(self):
# def playQnty():
# def nth(n):
# def skip(s, substr):
# def until(s, substr):
# def ensure_dir(folder):
# def now(format=None):
# def readImgSize(fname, dirName):
# def asciiOnly(s):
# class NoSuchPickle(Exception):
# class PickleException(Exception):
# class Resource(object):
# class CharEnum(object):
# class ChainablyUpdatableOrderedDict(odict):
# class Bag(object):
# class Qnty(qq):


import re
import six
from . import ut, irs
from .ut import log, jj, numerify
        if end.startswith(prefix):
            prefix = ''
        startnum, endnum = numerify(start), numerify(end)
        start, end = (prefix + start, prefix + end)
        # find horizontally aligned non-cent start and end fields
        log.debug(' lineOrRange pg=%s start=%s end=%s fieldsByLine.pg,start=%s'
                  ' fieldsByLine.pg,end=%s',
                  pg, start, end, fieldsByLine[(pg, start)],
                  fieldsByLine[(pg, end)])
        startxpoz = [f['xpos'] for f in fieldsByLine[(pg, start)]
                     if f['unit'] != 'cents']
        endxpoz = [f['xpos'] for f in fieldsByLine[(pg, end)]
                   if f['unit'] != 'cents']
        for pos in startxpoz:
            if pos in endxpoz:
                startxpos = endxpos = pos
                break
        else:
            # no matching xpos for start and end lines so just use rightmost
            # xpos for each
            startxpos = max(startxpoz)
            endxpos = max(endxpoz)
        # todo make this less sensitive to adjustments in xpos for now, moved
        # dx adjustment from top of computeMath [where it wrecked havoc] to
        # writeEmptyHtmlPages/adjustxpos
        lines = ut.uniqify(
                    [(f['linenum'], f['unit'], f['xpos'])
                     for k, fs in fieldsByLine.items()
                     for f in fs
                     if f['linenum']

# Path: opentaxforms/ut.py
# NL = '\n'
# TAB = '\t'
# def merge(bb1, bb2):
# def numerify(s):
# def compactify(multilineRegex):
#     def crunch(seg):
# def pickle(data, pickleFilePrefix):
# def unpickle(pickleFilePrefix, default=None):
# def flattened(l):
# def hasdups(l, key=None):
# def uniqify(l):
# def uniqify2(l):
# def setupLogging(loggerId, args=None):
# def unsetupLogging():
# def logg(msg, outputs=None):
# def jj(*args, **kw):
# def jdb(*args, **kw):
# def run0(cmd):
# def run(cmd, logprefix='run', loglevel='INFO'):
#     def __init__(self, pkgname, fpath=None):
#     def path(self):
#     def content(self):
#     def keys(cls):
#     def vals(cls):
#     def items(cls):
#     def __init__(self):
#     def __call__(self, **kw):
#     def __init__(self, *maps, **kw):
#     def _getGetitems(self, mapp):
#     def __getitem__(self, key):
#     def __setitem__(self, key, val):
#     def __len__(self):
#     def __call__(self, *keys):
#     def clear(self):
#     def update(self, *maps):
#     def __add__(self, *maps):
#     def __iadd__(self, *maps):
#     def __iter__(self):
#     def iterkeys(self):
#     def keys(self):
#     def values(self):
#     def items(self):
#     def iteritems(self):
#     def get(self, key, dflt=None):
#     def __str__(self):
#     def __repr__(self):
# def notequalpatch(self, o):
#     def fromstring(cls, s):
#     def __hash__(self):
# def playQnty():
# def nth(n):
# def skip(s, substr):
# def until(s, substr):
# def ensure_dir(folder):
# def now(format=None):
# def readImgSize(fname, dirName):
# def asciiOnly(s):
# class NoSuchPickle(Exception):
# class PickleException(Exception):
# class Resource(object):
# class CharEnum(object):
# class ChainablyUpdatableOrderedDict(odict):
# class Bag(object):
# class Qnty(qq):


# Path: opentaxforms/cmds.py
import re
import six
from . import ut, irs
from .ut import log, jj, numerify

        if end.startswith(prefix):
            prefix = ''
        startnum, endnum = numerify(start), numerify(end)
        start, end = (prefix + start, prefix + end)
        # find horizontally aligned non-cent start and end fields
        log.debug(' lineOrRange pg=%s start=%s end=%s fieldsByLine.pg,start=%s'
                  ' fieldsByLine.pg,end=%s',
                  pg, start, end, fieldsByLine[(pg, start)],
                  fieldsByLine[(pg, end)])
        startxpoz = [f['xpos'] for f in fieldsByLine[(pg, start)]
                     if f['unit'] != 'cents']
        endxpoz = [f['xpos'] for f in fieldsByLine[(pg, end)]
                   if f['unit'] != 'cents']
        for pos in startxpoz:
            if pos in endxpoz:
                startxpos = endxpos = pos
                break
        else:
            # no matching xpos for start and end lines so just use rightmost
            # xpos for each
            startxpos = max(startxpoz)
            endxpos = max(endxpoz)
        # todo make this less sensitive to adjustments in xpos for now, moved
        # dx adjustment from top of computeMath [where it wrecked havoc] to
        # writeEmptyHtmlPages/adjustxpos
        lines = ut.uniqify(
                    [(f['linenum'], f['unit'], f['xpos'])
                     for k, fs in fieldsByLine.items()
                     for f in fs
                     if f['linenum']

                        and startnum <= numerify(f['linenum']) <= endnum