text: /**
     * Create By Dika Ardnt.
     * Contact Me on wa.me/6288292024190
     * Follow https://github.com/DikaArdnt
  */
  
  require('./config')
  const { default: nekellConnect, useSingleFileAuthState, DisconnectReason, generateForwardMessageContent, prepareWAMessageMedia, generateWAMessageFromContent, generateMessageID, downloadContentFromMessage, makeInMemoryStore, jidDecode, proto } = require("@adiwajshing/baileys")
  const { state, saveState } = useSingleFileAuthState(`./${sessionName}.json`)
  const pino = require('pino')
  const fs = require('fs')
  const chalk = require('chalk')
  const FileType = require('file-type')
  const path = require('path')
  const PhoneNumber = require('awesome-phonenumber')
  const { imageToWebp, videoToWebp, writeExifImg, writeExifVid } = require('./lib/exif')
  const { smsg, isUrl, generateMessageTag, getBuffer, getSizeMedia, fetchJson, await, sleep } = require('./lib/myfunc')
  
  global.api = (name, path = '/', query = {}, apikeyqueryname) => (name in global.APIs ? global.APIs[name] : name) + path + (query || apikeyqueryname ? '?' + new URLSearchParams(Object.entries({ ...query, ...(apikeyqueryname ? { [apikeyqueryname]: global.APIKeys[name in global.APIs ? global.APIs[name] : name] } : {}) })) : '')
  
  const store = makeInMemoryStore({ logger: pino().child({ level: 'silent', stream: 'store' }) })
  
  const getVersionWaweb = () => {
      let version
      try {
          let a = fetchJson('https://web.whatsapp.com/check-update?version=1&platform=web')
          version = [a.currentVersion.replace(/[.]/g, ', ')]
      } catch {
          version = [2, 2204, 13]
      }
      return version
  }
  
  async function startnekell() {
      const nekell = nekellConnect({
          logger: pino({ level: 'silent' }),
          printQRInTerminal: true,
          browser: ['Nekell Multi Device','Safari','1.0.0'],
          auth: state,
          version: getVersionWaweb() || [2, 2204, 13]
      })
  
      store.bind(nekell.ev)
  
      nekell.ws.on('CB:call', async (json) => {
      const callerId = json.content[0].attrs['call-creator']
      if (json.content[0].tag == 'offer') {
      let pa7rick = await nekell.sendContact(callerId, global.owner)
      nekell.sendMessage(callerId, { text: `Sistem otomatis block!\nJangan menelpon bot!\nSilahkan Hubungi Owner Untuk Dibuka !`}, { quoted : pa7rick })
      await sleep(8000)
      await nekell.updateBlockStatus(callerId, "block")
      }
      })
  
      nekell.ev.on('messages.upsert', async chatUpdate => {
          //console.log(JSON.stringify(chatUpdate, undefined, 2))
          try {
          mek = chatUpdate.messages[0]
          if (!mek.message) return
          mek.message = (Object.keys(mek.message)[0] === 'ephemeralMessage') ? mek.message.ephemeralMessage.message : mek.message
          if (mek.key && mek.key.remoteJid === 'status@broadcast') return
          if (!nekell.public && !mek.key.fromMe && chatUpdate.type === 'notify') return
          if (mek.key.id.startsWith('BAE5') && mek.key.id.length === 16) return
          m = smsg(nekell, mek, store)
          require("./nekell")(nekell, m, chatUpdate, store)
          } catch (err) {
              console.log(err)
          }
      })
  
      nekell.ev.on('group-participants.update', async (anu) => {
  console.log(anu)
  try {
  let metadata = await nekell.groupMetadata(anu.id)
  memeg = metadata.participants.length
  let participants = anu.participants
  let chat = global.db.data.chats[anu.id]
  for (let num of participants) {
  // Get Profile Picture User
  try {
  ppuser = await nekell.profilePictureUrl(num, 'image')
  } catch {
  ppuser = 'https://i0.wp.com/www.gambarunik.id/wp-content/uploads/2019/06/Top-Gambar-Foto-Profil-Kosong-Lucu-Tergokil-.jpg'
  }
  // Get Profile Picture Group
  try {
  ppgroup = await nekell.profilePictureUrl(anu.id, 'image')
  } catch {
  ppgroup = 'https://i0.wp.com/www.gambarunik.id/wp-content/uploads/2019/06/Top-Gambar-Foto-Profil-Kosong-Lucu-Tergokil-.jpg'
  }
  //Get bio
  try { bio = await nekell.fetchStatus(num)} catch { bio = { status: 'no bio' }}
  /*hmm = await getBuffer(ppuser)
  ff = await './tmp/ppuser-'+getRandom('.png')
  await fs.writeFileSync(ff, hmm)
  ppu = await TelegraPh(ff)
  await fs.unlinkSync(ff)
  hmm2 = await getBuffer(ppgroup)*/
  try {
  welcome = await getBuffer(`https://api.popcat.xyz/welcomecard?background=https://tinyurl.com/ybg6koy8&text1=${encodeURI(await nekell.getName(num))}&text2=Welcome+To+${encodeURI(metadata.subject)}&text3=Member+${encodeURI(metadata.participants.length)}&avatar=${ppu}`)
  } catch {
  welcome = await getBuffer(ppuser)
  }
  
  //let buffu = Buffer.isBuffer(ppuser) ? ppuser : /^data:.*?\/.*?;base64,/i.test(ppuser) ? Buffer.from(ppuser.split`,`[1], 'base64') : /^https?:\/\//.test(ppuser) ? await (await fetch(ppuser)).buffer() : fs.existsSync(ppuser) ? fs.readFileSync(ppuser) : Buffer.alloc(0)
  
  if (anu.action == 'add') {
  teks = `╭─❒  Selamat datang di *@subject*\n` 
  teks += `├ Semoga betah kak !\n`
  teks += `├ Nama: @user\n`
  teks += `├ Bio: @bio\n`
  teks += `├ Pada: @time\n`
  teks += `╰❒ Patuhi Rules Group Ya !`
  let capt = (chat.sWelcome.length > 5) ? chat.sWelcome : teks
  caption = capt.replace('@user', '@' + num.split('@')[0]).replace('@time', tanggal(new Date())).replace('@subject', metadata.subject).replace('@desc', metadata.desc).replace('@bio', bio.status)
  let buttons = [
  {buttonId: 'donasi', buttonText: {displayText: 'Welcome Sloerddddd🤡'}, type: 1},
  ]
  let go = await getBuffer(ppuser)
  let buttonMessage = {
  location: {
  degreesLatitude: 0,
  degreesLongtitude: 0,
  jpegThumbnail: go
  },
  caption: caption,
  footer: metadata.subject,
  buttons: buttons,
  headerType: 6,
  mentions: [...caption.matchAll(/@(\d{0,16})/g)].map(v => v[1] + '@s.whatsapp.net')
  }
  nekell.sendMessage(anu.id, buttonMessage)
  } else if (anu.action == 'remove') {
  try {
  leave = await getBuffer(`https://api.popcat.xyz/welcomecard?background=https://tinyurl.com/y99a3phd&text1=${encodeURI(await nekell.getName(num))}&text2=Leaving+From+${encodeURI(metadata.subject)}&text3=Member+${encodeURI(metadata.participants.length)}&avatar=${ppu}`)
  } catch {
  leave = await getBuffer(ppuser)
  }
  
  teks = `╭─❒  Selamat tinggal di *@subject*\n` 
  teks += `├ Semoga tenang dialam sana :)\n`
  teks += `├ Nama: @user\n`
  teks += `├ Bio: @bio\n`
  teks += `├ Pada: @time\n`
  teks += `╰❒ Jangan Lupa Balik Lagi !`
  let capt = (chat.sLeave.length > 5) ? chat.sLeave : teks
  caption = capt.replace('@user', '@' + num.split('@')[0]).replace('@time', tanggal(new Date())).replace('@subject', metadata.subject).replace('@desc', metadata.desc).replace('@bio', bio.status)
  let buttons = [
  {buttonId: 'donasi', buttonText: {displayText: 'Kena Mental👻'}, type: 1},
  ]
  let go = await getBuffer(ppuser)
  let buttonMessage = {
  location: {
  degreesLatitude: 0,
  degreesLongtitude: 0,
  jpegThumbnail: go
  },
  caption: caption,
  footer: metadata.subject,
  buttons: buttons,
  headerType: 6,
  mentions: [...caption.matchAll(/@(\d{0,16})/g)].map(v => v[1] + '@s.whatsapp.net')
  }
  nekell.sendMessage(anu.id, buttonMessage)
  } else if (anu.action == 'promote') {
  nekell.sendMessage(anu.id, { image: { url: ppuser }, contextInfo: { mentionedJid: [num] }, caption: `@${num.split("@")[0]} Promote From ${metadata.subject}` })
  } else if (anu.action == 'demote') {
  nekell.sendMessage(anu.id, { image: { url: ppuser }, contextInfo: { mentionedJid: [num] }, caption: `@${num.split("@")[0]} Demote From ${metadata.subject}` })
  }
  }
  } catch (err) {
  console.log(err)
  }
  })
  	
      // Setting
      nekell.decodeJid = (jid) => {
          if (!jid) return jid
          if (/:\d+@/gi.test(jid)) {
              let decode = jidDecode(jid) || {}
              return decode.user && decode.server && decode.user + '@' + decode.server || jid
          } else return jid
      }
      
      nekell.ev.on('contacts.update', update => {
          for (let contact of update) {
              let id = nekell.decodeJid(contact.id)
              if (store && store.contacts) store.contacts[id] = { id, name: contact.notify }
          }
      })
  
      nekell.getName = (jid, withoutContact  = false) => {
          id = nekell.decodeJid(jid)
          withoutContact = nekell.withoutContact || withoutContact 
          let v
          if (id.endsWith("@g.us")) return new Promise(async (resolve) => {
              v = store.contacts[id] || {}
              if (!(v.name || v.subject)) v = nekell.groupMetadata(id) || {}
              resolve(v.name || v.subject || PhoneNumber('+' + id.replace('@s.whatsapp.net', '')).getNumber('international'))
          })
          else v = id === '0@s.whatsapp.net' ? {
              id,
              name: 'WhatsApp'
          } : id === nekell.decodeJid(nekell.user.id) ?
              nekell.user :
              (store.contacts[id] || {})
              return (withoutContact ? '' : v.name) || v.subject || v.verifiedName || PhoneNumber('+' + jid.replace('@s.whatsapp.net', '')).getNumber('international')
      }
      
      nekell.sendContact = async (jid, kon, quoted = '', opts = {}) => {
  	let list = []
  	for (let i of kon) {
  	    list.push({
  	    	displayName: await nekell.getName(i + '@s.whatsapp.net'),
  	    	vcard: `BEGIN:VCARD\nVERSION:3.0\nN:${await nekell.getName(i + '@s.whatsapp.net')}\nFN:${await nekell.getName(i + '@s.whatsapp.net')}\nitem1.TEL;waid=${i}:${i}\nitem1.X-ABLabel:Ponsel\nitem2.EMAIL;type=INTERNET:nekellganss@gmail.com\nitem2.X-ABLabel:Email\nitem3.URL:https://instagram.com/bernekellboy_\nitem3.X-ABLabel:Instagram\nitem4.ADR:;;Indonesia;;;;\nitem4.X-ABLabel:Region\nEND:VCARD`
  	    })
  	}
  	nekell.sendMessage(jid, { contacts: { displayName: `${list.length} Kontak`, contacts: list }, ...opts }, { quoted })
      }
  	
      nekell.public = true
  
      nekell.serializeM = (m) => smsg(nekell, m, store)
  
      nekell.ev.on('connection.update', async (update) => {
          const { connection, lastDisconnect } = update
          if (connection === 'close') {
              lastDisconnect.error?.output?.statusCode !== DisconnectReason.loggedOut ? startnekell() : console.log('Koneksi Terputus...')
          }
          console.log('Koneksi Terhubung...', update)
      })
  
      nekell.ev.on('creds.update', saveState)
  
      // Add Other
      /** Send Button 5 Image
       *
       * @param {*} jid
       * @param {*} text
       * @param {*} footer
       * @param {*} image
       * @param [*] button
       * @param {*} options
       * @returns
       */
      nekell.send5ButImg = async (jid , text = '' , footer = '', img, but = [], options = {}) =>{
          let message = await prepareWAMessageMedia({ image: img }, { upload: nekell.waUploadToServer })
          var template = generateWAMessageFromContent(m.chat, proto.Message.fromObject({
          templateMessage: {
          hydratedTemplate: {
          imageMessage: message.imageMessage,
                 "hydratedContentText": text,
                 "hydratedFooterText": footer,
                 "hydratedButtons": but
              }
              }
              }), options)
              nekell.relayMessage(jid, template.message, { messageId: template.key.id })
      }
  
      /**
       * 
       * @param {*} jid 
       * @param {*} buttons 
       * @param {*} caption 
       * @param {*} footer 
       * @param {*} quoted 
       * @param {*} options 
       */
      nekell.sendButtonText = (jid, buttons = [], text, footer, quoted = '', options = {}) => {
          let buttonMessage = {
              text,
              footer,
              buttons,
              headerType: 2,
              ...options
          }
          nekell.sendMessage(jid, buttonMessage, { quoted, ...options })
      }
      
      /**
       * 
       * @param {*} jid 
       * @param {*} text 
       * @param {*} quoted 
       * @param {*} options 
       * @returns 
       */
      nekell.sendText = (jid, text, quoted = '', options) => nekell.sendMessage(jid, { text: text, ...options }, { quoted })
  
      /**
       * 
       * @param {*} jid 
       * @param {*} path 
       * @param {*} caption 
       * @param {*} quoted 
       * @param {*} options 
       * @returns 
       */
      nekell.sendImage = async (jid, path, caption = '', quoted = '', options) => {
  	let buffer = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0)
          return await nekell.sendMessage(jid, { image: buffer, caption: caption, ...options }, { quoted })
      }
  
      /**
       * 
       * @param {*} jid 
       * @param {*} path 
       * @param {*} caption 
       * @param {*} quoted 
       * @param {*} options 
       * @returns 
       */
      nekell.sendVideo = async (jid, path, caption = '', quoted = '', gif = false, options) => {
          let buffer = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0)
          return await nekell.sendMessage(jid, { video: buffer, caption: caption, gifPlayback: gif, ...options }, { quoted })
      }
  
      /**
       * 
       * @param {*} jid 
       * @param {*} path 
       * @param {*} quoted 
       * @param {*} mime 
       * @param {*} options 
       * @returns 
       */
      nekell.sendAudio = async (jid, path, quoted = '', ptt = false, options) => {
          let buffer = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0)
          return await nekell.sendMessage(jid, { audio: buffer, ptt: ptt, ...options }, { quoted })
      }
  
      /**
       * 
       * @param {*} jid 
       * @param {*} text 
       * @param {*} quoted 
       * @param {*} options 
       * @returns 
       */
      nekell.sendTextWithMentions = async (jid, text, quoted, options = {}) => nekell.sendMessage(jid, { text: text, contextInfo: { mentionedJid: [...text.matchAll(/@(\d{0,16})/g)].map(v => v[1] + '@s.whatsapp.net') }, ...options }, { quoted })
  
      /**
       * 
       * @param {*} jid 
       * @param {*} path 
       * @param {*} quoted 
       * @param {*} options 
       * @returns 
       */
      nekell.sendImageAsSticker = async (jid, path, quoted, options = {}) => {
          let buff = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0)
          let buffer
          if (options && (options.packname || options.author)) {
              buffer = await writeExifImg(buff, options)
          } else {
              buffer = await imageToWebp(buff)
          }
  
          await nekell.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted })
          return buffer
      }
  
      /**
       * 
       * @param {*} jid 
       * @param {*} path 
       * @param {*} quoted 
       * @param {*} options 
       * @returns 
       */
      nekell.sendVideoAsSticker = async (jid, path, quoted, options = {}) => {
          let buff = Buffer.isBuffer(path) ? path : /^data:.*?\/.*?;base64,/i.test(path) ? Buffer.from(path.split`,`[1], 'base64') : /^https?:\/\//.test(path) ? await (await getBuffer(path)) : fs.existsSync(path) ? fs.readFileSync(path) : Buffer.alloc(0)
          let buffer
          if (options && (options.packname || options.author)) {
              buffer = await writeExifVid(buff, options)
          } else {
              buffer = await videoToWebp(buff)
          }
  
          await nekell.sendMessage(jid, { sticker: { url: buffer }, ...options }, { quoted })
          return buffer
      }
  	
      /**
       * 
       * @param {*} message 
       * @param {*} filename 
       * @param {*} attachExtension 
       * @returns 
       */
      nekell.downloadAndSaveMediaMessage = async (message, filename, attachExtension = true) => {
          let quoted = message.msg ? message.msg : message
          let mime = (message.msg || message).mimetype || ''
          let messageType = message.mtype ? message.mtype.replace(/Message/gi, '') : mime.split('/')[0]
          const stream = await downloadContentFromMessage(quoted, messageType)
          let buffer = Buffer.from([])
          for await(const chunk of stream) {
              buffer = Buffer.concat([buffer, chunk])
          }
  	let type = await FileType.fromBuffer(buffer)
          trueFileName = attachExtension ? (filename + '.' + type.ext) : filename
          // save to file
          await fs.writeFileSync(trueFileName, buffer)
          return trueFileName
      }
  
      nekell.downloadMediaMessage = async (message) => {
          let mime = (message.msg || message).mimetype || ''
          let messageType = message.mtype ? message.mtype.replace(/Message/gi, '') : mime.split('/')[0]
          const stream = await downloadContentFromMessage(message, messageType)
          let buffer = Buffer.from([])
          for await(const chunk of stream) {
              buffer = Buffer.concat([buffer, chunk])
  	}
          
  	return buffer
       } 
      
      /**
       * 
       * @param {*} jid 
       * @param {*} path 
       * @param {*} filename
       * @param {*} caption
       * @param {*} quoted 
       * @param {*} options 
       * @returns 
       */
      nekell.sendMedia = async (jid, path, fileName = '', caption = '', quoted = '', options = {}) => {
          let types = await nekell.getFile(path, true)
             let { mime, ext, res, data, filename } = types
             if (res && res.status !== 200 || file.length <= 65536) {
                 try { throw { json: JSON.parse(file.toString()) } }
                 catch (e) { if (e.json) throw e.json }
             }
         let type = '', mimetype = mime, pathFile = filename
         if (options.asDocument) type = 'document'
         if (options.asSticker || /webp/.test(mime)) {
          let { writeExif } = require('./lib/exif')
          let media = { mimetype: mime, data }
          pathFile = await writeExif(media, { packname: options.packname ? options.packname : global.packname, author: options.author ? options.author : global.author, categories: options.categories ? options.categories : [] })
          await fs.promises.unlink(filename)
          type = 'sticker'
          mimetype = 'image/webp'
          }
         else if (/image/.test(mime)) type = 'image'
         else if (/video/.test(mime)) type = 'video'
         else if (/audio/.test(mime)) type = 'audio'
         else type = 'document'
         await nekell.sendMessage(jid, { [type]: { url: pathFile }, caption, mimetype, fileName, ...options }, { quoted, ...options })
         return fs.promises.unlink(pathFile)
         }
  
      /**
       * 
       * @param {*} jid 
       * @param {*} message 
       * @param {*} forceForward 
       * @param {*} options 
       * @returns 
       */
      nekell.copyNForward = async (jid, message, forceForward = false, options = {}) => {
          let vtype
  		if (options.readViewOnce) {
  			message.message = message.message && message.message.ephemeralMessage && message.message.ephemeralMessage.message ? message.message.ephemeralMessage.message : (message.message || undefined)
  			vtype = Object.keys(message.message.viewOnceMessage.message)[0]
  			delete(message.message && message.message.ignore ? message.message.ignore : (message.message || undefined))
  			delete message.message.viewOnceMessage.message[vtype].viewOnce
  			message.message = {
  				...message.message.viewOnceMessage.message
  			}
  		}
  
          let mtype = Object.keys(message.message)[0]
          let content = await generateForwardMessageContent(message, forceForward)
          let ctype = Object.keys(content)[0]
  		let context = {}
          if (mtype != "conversation") context = message.message[mtype].contextInfo
          content[ctype].contextInfo = {
              ...context,
              ...content[ctype].contextInfo
          }
          const waMessage = await generateWAMessageFromContent(jid, content, options ? {
              ...content[ctype],
              ...options,
              ...(options.contextInfo ? {
                  contextInfo: {
                      ...content[ctype].contextInfo,
                      ...options.contextInfo
                  }
              } : {})
          } : {})
          await nekell.relayMessage(jid, waMessage.message, { messageId:  waMessage.key.id })
          return waMessage
      }
  
      nekell.cMod = (jid, copy, text = '', sender = nekell.user.id, options = {}) => {
          //let copy = message.toJSON()
  		let mtype = Object.keys(copy.message)[0]
  		let isEphemeral = mtype === 'ephemeralMessage'
          if (isEphemeral) {
              mtype = Object.keys(copy.message.ephemeralMessage.message)[0]
          }
          let msg = isEphemeral ? copy.message.ephemeralMessage.message : copy.message
  		let content = msg[mtype]
          if (typeof content === 'string') msg[mtype] = text || content
  		else if (content.caption) content.caption = text || content.caption
  		else if (content.text) content.text = text || content.text
  		if (typeof content !== 'string') msg[mtype] = {
  			...content,
  			...options
          }
          if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant
  		else if (copy.key.participant) sender = copy.key.participant = sender || copy.key.participant
  		if (copy.key.remoteJid.includes('@s.whatsapp.net')) sender = sender || copy.key.remoteJid
  		else if (copy.key.remoteJid.includes('@broadcast')) sender = sender || copy.key.remoteJid
  		copy.key.remoteJid = jid
  		copy.key.fromMe = sender === nekell.user.id
  
          return proto.WebMessageInfo.fromObject(copy)
      }
  
  
      /**
       * 
       * @param {*} path 
       * @returns 
       */
      nekell.getFile = async (PATH, save) => {
          let res
          let data = Buffer.isBuffer(PATH) ? PATH : /^data:.*?\/.*?;base64,/i.test(PATH) ? Buffer.from(PATH.split`,`[1], 'base64') : /^https?:\/\//.test(PATH) ? await (res = await getBuffer(PATH)) : fs.existsSync(PATH) ? (filename = PATH, fs.readFileSync(PATH)) : typeof PATH === 'string' ? PATH : Buffer.alloc(0)
          //if (!Buffer.isBuffer(data)) throw new TypeError('Result is not a buffer')
          let type = await FileType.fromBuffer(data) || {
              mime: 'application/octet-stream',
              ext: '.bin'
          }
          filename = path.join(__filename, '../src/' + new Date * 1 + '.' + type.ext)
          if (data && save) fs.promises.writeFile(filename, data)
          return {
              res,
              filename,
  	    size: await getSizeMedia(data),
              ...type,
              data
          }
  
      }
  
      return nekell
  }
  
  startnekell()
  
  
  let file = require.resolve(__filename)
  fs.watchFile(file, () => {
  	fs.unwatchFile(file)
  	console.log(chalk.redBright(`Update ${__filename}`))
  	delete require.cache[file]
  	require(file)
  })
  