class HitomiRipper extends AbstractHTMLRipper {

    private String galleryId = "";

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

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

    @Override
    public String getDomain() {
        return "hitomi.la";
    }

    @Override
    public String getGID(URL url) throws MalformedURLException {
        Pattern p = Pattern.compile("https://hitomi.la/galleries/([\\d]+).html");
        Matcher m = p.matcher(url.toExternalForm());
        if (m.matches()) {
            galleryId = m.group(1);
            return m.group(1);
        }
        throw new MalformedURLException("Expected hitomi URL format: " +
                "https://hitomi.la/galleries/ID.html - got " + url + " instead");
    }

    @Override
    public Document getFirstPage() throws IOException {
        // if we go to /GALLERYID.js we get a nice json array of all images in the gallery
        return Http.url(new URL(url.toExternalForm().replaceAll("hitomi", "ltn.hitomi").replaceAll(".html", ".js"))).ignoreContentType().get();
    }


    @Override
    public List<String> getURLsFromPage(Document doc) {
        List<String> result = new ArrayList<>();
        String json = doc.text().replaceAll("var galleryinfo =", "");
        JSONArray json_data = new JSONArray(json);
        for (int i = 0; i < json_data.length(); i++) {
            result.add("https://ba.hitomi.la/galleries/" + galleryId + "/" + json_data.getJSONObject(i).getString("name"));
        }

        return result;
    }

    @Override
    public String getAlbumTitle(URL url) throws MalformedURLException {<FILL_FUNCTION_BODY>}

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

        try {
            // Attempt to use album title and username as GID
            Document doc = Http.url(url).get();
            return getHost() + "_" + getGID(url) + "_" +
                    doc.select("title").text().replaceAll(" - Read Online - hentai artistcg \\| Hitomi.la", "");
        } catch (IOException e) {
            LOGGER.info("Falling back");
        }
        return super.getAlbumTitle(url);
    
<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