default variable filters import random as randommodule import re import types from decimal import roundhalfup context decimal invalidoperation getcontext from functools import wraps from inspect import unwrap from operator import itemgetter from pprint import pformat from urllib parse import quote from django utils import formats from django utils dateformat import format timeformat from django utils encoding import iritouri from django utils html import avoidwrapping conditionalescape escape escapejs from django utils html import jsonscript as jsonscript from django utils html import linebreaks striptags from django utils html import urlize as urlize from django utils safestring import safedata marksafe from django utils text import truncator normalizenewlines phone2numeric from django utils text import slugify as slugify from django utils text import wrap from django utils timesince import timesince timeuntil from django utils translation import gettext ngettext from base import variableattributeseparator from library import library register library string decorator def stringfilterfunc wrapsfunc def decfirst args kwargs first strfirst result funcfirst args kwargs if isinstancefirst safedata and getattrunwrapfunc issafe false result marksaferesult return result return dec strings register filterissafetrue stringfilter def addslashesvalue return value replace replace replace register filterissafetrue stringfilter def capfirstvalue hex encode characters for use in javascript strings return escapejsvalue register filterissafetrue def jsonscriptvalue elementidnone return jsonscriptvalue elementid register filterissafetrue def floatformattext arg1 forcegrouping false usel10n true if isinstancearg str lastchar arg1 if arg2 in gu ug forcegrouping true usel10n false arg arg 2 or 1 elif lastchar g forcegrouping true arg arg 1 or 1 elif lastchar u usel10n false arg arg 1 or 1 try inputval strtext d decimalinputval except invalidoperation try d decimalstrfloattext except valueerror invalidoperation typeerror return try p intarg except valueerror return inputval try m intd d except valueerror overflowerror invalidoperation return inputval if not m and p 0 return marksafe formats numberformat d intd 0 usel10nusel10n forcegroupingforcegrouping exp decimal1 scalebabsp set the precision high enough to avoid an exception 15789 tupl d astuple units lentupl1 units tupl2 if m else tupl2 prec absp units 1 prec maxgetcontext prec prec avoid conversion to scientific notation by accessing sign digits and exponent from decimal astuple directly roundedd d quantizeexp roundhalfup contextprecprec sign digits exponent roundedd astuple digits strdigit for digit in reverseddigits while lendigits absexponent digits append0 digits insertexponent if sign and roundedd digits append number joinreverseddigits return marksafe formats numberformat number absp usel10nusel10n forcegroupingforcegrouping register filterissafetrue stringfilter def iriencodevalue display text with line numbers lines value splitn find the maximum width of the line count for use with zero padding string format command width strlenstrlenlines if not autoescape or isinstancevalue safedata for i line in enumeratelines linesi 0 width d s i 1 line else for i line in enumeratelines linesi 0 width d s i 1 escapeline return marksafen joinlines register filterissafetrue stringfilter def lowervalue return the value turned into a list for an integer it s a list of digits for a string it s a list of characters convert to ascii convert spaces to hyphens remove characters that aren t alphanumerics underscores or hyphens convert to lowercase also strip leading and trailing whitespace format the variable according to the arg a string formatting specifier this specifier uses python string formatting syntax with the exception that the leading is dropped see https docs python orglibrarystdtypes htmlprintfstylestringformatting for documentation of python string formatting convert a string into titlecase t re subaz az lambda m m0 lower value title return re subrdaz lambda m m0 lower t register filterissafetrue stringfilter def truncatecharsvalue arg truncate html after arg number of chars preserve newlines in the html truncate a string after arg number of words remove newlines within the string truncate html after arg number of words preserve newlines in the html convert a string into all uppercase return value upper register filterissafefalse stringfilter def urlencodevalue safenone kwargs if safe is not none kwargssafe safe return quotevalue kwargs register filterissafetrue needsautoescapetrue stringfilter def urlizevalue autoescapetrue convert urls into clickable links truncating urls to the given character limit and adding relnofollow attribute to discourage spamming argument length to truncate urls to return the number of words return lenvalue split register filterissafetrue stringfilter def wordwrapvalue arg leftalign the value in a field of a given width return value ljustintarg register filterissafetrue stringfilter def rjustvalue arg center the value in a field of a given width return value centerintarg register filter stringfilter def cutvalue arg html strings mark the value as a string that should be autoescaped return conditionalescapevalue register filterissafetrue def escapeseqvalue return conditionalescapeobj for obj in value register filterissafetrue stringfilter def forceescapevalue return escapevalue register filterlinebreaks issafetrue needsautoescapetrue stringfilter def linebreaksfiltervalue autoescapetrue autoescape autoescape and not isinstancevalue safedata return marksafelinebreaksvalue autoescape register filterissafetrue needsautoescapetrue stringfilter def linebreaksbrvalue autoescapetrue autoescape autoescape and not isinstancevalue safedata value normalizenewlinesvalue if autoescape value escapevalue return marksafevalue replacen br register filterissafetrue stringfilter def safevalue a safe filter for sequences mark each element in the sequence individually as safe after converting them to strings return a list with the results strip all xhtml tags return striptagsvalue lists def propertyresolverarg try floatarg except valueerror if variableattributeseparator in arg or arg0 raise attributeerroraccess to private variables is forbidden parts arg splitvariableattributeseparator def resolvevalue for part in parts try value valuepart except attributeerror indexerror keyerror typeerror valueerror value getattrvalue part return value return resolve else return itemgetterarg register filterissafefalse def dictsortvalue arg try return sortedvalue keypropertyresolverarg except attributeerror typeerror return register filterissafefalse def dictsortreversedvalue arg try return sortedvalue keypropertyresolverarg reversetrue except attributeerror typeerror return register filterissafefalse def firstvalue join a list with a string like python s str joinlist try if autoescape data conditionalescapearg joinconditionalescapev for v in value else data arg joinvalue except typeerror fail silently if arg isn t iterable return value return marksafedata register filterissafetrue def lastvalue return the length of the value useful for lists try return lenvalue except valueerror typeerror return 0 register filterissafetrue def randomvalue return a slice of the list using the same syntax as python s list slicing recursively take a selfnested list and return an html unordered list without opening and closing ul tags assume the list is in the proper format for example if var contains states kansas lawrence topeka illinois then varunorderedlist returns listates ul likansas ul lilawrenceli litopekali ul li liillinoisli ul li integers add the arg to the value try return intvalue intarg except valueerror typeerror try return value arg except exception return register filterissafefalse def getdigitvalue arg try arg intarg value intvalue except valueerror return value fail silently for an invalid argument if arg 1 return value try return intstrvaluearg except indexerror return 0 dates register filterexpectslocaltimetrue issafefalse def datevalue argnone format a time according to the given format if value in none return try return formats timeformatvalue arg except attributeerror typeerror try return timeformatvalue arg except attributeerror typeerror return register filtertimesince issafefalse def timesincefiltervalue argnone format a date as the time until that date i e 4 days 6 hours if not value return try return timeuntilvalue arg except valueerror typeerror return logic register filterissafefalse def defaultvalue arg if value is none use given default if value is none return arg return value register filterissafefalse def divisiblebyvalue arg given a string mapping values for true false and optionally none return one of those strings according to the value value argument outputs true yeah no maybe yeah false yeah no maybe no none yeah no maybe maybe none yeah no no converts none to false if no mapping for none is given translators please do not add spaces around commas unpack list of wrong size no maybe value provided misc format the value like a humanreadable file size i e 13 kb 4 1 mb 102 bytes etc return a plural suffix if the value is not 1 1 or an object of length 1 by default use s as the suffix if value is 0 vote valuepluralize display votes if value is 1 vote valuepluralize display vote if value is 2 vote valuepluralize display votes if an argument is provided use that string instead if value is 0 class valuepluralize es display classes if value is 1 class valuepluralize es display class if value is 2 class valuepluralize es display classes if the provided argument contains a comma use the text before the comma for the singular case and the text after the comma for the plural case if value is 0 cand valuepluralize y ies display candies if value is 1 cand valuepluralize y ies display candy if value is 2 cand valuepluralize y ies display candies take a phone number and converts it in to its numerical equivalent return phone2numericvalue register filterissafetrue def pprintvalue string decorator decorator for filters which should only receive strings the object passed as the first positional argument will be converted to a string strings add slashes before quotes useful for escaping strings in csv for example less useful for escaping javascript use the escapejs filter instead capitalize the first character of the value hex encode characters for use in javascript strings output value json encoded wrapped in a script type application json tag with an optional id display a float to a specified number of decimal places if called without an argument display the floating point number with one decimal place but only if there s a decimal place to be displayed num1 34 23234 num2 34 00000 num3 34 26000 num1 floatformat displays 34 2 num2 floatformat displays 34 num3 floatformat displays 34 3 if arg is positive always display exactly arg number of decimal places num1 floatformat 3 displays 34 232 num2 floatformat 3 displays 34 000 num3 floatformat 3 displays 34 260 if arg is negative display arg number of decimal places but only if there are places to be displayed num1 floatformat 3 displays 34 232 num2 floatformat 3 displays 34 num3 floatformat 3 displays 34 260 if arg has the g suffix force the result to be grouped by the thousand_separator for the active locale when the active locale is en english 6666 6666 floatformat 2g displays 6 666 67 10000 floatformat g displays 10 000 if arg has the u suffix force the result to be unlocalized when the active locale is pl polish 66666 6666 floatformat 2 displays 66666 67 66666 6666 floatformat 2u displays 66666 67 if the input float is infinity or nan display the string representation of that value set the precision high enough to avoid an exception 15789 avoid conversion to scientific notation by accessing sign digits and exponent from decimal as_tuple directly escape an iri value for use in a url display text with line numbers find the maximum width of the line count for use with zero padding string format command convert a string into all lowercase return the value turned into a list for an integer it s a list of digits for a string it s a list of characters convert to ascii convert spaces to hyphens remove characters that aren t alphanumerics underscores or hyphens convert to lowercase also strip leading and trailing whitespace format the variable according to the arg a string formatting specifier this specifier uses python string formatting syntax with the exception that the leading is dropped see https docs python org library stdtypes html printf style string formatting for documentation of python string formatting convert a string into titlecase truncate a string after arg number of characters invalid literal for int fail silently truncate html after arg number of chars preserve newlines in the html invalid literal for int fail silently truncate a string after arg number of words remove newlines within the string invalid literal for int fail silently truncate html after arg number of words preserve newlines in the html invalid literal for int fail silently convert a string into all uppercase escape a value for use in a url the safe parameter determines the characters which should not be escaped by python s quote function if not provided use the default safe characters but an empty string can be provided when all characters should be escaped convert urls in plain text into clickable links convert urls into clickable links truncating urls to the given character limit and adding rel nofollow attribute to discourage spamming argument length to truncate urls to return the number of words wrap words at arg line length left align the value in a field of a given width right align the value in a field of a given width center the value in a field of a given width remove all values of arg from the given string html strings mark the value as a string that should be auto escaped an escape filter for sequences mark each element in the sequence individually as a string that should be auto escaped return a list with the results escape a string s html return a new string containing the escaped characters as opposed to escape which marks the content for later possible escaping replace line breaks in plain text with appropriate html a single newline becomes an html line break br and a new line followed by a blank line becomes a paragraph break p convert all newlines in a piece of plain text to html line breaks br mark the value as a string that should not be auto escaped a safe filter for sequences mark each element in the sequence individually as safe after converting them to strings return a list with the results strip all x html tags lists when arg is convertible to float behave like operator itemgetter arg otherwise chain __getitem__ and getattr _property_resolver 1 abc b _property_resolver 1 abc traceback most recent call last typeerror string indices must be integers class foo a 42 b 3 14 c hey _property_resolver b foo 3 14 given a list of dicts return that list sorted by the property given in the argument given a list of dicts return that list sorted in reverse order by the property given in the argument return the first item in a list join a list with a string like python s str join list fail silently if arg isn t iterable return the last item in a list return the length of the value useful for lists return a random item from the list return a slice of the list using the same syntax as python s list slicing fail silently recursively take a self nested list and return an html unordered list without opening and closing ul tags assume the list is in the proper format for example if var contains states kansas lawrence topeka illinois then var unordered_list returns li states ul li kansas ul li lawrence li li topeka li ul li li illinois li ul li integers add the arg to the value given a whole number return the requested digit of it where 1 is the right most digit 2 is the second right most digit etc return the original value for invalid input if input or argument is not an integer or if argument is less than 1 otherwise output is always an integer fail silently for an invalid argument dates format a date according to the given format format a time according to the given format format a date as the time since that date i e 4 days 6 hours format a date as the time until that date i e 4 days 6 hours logic if value is unavailable use given default if value is none use given default return true if the value is divisible by the argument given a string mapping values for true false and optionally none return one of those strings according to the value value argument outputs true yeah no maybe yeah false yeah no maybe no none yeah no maybe maybe none yeah no no converts none to false if no mapping for none is given translators please do not add spaces around commas invalid arg unpack list of wrong size no maybe value provided misc format the value like a human readable file size i e 13 kb 4 1 mb 102 bytes etc allow formatting of negative numbers return a plural suffix if the value is not 1 1 or an object of length 1 by default use s as the suffix if value is 0 vote value pluralize display votes if value is 1 vote value pluralize display vote if value is 2 vote value pluralize display votes if an argument is provided use that string instead if value is 0 class value pluralize es display classes if value is 1 class value pluralize es display class if value is 2 class value pluralize es display classes if the provided argument contains a comma use the text before the comma for the singular case and the text after the comma for the plural case if value is 0 cand value pluralize y ies display candies if value is 1 cand value pluralize y ies display candy if value is 2 cand value pluralize y ies display candies invalid string that s not a number value isn t a string or a number maybe it s a list len of unsized object take a phone number and converts it in to its numerical equivalent a wrapper around pprint pprint for debugging really
import random as random_module
import re
import types
from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation, getcontext
from functools import wraps
from inspect import unwrap
from operator import itemgetter
from pprint import pformat
from urllib.parse import quote

