def levels(self):
        """
        A generator of (idx, label) sequences representing the category
        hierarchy from the bottom up. The first level contains all leaf
        categories, and each subsequent is the next level up.
        """
        def levels(categories):
            # yield all lower levels
            sub_categories = [
                sc for c in categories for sc in c.sub_categories
            ]
            if sub_categories:
                for level in levels(sub_categories):
                    yield level
            # yield this level
            yield [(cat.idx, cat.label) for cat in categories]

        for level in levels(self):
            yield level