class BatoRipper extends AbstractHTMLRipper {

    public BatoRipper(URL url) throws IOException {
        super(url);
    }

    @Override
    public String getHost() {
        return "bato";
    }

    @Override
    public String getDomain() {
        return "bato.to";
    }

    @Override
    public String getGID(URL url) throws MalformedURLException {
        Pattern p = Pattern.compile("https?://bato.to/chapter/([\\d]+)/?");
        Matcher m = p.matcher(url.toExternalForm());
        if (m.matches()) {
            return m.group(1);
        }
        // As this is just for quick queue support it does matter what this if returns
        p = Pattern.compile("https?://bato.to/series/([\\d]+)/?");
        m = p.matcher(url.toExternalForm());
        if (m.matches()) {
            return "";
        }
        throw new MalformedURLException("Expected bato.to URL format: " +
                "bato.to/chapter/ID - got " + url + " instead");
    }

    @Override
    public boolean hasQueueSupport() {
        return true;
    }

    @Override
    public boolean pageContainsAlbums(URL url) {
        Pattern p = Pattern.compile("https?://bato.to/series/([\\d]+)/?");
        Matcher m = p.matcher(url.toExternalForm());
        return m.matches();
    }

    @Override
    public List<String> getAlbumsToQueue(Document doc) {
        List<String> urlsToAddToQueue = new ArrayList<>();
        for (Element elem : doc.select("div.main > div > a")) {
            urlsToAddToQueue.add("https://" + getDomain() + elem.attr("href"));
        }
        return urlsToAddToQueue;
    }

    @Override
    public String getAlbumTitle(URL url) throws MalformedURLException {
        try {
            // Attempt to use album title as GID
            return getHost() + "_" + getGID(url) + "_" + getFirstPage().select("title").first().text().replaceAll(" ", "_");
        } catch (IOException e) {
            // Fall back to default album naming convention
            LOGGER.info("Unable to find title at " + url);
        }
        return super.getAlbumTitle(url);
    }

    @Override
    public boolean canRip(URL url) {
        Pattern p = Pattern.compile("https?://bato.to/series/([\\d]+)/?");
        Matcher m = p.matcher(url.toExternalForm());
        if (m.matches()) {
            return true;
        }

        p = Pattern.compile("https?://bato.to/chapter/([\\d]+)/?");
        m = p.matcher(url.toExternalForm());
        return m.matches();
    }

    @Override
    public Document getFirstPage() throws IOException {
        // "url" is an instance field of the superclass
        return Http.url(url).get();
    }

    @Override
    public List<String> getURLsFromPage(Document doc) {<FILL_FUNCTION_BODY>}

    @Override
    public void downloadURL(URL url, int index) {
        addURLToDownload(url, getPrefix(index));
    }
}

        List<String> result = new ArrayList<>();
        for (Element script : doc.select("script")) {
            if (script.data().contains("var images = ")) {
                String s = script.data();
                s = s.replaceAll("var seriesId = \\d+;", "");
                s = s.replaceAll("var chapterId = \\d+;", "");
                s = s.replaceAll("var pages = \\d+;", "");
                s = s.replaceAll("var page = \\d+;", "");
                s = s.replaceAll("var prevCha = null;", "");
                s = s.replaceAll("var nextCha = \\.*;", "");
                String json = s.replaceAll("var images = ", "").replaceAll(";", "");
                JSONObject images = new JSONObject(json);
                for (int i = 1; i < images.length() +1; i++) {
                    result.add(images.getString(Integer.toString(i)));
                }

            }
        }
        return result;
    
<methods>public boolean addURLToDownload(java.net.URL, java.io.File, java.lang.String, Map<java.lang.String,java.lang.String>, java.lang.Boolean) ,public boolean addURLToDownload(java.net.URL, java.io.File) ,public boolean canRip(java.net.URL) ,public void downloadCompleted(java.net.URL, java.io.File) ,public void downloadErrored(java.net.URL, java.lang.String) ,public void downloadExists(java.net.URL, java.io.File) ,public int getCompletionPercentage() ,public int getCount() ,public abstract java.lang.String getHost() ,public Document getNextPage(Document) throws java.io.IOException,public java.lang.String getStatusText() ,public void rip() throws java.io.IOException,public java.net.URL sanitizeURL(java.net.URL) throws java.net.MalformedURLException,public boolean saveText(java.net.URL, java.lang.String, java.lang.String, int) ,public void setWorkingDir(java.net.URL) throws java.io.IOException<variables>private Map<java.net.URL,java.io.File> itemsCompleted,private Map<java.net.URL,java.lang.String> itemsErrored,private Map<java.net.URL,java.io.File> itemsPending