from django.utils import formats
from django.utils.dateformat import format, time_format
from django.utils.encoding import iri_to_uri
from django.utils.html import avoid_wrapping, conditional_escape, escape, escapejs
from django.utils.html import json_script as _json_script
from django.utils.html import linebreaks, strip_tags
from django.utils.html import urlize as _urlize
from django.utils.safestring import SafeData, mark_safe
from django.utils.text import Truncator, normalize_newlines, phone2numeric
from django.utils.text import slugify as _slugify
from django.utils.text import wrap
from django.utils.timesince import timesince, timeuntil
from django.utils.translation import gettext, ngettext

from .base import VARIABLE_ATTRIBUTE_SEPARATOR
from .library import Library

register = Library()







def stringfilter(func):
    

    @wraps(func)
    def _dec(first, *args, **kwargs):
        first = str(first)
        result = func(first, *args, **kwargs)
        if isinstance(first, SafeData) and getattr(unwrap(func), "is_safe", False):
            result = mark_safe(result)
        return result

    return _dec







@register.filter(is_safe=True)
@stringfilter
def addslashes(value):
    
    return value.replace("\\", "\\\\").replace('"', '\\"').replace("'", "\\'")


@register.filter(is_safe=True)
@stringfilter
def capfirst(value):
    
    return value and value[0].upper() + value[1:]


