{"version":3,"sources":["jsdelivr-header.js","/npm/ai-lyrics@1.1.1/index.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,ACQA,MAAM,UAAY,QAAQ,cACpB,WAAE,YAAe,QAAQ,gBAKzB,SAAW,CACb,WAAY,IAOZ,sBAAuB,eAAe,GAClC,OAAO,KAAK,KAAK,EACrB,EAQA,+BAAgC,eAAe,EAAO,GAClD,OAAO,KAAK,KAAK,GAAG,KAAS,IACjC,EAOA,KAAM,eAAe,GACjB,MAAM,QAAgB,UAAU,OAAO,CAAE,SAAU,QAC7C,QAAa,EAAQ,UAErB,EAAQ,mCAAmC,mBAAmB,GAAG,oBACjE,EAAK,KAAK,GAEhB,MAAM,QAAsB,EAAK,EAAE,wBACnC,GAAI,EAAe,CACf,MAAM,QAAe,EAAc,UAAS,GAAW,EAAQ,YAM/D,aALM,EAAQ,QACH,WAAW,EAAQ,CAC1B,SAAU,MAEF,QAAQ,KAAM,GAE9B,CAEA,MAAM,QAAc,KAAK,MAAM,GAE/B,IAAK,MAAM,KAAQ,EACf,UACU,EAAK,KAAK,GAChB,MAAM,QAAsB,EAAK,UAAS,KACtC,MAAM,EAAc,MAAM,KAAK,SAAS,iBAAiB,qBACzD,IAAI,EAAgB,KAChB,EAAa,EACjB,IAAK,MAAM,KAAc,EAAa,CAClC,MAAM,EAAU,EAAW,iBAAiB,MAAM,OAC9C,GAAW,GAAc,EAAW,YAAY,OAAS,MACzD,EAAa,EACb,EAAgB,EAAW,UAEnC,CACA,IAAI,EAAO,WAAW,EAAe,CACjC,SAAU,MAGd,OADA,EAAO,EAAK,QAAQ,KAAM,GACf,IAEf,GAAI,EAMA,aALM,EAAQ,QACH,WAAW,EAAe,CACjC,SAAU,MAEF,QAAQ,KAAM,GAGlC,CAAE,MAAO,GACL,QAAQ,MAAM,EAClB,CAIJ,aADM,EAAQ,QACP,EACX,EAOA,MAAO,eAAe,GAClB,MAAM,QAAgB,UAAU,OAAO,CAAE,SAAU,QAC7C,QAAa,EAAQ,UAGrB,EAAQ,mCADM,mBAAmB,GAAG,2BAEpC,EAAK,KAAK,GAEhB,MAAM,QAAoB,EAAK,UAAS,IACtB,MAAM,KAAK,SAAS,iBAAiB,iBACtC,KAAI,GAAQ,EAAK,SAIlC,aADM,EAAQ,QACP,KAAK,iBAAiB,EACjC,EAOA,iBAAkB,SAAS,GACvB,MAAO,IAAI,IAAI,IAAI,GACvB,GAGJ,OAAO,QAAU","file":"/npm/ai-lyrics@1.1.1/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/ai-lyrics@1.1.1/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\r\n * ai-lyrics\r\n * A JavaScript library to fetch song lyrics from the web.\r\n * \r\n * Credits:\r\n * Author: KHAOUITI ABDELHAKIM\r\n * Repository: https://github.com/khaouitiabdelhakim/AILyrics-JS\r\n * \r\n * Copyright:\r\n * Copyright (c) [Year], KHAOUITI ABDELHAKIM\r\n * \r\n * Last Date: 13 March 2024\r\n */\r\n\r\nconst puppeteer = require('puppeteer');\r\nconst { htmlToText } = require('html-to-text');\r\n\r\n/**\r\n * LyricsAI - Object containing methods to fetch song lyrics.\r\n */\r\nconst LyricsAI = {\r\n    MIN_LENGTH: 200,\r\n\r\n    /**\r\n     * findLyricsBySongTitle - Fetches lyrics by song title.\r\n     * @param {string} title - The title of the song.\r\n     * @returns {Promise<string>} - The lyrics of the song.\r\n     */\r\n    findLyricsBySongTitle: async function(title) {\r\n        return this.find(title);\r\n    },\r\n\r\n    /**\r\n     * findLyricsBySongTitleAndArtist - Fetches lyrics by song title and artist.\r\n     * @param {string} title - The title of the song.\r\n     * @param {string} artist - The artist of the song.\r\n     * @returns {Promise<string>} - The lyrics of the song.\r\n     */\r\n    findLyricsBySongTitleAndArtist: async function(title, artist) {\r\n        return this.find(`${title} ${artist}`);\r\n    },\r\n\r\n    /**\r\n     * find - Finds lyrics based on the provided information.\r\n     * @param {string} info - The information to search for.\r\n     * @returns {Promise<string>} - The lyrics found.\r\n     */\r\n    find: async function(info) {\r\n        const browser = await puppeteer.launch({ headless: \"new\" }); // Specify Headless mode as \"new\"\r\n        const page = await browser.newPage();\r\n\r\n        const myUrl = `https://www.google.com/search?q=${encodeURIComponent(`${info} lyrics`)}`;\r\n        await page.goto(myUrl);\r\n\r\n        const lyricsElement = await page.$('div[jsname=\"WbKHeb\"]');\r\n        if (lyricsElement) {\r\n            const lyrics = await lyricsElement.evaluate(element => element.innerHTML); // Return HTML content instead of text content\r\n            await browser.close();\r\n            var text = htmlToText(lyrics, {\r\n                wordwrap: 130\r\n            });\r\n            text = text.replace(/\"/g, ''); // Replace all occurrences of double quotes with an empty string\r\n            return text;\r\n        }\r\n\r\n        const links = await this.links(info);\r\n\r\n        for (const link of links) {\r\n            try {\r\n                await page.goto(link);\r\n                const divWithMostBr = await page.evaluate(() => {\r\n                    const divElements = Array.from(document.querySelectorAll('*:not(:has(div))'));\r\n                    let divWithMostBr = null;\r\n                    let maxBrCount = 0;\r\n                    for (const divElement of divElements) {\r\n                        const brCount = divElement.querySelectorAll('br').length;\r\n                        if (brCount >= maxBrCount && divElement.textContent.length > 600) {\r\n                            maxBrCount = brCount;\r\n                            divWithMostBr = divElement.innerHTML;\r\n                        }\r\n                    }\r\n                    var text = htmlToText(divWithMostBr, {\r\n                        wordwrap: 130\r\n                    });\r\n                    text = text.replace(/\"/g, ''); // Replace all occurrences of double quotes with an empty string\r\n                    return text;\r\n                });\r\n                if (divWithMostBr) {\r\n                    await browser.close();\r\n                    var text = htmlToText(divWithMostBr, {\r\n                        wordwrap: 130\r\n                    });\r\n                    text = text.replace(/\"/g, ''); // Replace all occurrences of double quotes with an empty string\r\n                    return text;\r\n                }\r\n            } catch (error) {\r\n                console.error(error);\r\n            }\r\n        }\r\n\r\n        await browser.close();\r\n        return '';\r\n    },\r\n\r\n    /**\r\n     * links - Retrieves links related to the search information.\r\n     * @param {string} info - The information to search for.\r\n     * @returns {Promise<string[]>} - Array of links.\r\n     */\r\n    links: async function(info) {\r\n        const browser = await puppeteer.launch({ headless: \"new\" });\r\n        const page = await browser.newPage();\r\n\r\n        const encodedInfo = encodeURIComponent(`${info} lyrics`);\r\n        const myUrl = `https://www.google.com/search?q=${encodedInfo}&num=15`;\r\n        await page.goto(myUrl);\r\n\r\n        const linksToSong = await page.evaluate(() => {\r\n            const links = Array.from(document.querySelectorAll('div.yuRUbf a'));\r\n            return links.map(link => link.href);\r\n        });\r\n\r\n        await browser.close();\r\n        return this.removeDuplicates(linksToSong);\r\n    },\r\n\r\n    /**\r\n     * removeDuplicates - Removes duplicate links from the list.\r\n     * @param {string[]} list - Array of links.\r\n     * @returns {string[]} - Array of unique links.\r\n     */\r\n    removeDuplicates: function(list) {\r\n        return [...new Set(list)];\r\n    },\r\n};\r\n\r\nmodule.exports = LyricsAI;\r\n"]}