# Path: src/formpack/constants.py
# UNSPECIFIED_TRANSLATION = False
# 
# Path: src/formpack/submission.py
# class FormSubmission:
#     def __init__(self, submission_data=None, version=None):
#         self.data = submission_data or {}
#         self._version = version
# 
#         for key in submission_data:
#             val = submission_data[key]
#             if B64Attachment._is_attachment(val):
#                 submission_data[key] = B64Attachment(val)
# 
#     def to_dict(self):
#         return self.data
# 
#     def to_xml_struct(self, files=False):
#         def _item_to_struct(item):
#             key, val = item
#             if isinstance(val, list):
#                 val = list(map(_item_to_struct, val))
#             elif isinstance(val, B64Attachment) and files is not False:
#                 (fname, fpath) = B64Attachment.write_to_tempfile(val)
#                 files.append([fname, fpath])
#                 val = fname
#             return {'tag': key, 'attributes': {}, 'children': val}
# 
#         return {
#             'tag': self._version._root_node_name or 'data',
#             'attributes': {
#                 'id_string': self._version.id_string,
#                 'version': self._version._version_id,
#             },
#             'children': [
#                 _item_to_struct(item) for item in iter(self.data.items())
#             ],
#         }
# 
#     def to_xml(self, files=False):
#         return xmljson_to_xml(self.to_xml_struct(files))
# 
#     def to_xml_export(self):
#         files = []
#         return self.to_xml(), files
# 
#     @classmethod
#     def from_xml(cls, xml, version=None):
#         xmljson = OrderedDict(parse_xmljson_to_data(xml, [], []))
#         return cls(xmljson, version)
# 
# Path: src/formpack/utils/ordered_collection.py
# class OrderedCounter(Counter, OrderedDict):
#     """
#     Counter that keeps insertion order compatible with Python 2.7+
# 
#     Useless for Python3.6+ because Counter keeps insertion order.
# 
#     Source: https://stackoverflow.com/a/23747652
#     """
# 
#     def __repr__(self):
#         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
# 
#     def __reduce__(self):
#         return self.__class__, (OrderedDict(self),)
# 
#     def most_common(self, n=None, ordered=False):
#         """
#         If `ordered` is `True`, it sorts (ascendant) elements with equal counts,
#         not ordered arbitrarily like `Counter` does.
# 
#         TODO: Not used with ordered=True so far. Discuss with other members of
#         team if it's needed, otherwise delete it.
# 
#         Args:
#             n (int): Optional
#             ordered (bool): Optional
# 
#         Returns:
#             list: list of tuples (items, count)
#         """
#         if ordered is False:
#             return super().most_common(n)
# 
#         # We can use `lambda x: (-x[1], x[0])` to sort by:
#         # - second element (descendant order)
#         # - first element (ascendant order)
#         # because elements of `Counter` are tuples (<item>, <count)
#         most_common_ = sorted(
#             iter(self.items()), key=lambda x: (-x[1], orderable_with_none(x[0]))
#         )
#         if n is None:
#             return most_common_
# 
#         return most_common_[:n]


import logging
from collections import defaultdict
from ..constants import UNSPECIFIED_TRANSLATION
from ..submission import FormSubmission
from ..utils.ordered_collection import OrderedCounter
                            counter['__submissions__'] += 1
                    else:
                        counter[None] += 1

        def stats_generator():
            for field in fields:
                yield (
                    field,
                    field.get_labels(lang)[0],
                    field.get_stats(metrics[field.name], lang=lang),
                )

        return AutoReportStats(
            self,
            stats_generator(),
            submissions_count,
            submission_counts_by_version,
        )

    def _disaggregate_stats(
        self, submissions, fields, versions, lang, split_by_field
    ):

        # We want only the most used values so we build a separate counter
        # for it to filter them
        splitters_rank = OrderedCounter()
        # Extract the split_by field from the values to get stats on

        # total number of submissions
        submissions_count = 0