@register.filter("escapejs")
@stringfilter
def escapejs_filter(value):
    
    return escapejs(value)


@register.filter(is_safe=True)
def json_script(value, element_id=None):
    
    return _json_script(value, element_id)


@register.filter(is_safe=True)
def floatformat(text, arg=-1):
    
    force_grouping = False
    use_l10n = True
    if isinstance(arg, str):
        last_char = arg[-1]
        if arg[-2:] in {"gu", "ug"}:
            force_grouping = True
            use_l10n = False
            arg = arg[:-2] or -1
        elif last_char == "g":
            force_grouping = True
            arg = arg[:-1] or -1
        elif last_char == "u":
            use_l10n = False
            arg = arg[:-1] or -1
    try:
        input_val = str(text)
        d = Decimal(input_val)
    except InvalidOperation:
        try:
            d = Decimal(str(float(text)))
        except (ValueError, InvalidOperation, TypeError):
            return ""
    try:
        p = int(arg)
    except ValueError:
        return input_val

    try:
        m = int(d) - d
    except (ValueError, OverflowError, InvalidOperation):
        return input_val

    if not m and p <= 0:
        return mark_safe(
            formats.number_format(
                "%d" % (int(d)),
                0,
                use_l10n=use_l10n,
                force_grouping=force_grouping,
            )
        )

    exp = Decimal(1).scaleb(-abs(p))
    
    tupl = d.as_tuple()
    units = len(tupl[1])
    units += -tupl[2] if m else tupl[2]
    prec = abs(p) + units + 1
    prec = max(getcontext().prec, prec)

    
    
    rounded_d = d.quantize(exp, ROUND_HALF_UP, Context(prec=prec))
    sign, digits, exponent = rounded_d.as_tuple()
    digits = [str(digit) for digit in reversed(digits)]
    while len(digits) <= abs(exponent):
        digits.append("0")
    digits.insert(-exponent, ".")
    if sign and rounded_d:
        digits.append("-")
    number = "".join(reversed(digits))
    return mark_safe(
        formats.number_format(
            number,
            abs(p),
            use_l10n=use_l10n,
            force_grouping=force_grouping,
        )
    )


