def packBest(self, autorotate=False):

        sheets, extraBlocks = [], []
        score = 0

        best = {
            'score': 0,
            'area': 10000000000000000000,
            'count': 10000000000000,
            'eff': 0
        }
        
        # Sort Functions
        def sortHeight(block):
            return (block.w, block.h, block.image.checksum)

        def sortWidth(block):
            return (block.h, block.w, block.image.checksum)

        def sortArea(block):
            return (block.w * block.h, block.w, block.h, block.image.checksum)

        sorts = [sortHeight, sortWidth, sortArea]
        rotationDiff = [(0, 0), (1.4, 0), (0, 1.4), (1.4, 1.4)] # rotate by 90 degrees if either b / a > value

        # Determine minimum size for spritesheet generation
        # by averaging the widths and heights of all images
        # while taking the ones in the sorted middile higher into account
        # then the ones at the outer edges of the spectirum


        l = len(self.files)
        mw = [(l - abs(i - l / 2)) / l * v for i, v in enumerate(sorted([i.width for i in self.files]))]
        mh = [(l - abs(i - l / 2)) / l * v for i, v in enumerate(sorted([i.height for i in self.files]))]

        minWidth = max(128, math.pow(2, math.ceil(math.log(sum(mw) / l, 2))))
        minHeight = max(128, math.pow(2, math.ceil(math.log(sum(mh) / l, 2))))

        #baseArea = sum([(l - abs(i - l / 2)) / l * v for i, v in enumerate(sorted([i.width * i.height for i in self.files]))])


        # try to skip senseless generation of way to small sprites
        baseArea = sum([minWidth * minHeight for i in self.files])
        while baseArea / (minWidth * minHeight) >= 20: # bascially an estimate of the number of sheets needed
            minWidth *= 2
            minHeight *= 2

        Console.debug('- Minimal size is %dx%dpx' % (minWidth, minHeight))

        sizes = list(itertools.product([w for w in [128, 256, 512, 1024, 2048] if w >= minWidth],
                                       [h for h in [128, 256, 512, 1024, 2048] if h >= minHeight]))

        if autorotate:
            methods = list(itertools.product(sorts, sizes, rotationDiff))

        else:
            methods = list(itertools.product(sorts, sizes, [(0, 0)]))

        Console.debug('Packing sprite sheet variants...')
        Console.indent()

        scores = []
        for sort, size, rotation in methods:

            # pack with current settings
            sh, ex, _ = self.pack(size[0], size[1], sort, silent=True, rotate=rotation)

            if len(sh):
                score = PackerScore(sh, ex)

                # Determine score, highest wins
                scores.append(score)

            else:
                Console.debug('No sprite sheets generated, no image fit into the sheet')

        Console.outdent()
        scores.sort()

        Console.debug('Generated the following sheets:')
        for i in scores:
            Console.debug('- ' + str(i))

        sheets, external = scores[0].data()
        
        if external:
            for block in external:
                Console.info('Ignored file %s (%dx%dpx)' % (block.image.relPath, block.w, block.h))
        
        return sheets, len(scores)
Performs a HTTP GET to address/validate/
dataset/ETHPy150Open zynga/jasy/jasy/asset/SpritePacker.py/SpritePacker.packBest--crossover with--dataset/ETHPy150Open activefrequency/pyavatax/pyavatax/api.py/API.validate_address