# Path: src/formpack/constants.py
# UNSPECIFIED_TRANSLATION = False
# 
# Path: src/formpack/submission.py
# class FormSubmission:
#     def __init__(self, submission_data=None, version=None):
#         self.data = submission_data or {}
#         self._version = version
# 
#         for key in submission_data:
#             val = submission_data[key]
#             if B64Attachment._is_attachment(val):
#                 submission_data[key] = B64Attachment(val)
# 
#     def to_dict(self):
#         return self.data
# 
#     def to_xml_struct(self, files=False):
#         def _item_to_struct(item):
#             key, val = item
#             if isinstance(val, list):
#                 val = list(map(_item_to_struct, val))
#             elif isinstance(val, B64Attachment) and files is not False:
#                 (fname, fpath) = B64Attachment.write_to_tempfile(val)
#                 files.append([fname, fpath])
#                 val = fname
#             return {'tag': key, 'attributes': {}, 'children': val}
# 
#         return {
#             'tag': self._version._root_node_name or 'data',
#             'attributes': {
#                 'id_string': self._version.id_string,
#                 'version': self._version._version_id,
#             },
#             'children': [
#                 _item_to_struct(item) for item in iter(self.data.items())
#             ],
#         }
# 
#     def to_xml(self, files=False):
#         return xmljson_to_xml(self.to_xml_struct(files))
# 
#     def to_xml_export(self):
#         files = []
#         return self.to_xml(), files
# 
#     @classmethod
#     def from_xml(cls, xml, version=None):
#         xmljson = OrderedDict(parse_xmljson_to_data(xml, [], []))
#         return cls(xmljson, version)
# 
# Path: src/formpack/utils/ordered_collection.py
# class OrderedCounter(Counter, OrderedDict):
#     """
#     Counter that keeps insertion order compatible with Python 2.7+
# 
#     Useless for Python3.6+ because Counter keeps insertion order.
# 
#     Source: https://stackoverflow.com/a/23747652
#     """
# 
#     def __repr__(self):
#         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
# 
#     def __reduce__(self):
#         return self.__class__, (OrderedDict(self),)
# 
#     def most_common(self, n=None, ordered=False):
#         """
#         If `ordered` is `True`, it sorts (ascendant) elements with equal counts,
#         not ordered arbitrarily like `Counter` does.
# 
#         TODO: Not used with ordered=True so far. Discuss with other members of
#         team if it's needed, otherwise delete it.
# 
#         Args:
#             n (int): Optional
#             ordered (bool): Optional
# 
#         Returns:
#             list: list of tuples (items, count)
#         """
#         if ordered is False:
#             return super().most_common(n)
# 
#         # We can use `lambda x: (-x[1], x[0])` to sort by:
#         # - second element (descendant order)
#         # - first element (ascendant order)
#         # because elements of `Counter` are tuples (<item>, <count)
#         most_common_ = sorted(
#             iter(self.items()), key=lambda x: (-x[1], orderable_with_none(x[0]))
#         )
#         if n is None:
#             return most_common_
# 
#         return most_common_[:n]


# Path: src/formpack/reporting/autoreport.py
import logging
from collections import defaultdict
from ..constants import UNSPECIFIED_TRANSLATION
from ..submission import FormSubmission
from ..utils.ordered_collection import OrderedCounter

                            counter['__submissions__'] += 1
                    else:
                        counter[None] += 1

        def stats_generator():
            for field in fields:
                yield (
                    field,
                    field.get_labels(lang)[0],
                    field.get_stats(metrics[field.name], lang=lang),
                )

        return AutoReportStats(
            self,
            stats_generator(),
            submissions_count,
            submission_counts_by_version,
        )

    def _disaggregate_stats(
        self, submissions, fields, versions, lang, split_by_field
    ):

        # We want only the most used values so we build a separate counter
        # for it to filter them
        splitters_rank = OrderedCounter()
        # Extract the split_by field from the values to get stats on

        # total number of submissions
        submissions_count = 0

        submission_counts_by_version = OrderedCounter()