@register.filter(is_safe=True)
@stringfilter
def iriencode(value):
    
    return iri_to_uri(value)


@register.filter(is_safe=True, needs_autoescape=True)
@stringfilter
def linenumbers(value, autoescape=True):
    
    lines = value.split("\n")
    
    
    width = str(len(str(len(lines))))
    if not autoescape or isinstance(value, SafeData):
        for i, line in enumerate(lines):
            lines[i] = ("%0" + width + "d. %s") % (i + 1, line)
    else:
        for i, line in enumerate(lines):
            lines[i] = ("%0" + width + "d. %s") % (i + 1, escape(line))
    return mark_safe("\n".join(lines))


@register.filter(is_safe=True)
@stringfilter
def lower(value):
    
    return value.lower()


@register.filter(is_safe=False)
@stringfilter
def make_list(value):
    
    return list(value)


@register.filter(is_safe=True)
@stringfilter
def slugify(value):
    
    return _slugify(value)


@register.filter(is_safe=True)
def stringformat(value, arg):
    
    if isinstance(value, tuple):
        value = str(value)
    try:
        return ("%" + str(arg)) % value
    except (ValueError, TypeError):
        return ""


@register.filter(is_safe=True)
@stringfilter
def title(value):
    
    t = re.sub("([a-z])'([A-Z])", lambda m: m[0].lower(), value.title())
    return re.sub(r"\d([A-Z])", lambda m: m[0].lower(), t)


