def find_and_tap_episode_by_ocr(self, target):
        import imgreco.common
        import imgreco.map
        import imgreco.stage_ocr
        from resources.imgreco.map_vectors import ep2region, region2ep
        target_region = ep2region.get(target)
        if target_region is None:
            self.logger.error(f'未能定位章节区域, target: {target}')
            raise RuntimeError('recognition failed')
        vw, vh = imgreco.common.get_vwvh(self.viewport)
        episode_tag_rect = tuple(
            map(int, (34.861 * vh, 40.139 * vh, 50.139 * vh, 43.194 * vh)))
        next_ep_region_rect = (6.389 * vh, 73.750 * vh, 33.889 * vh,
                               80.417 * vh)
        prev_ep_region_rect = (6.389 * vh, 15.556 * vh, 33.889 * vh,
                               22.083 * vh)
        current_ep_rect = (50 * vw + 19.907 * vh, 28.426 * vh,
                           50 * vw + 63.426 * vh, 71.944 * vh)
        episode_move = (400 * self.viewport[1] / 1080)

        while True:
            screenshot = self.device.screenshot()
            current_episode_tag = screenshot.crop(episode_tag_rect)
            current_episode_str = imgreco.stage_ocr.do_img_ocr(
                current_episode_tag)
            self.logger.info(f'当前章节: {current_episode_str}')
            if not current_episode_str.startswith('EPISODE'):
                self.logger.error(
                    f'章节识别失败, current_episode_str: {current_episode_str}')
                raise RuntimeError('recognition failed')
            current_episode = int(current_episode_str[7:])
            current_region = ep2region.get(current_episode)
            if current_region is None:
                self.logger.error(
                    f'未能定位章节区域, current_episode: {current_episode}')
                raise RuntimeError('recognition failed')
            if current_region == target_region:
                break
            if current_region > target_region:
                self.logger.info(f'前往上一章节区域')
                self.tap_rect(prev_ep_region_rect)
            else:
                self.logger.info(f'前往下一章节区域')
                self.tap_rect(next_ep_region_rect)
        while current_episode != target:
            move = min(abs(current_episode - target), 2) * episode_move * (
                1 if current_episode > target else -1)
            self.swipe_screen(move, 10, self.viewport[0] // 4 * 3)
            screenshot = self.device.screenshot()
            current_episode_tag = screenshot.crop(episode_tag_rect)
            current_episode_str = imgreco.stage_ocr.do_img_ocr(
                current_episode_tag)
            self.logger.info(f'当前章节: {current_episode_str}')
            current_episode = int(current_episode_str[7:])

        self.logger.info(f'进入章节: {current_episode_str}')
        self.tap_rect(current_ep_rect)
    def find_and_tap_episode_by_ocr(self, target):
        import imgreco.stage_ocr
        from resources.imgreco.map_vectors import ep2region, region2ep
        target_region = ep2region.get(target)
        if target_region is None:
            logger.error(f'未能定位章节区域, target: {target}')
            raise RuntimeError('recognition failed')
        vw, vh = imgreco.util.get_vwvh(self.viewport)
        episode_tag_rect = tuple(
            map(int, (35.185 * vh, 39.259 * vh, 50.093 * vh, 43.056 * vh)))
        next_ep_region_rect = (5.833 * vh, 69.167 * vh, 11.944 * vh,
                               74.815 * vh)
        prev_ep_region_rect = (5.833 * vh, 15.370 * vh, 11.944 * vh,
                               21.481 * vh)
        current_ep_rect = (50 * vw + 19.907 * vh, 28.426 * vh,
                           50 * vw + 63.426 * vh, 71.944 * vh)
        episode_move = (400 * self.viewport[1] / 1080)

        while True:
            screenshot = self.adb.screenshot()
            current_episode_tag = screenshot.crop(episode_tag_rect)
            current_episode_str = imgreco.stage_ocr.do_img_ocr(
                current_episode_tag)
            logger.info(f'当前章节: {current_episode_str}')
            if not current_episode_str.startswith('EPISODE'):
                logger.error(
                    f'章节识别失败, current_episode_str: {current_episode_str}')
                raise RuntimeError('recognition failed')
            current_episode = int(current_episode_str[7:])
            current_region = ep2region.get(current_episode)
            if current_region is None:
                logger.error(f'未能定位章节区域, current_episode: {current_episode}')
                raise RuntimeError('recognition failed')
            if current_region == target_region:
                break
            if current_region > target_region:
                logger.info(f'前往上一章节区域')
                self.tap_rect(prev_ep_region_rect)
            else:
                logger.info(f'前往下一章节区域')
                self.tap_rect(next_ep_region_rect)
        while current_episode != target:
            move = min(abs(current_episode - target), 2) * episode_move * (
                1 if current_episode > target else -1)
            self.__swipe_screen(move, 10, self.viewport[0] // 4 * 3)
            screenshot = self.adb.screenshot()
            current_episode_tag = screenshot.crop(episode_tag_rect)
            current_episode_str = imgreco.stage_ocr.do_img_ocr(
                current_episode_tag)
            logger.info(f'当前章节: {current_episode_str}')
            current_episode = int(current_episode_str[7:])

        logger.info(f'进入章节: {current_episode_str}')
        self.tap_rect(current_ep_rect)