@register.filter(is_safe=True)
@stringfilter
def truncatechars(value, arg):
    
    try:
        length = int(arg)
    except ValueError:  
        return value  
    return Truncator(value).chars(length)


@register.filter(is_safe=True)
@stringfilter
def truncatechars_html(value, arg):
    
    try:
        length = int(arg)
    except ValueError:  
        return value  
    return Truncator(value).chars(length, html=True)


@register.filter(is_safe=True)
@stringfilter
def truncatewords(value, arg):
    
    try:
        length = int(arg)
    except ValueError:  
        return value  
    return Truncator(value).words(length, truncate=" …")


@register.filter(is_safe=True)
@stringfilter
def truncatewords_html(value, arg):
    
    try:
        length = int(arg)
    except ValueError:  
        return value  
    return Truncator(value).words(length, html=True, truncate=" …")


@register.filter(is_safe=False)
@stringfilter
def upper(value):
    
    return value.upper()


@register.filter(is_safe=False)
@stringfilter
def urlencode(value, safe=None):
    
    kwargs = {}
    if safe is not None:
        kwargs["safe"] = safe
    return quote(value, **kwargs)


@register.filter(is_safe=True, needs_autoescape=True)
@stringfilter
def urlize(value, autoescape=True):
    
    return mark_safe(_urlize(value, nofollow=True, autoescape=autoescape))


@register.filter(is_safe=True, needs_autoescape=True)
@stringfilter
def urlizetrunc(value, limit, autoescape=True):
    
    return mark_safe(
        _urlize(value, trim_url_limit=int(limit), nofollow=True, autoescape=autoescape)
    )


@register.filter(is_safe=False)
@stringfilter
def wordcount(value):
    
    return len(value.split())


@register.filter(is_safe=True)
@stringfilter
def wordwrap(value, arg):
    
    return wrap(value, int(arg))


@register.filter(is_safe=True)
@stringfilter
def ljust(value, arg):
    
    return value.ljust(int(arg))


@register.filter(is_safe=True)
@stringfilter
def rjust(value, arg):
    
    return value.rjust(int(arg))


@register.filter(is_safe=True)
@stringfilter
def center(value, arg):
    
    return value.center(int(arg))


@register.filter
@stringfilter
def cut(value, arg):
    
    safe = isinstance(value, SafeData)
    value = value.replace(arg, "")
    if safe and arg != ";":
        return mark_safe(value)
    return value







@register.filter("escape", is_safe=True)
@stringfilter
def escape_filter(value):
    
    return conditional_escape(value)


@register.filter(is_safe=True)
def escapeseq(value):
    
    return [conditional_escape(obj) for obj in value]


@register.filter(is_safe=True)
@stringfilter
def force_escape(value):
    
    return escape(value)


@register.filter("linebreaks", is_safe=True, needs_autoescape=True)
@stringfilter
def linebreaks_filter(value, autoescape=True):
    
    autoescape = autoescape and not isinstance(value, SafeData)
    return mark_safe(linebreaks(value, autoescape))


@register.filter(is_safe=True, needs_autoescape=True)
@stringfilter
def linebreaksbr(value, autoescape=True):
    
    autoescape = autoescape and not isinstance(value, SafeData)
    value = normalize_newlines(value)
    if autoescape:
        value = escape(value)
    return mark_safe(value.replace("\n", "<br>"))


@register.filter(is_safe=True)
@stringfilter
def safe(value):
    
    return mark_safe(value)


@register.filter(is_safe=True)
def safeseq(value):
    
    return [mark_safe(obj) for obj in value]


@register.filter(is_safe=True)
@stringfilter
def striptags(value):
    
    return strip_tags(value)







def _property_resolver(arg):
    
    try:
        float(arg)
    except ValueError:
        if VARIABLE_ATTRIBUTE_SEPARATOR + "_" in arg or arg[0] == "_":
            raise AttributeError("Access to private variables is forbidden.")
        parts = arg.split(VARIABLE_ATTRIBUTE_SEPARATOR)

        def resolve(value):
            for part in parts:
                try:
                    value = value[part]
                except (AttributeError, IndexError, KeyError, TypeError, ValueError):
                    value = getattr(value, part)
            return value

        return resolve
    else:
        return itemgetter(arg)


@register.filter(is_safe=False)
def dictsort(value, arg):
    
    try:
        return sorted(value, key=_property_resolver(arg))
    except (AttributeError, TypeError):
        return ""


@register.filter(is_safe=False)
def dictsortreversed(value, arg):
    
    try:
        return sorted(value, key=_property_resolver(arg), reverse=True)
    except (AttributeError, TypeError):
        return ""


@register.filter(is_safe=False)
def first(value):
    
    try:
        return value[0]
    except IndexError:
        return ""


@register.filter(is_safe=True, needs_autoescape=True)
def join(value, arg, autoescape=True):
    
    try:
        if autoescape:
            data = conditional_escape(arg).join([conditional_escape(v) for v in value])
        else:
            data = arg.join(value)
    except TypeError:  
        return value
    return mark_safe(data)


@register.filter(is_safe=True)
def last(value):
    
    try:
        return value[-1]
    except IndexError:
        return ""


@register.filter(is_safe=False)
def length(value):
    
    try:
        return len(value)
    except (ValueError, TypeError):
        return 0


@register.filter(is_safe=True)
def random(value):
    
    try:
        return random_module.choice(value)
    except IndexError:
        return ""


@register.filter("slice", is_safe=True)
def slice_filter(value, arg):
    
    try:
        bits = []
        for x in str(arg).split(":"):
            if not x:
                bits.append(None)
            else:
                bits.append(int(x))
        return value[slice(*bits)]

    except (ValueError, TypeError):
        return value  


@register.filter(is_safe=True, needs_autoescape=True)
def unordered_list(value, autoescape=True):
    
    if autoescape:
        escaper = conditional_escape
    else:

        def escaper(x):
            return x

    def walk_items(item_list):
        item_iterator = iter(item_list)
        try:
            item = next(item_iterator)
            while True:
                try:
                    next_item = next(item_iterator)
                except StopIteration:
                    yield item, None
                    break
                if isinstance(next_item, (list, tuple, types.GeneratorType)):
                    try:
                        iter(next_item)
                    except TypeError:
                        pass
                    else:
                        yield item, next_item
                        item = next(item_iterator)
                        continue
                yield item, None
                item = next_item
        except StopIteration:
            pass

    def list_formatter(item_list, tabs=1):
        indent = "\t" * tabs
        output = []
        for item, children in walk_items(item_list):
            sublist = ""
            if children:
                sublist = "\n%s<ul>\n%s\n%s</ul>\n%s" % (
                    indent,
                    list_formatter(children, tabs + 1),
                    indent,
                    indent,
                )
            output.append("%s<li>%s%s</li>" % (indent, escaper(item), sublist))
        return "\n".join(output)

    return mark_safe(list_formatter(value))







@register.filter(is_safe=False)
def add(value, arg):
    
    try:
        return int(value) + int(arg)
    except (ValueError, TypeError):
        try:
            return value + arg
        except Exception:
            return ""


@register.filter(is_safe=False)
def get_digit(value, arg):
    
    try:
        arg = int(arg)
        value = int(value)
    except ValueError:
        return value  
    if arg < 1:
        return value
    try:
        return int(str(value)[-arg])
    except IndexError:
        return 0







@register.filter(expects_localtime=True, is_safe=False)
def date(value, arg=None):
    
    if value in (None, ""):
        return ""
    try:
        return formats.date_format(value, arg)
    except AttributeError:
        try:
            return format(value, arg)
        except AttributeError:
            return ""


@register.filter(expects_localtime=True, is_safe=False)
def time(value, arg=None):
    
    if value in (None, ""):
        return ""
    try:
        return formats.time_format(value, arg)
    except (AttributeError, TypeError):
        try:
            return time_format(value, arg)
        except (AttributeError, TypeError):
            return ""


@register.filter("timesince", is_safe=False)
def timesince_filter(value, arg=None):
    
    if not value:
        return ""
    try:
        if arg:
            return timesince(value, arg)
        return timesince(value)
    except (ValueError, TypeError):
        return ""


@register.filter("timeuntil", is_safe=False)
def timeuntil_filter(value, arg=None):
    
    if not value:
        return ""
    try:
        return timeuntil(value, arg)
    except (ValueError, TypeError):
        return ""







@register.filter(is_safe=False)
def default(value, arg):
    
    return value or arg


@register.filter(is_safe=False)
def default_if_none(value, arg):
    
    if value is None:
        return arg
    return value


@register.filter(is_safe=False)
def divisibleby(value, arg):
    
    return int(value) % int(arg) == 0


@register.filter(is_safe=False)
def yesno(value, arg=None):
    
    if arg is None:
        
        arg = gettext("yes,no,maybe")
    bits = arg.split(",")
    if len(bits) < 2:
        return value  
    try:
        yes, no, maybe = bits
    except ValueError:
        
        yes, no, maybe = bits[0], bits[1], bits[1]
    if value is None:
        return maybe
    if value:
        return yes
    return no







@register.filter(is_safe=True)
def filesizeformat(bytes_):
    
    try:
        bytes_ = int(bytes_)
    except (TypeError, ValueError, UnicodeDecodeError):
        value = ngettext("%(size)d byte", "%(size)d bytes", 0) % {"size": 0}
        return avoid_wrapping(value)

    def filesize_number_format(value):
        return formats.number_format(round(value, 1), 1)

    KB = 1 << 10
    MB = 1 << 20
    GB = 1 << 30
    TB = 1 << 40
    PB = 1 << 50

    negative = bytes_ < 0
    if negative:
        bytes_ = -bytes_  

    if bytes_ < KB:
        value = ngettext("%(size)d byte", "%(size)d bytes", bytes_) % {"size": bytes_}
    elif bytes_ < MB:
        value = gettext("%s KB") % filesize_number_format(bytes_ / KB)
    elif bytes_ < GB:
        value = gettext("%s MB") % filesize_number_format(bytes_ / MB)
    elif bytes_ < TB:
        value = gettext("%s GB") % filesize_number_format(bytes_ / GB)
    elif bytes_ < PB:
        value = gettext("%s TB") % filesize_number_format(bytes_ / TB)
    else:
        value = gettext("%s PB") % filesize_number_format(bytes_ / PB)

    if negative:
        value = "-%s" % value
    return avoid_wrapping(value)


@register.filter(is_safe=False)
def pluralize(value, arg="s"):
    
    if "," not in arg:
        arg = "," + arg
    bits = arg.split(",")
    if len(bits) > 2:
        return ""
    singular_suffix, plural_suffix = bits[:2]

    try:
        return singular_suffix if float(value) == 1 else plural_suffix
    except ValueError:  
        pass
    except TypeError:  
        try:
            return singular_suffix if len(value) == 1 else plural_suffix
        except TypeError:  
            pass
    return ""


@register.filter("phone2numeric", is_safe=True)
def phone2numeric_filter(value):
    
    return phone2numeric(value)


@register.filter(is_safe=True)
def pprint(value):
    
    try:
        return pformat(value)
    except Exception as e:
        return "Error in formatting: %s: %s" % (e.__class__.__name__, e)