var apx = apx || {};
apx.apxauth = {};
apx.apxauth.loadwco = async (id, ctx) => {
  // check if not authenticate, do nothing cause by default screensignin and wait authentification
  //       if     authenticate, if url xhash then redirect if no url then change wco-link=screenmyworld
  // if (dayjs(apx.data.headers.xdays).diff(dayjs(), "hours") >= 24) apx.apxauth.checkisauth();
  //load main.mustache of the component
  //when wco-xxx change it run this function
  console.log(
    `Load wconame:apxauth apx.apxauth.loadwco with id:${id} and ctx: ${JSON.stringify(
      ctx
    )}`
  );
  // Check that in localdb tpl exist if not means it is not authenticated 
  if (!apx.data.tpl[`apxauthscreen${ctx.link}`]) ctx.link="signin";
  const tpldataname = `${apx.data.pagename}_${id}_apxauth`;
  const apxauthid = document.getElementById(id);
  const data = apx.apxauth.getdata(id, ctx);
  if (apxauthid.innerHTML.trim() === "") {
    apxauthid.innerHTML = Mustache.render(apx.data.tpl.apxauthmain, data);
  }
  apxauthid.querySelector(`.screenaction`).innerHTML = Mustache.render(
    apx.data.tpl[`apxauthscreen${ctx.link}`],
    data
  );
  apxauthid.querySelector(`.msginfo`).innerHTML = "";
};

apx.apxauth.getdata = (id, ctx) => {
  const tpldataname = `${apx.data.pagename}_${id}_apxauth`;
  const data = JSON.parse(JSON.stringify(apx.data.tpldata[tpldataname]));
  data.id = id;
  data.xalias = apx.data.headers.xalias;
  data.xtribe = apx.data.headers.xtribe;

  data.emailssuport = apx.data?.appdata?.emailsupport
    ? apx.data.appdata.emailsupport
    : "";
  switch (ctx.link) {
    case "myworld":
      if (!data.profils) data.profils = [];
      apx.data.headers.xprofils.forEach((p) => {
        if (!["anonymous", "pagans", "persons"].includes(p)) {
          data.profils.push(apx.data.options.profil.itms[p].title);
        }
      });
      data.noprofils = data.profils.length == 0;
      data.member = apx.data.headers.xprofils.includes("persons");
      data.websites = apx.data?.appdata?.websites || [];
      data.optionlinks=apx.data.tpldata[tpldataname].optionlinks
      data.town=apx.data.town
      data.nation=apx.data.nation
      if (1==1 || apx.data.headers.xprofils.includes('major')){
         apx.data.tpldata[tpldataname].optionlinksmajor.forEach(o=>data.optionlinks.push(o))
         apx.save()
      }
      if (!apx.data.itms) apx.data.itms={}
      if (!apx.data.wco) apx.data.wco={} 

      // get towns list
      axios
        .get(`/api/apxtri/odmdb/idx/apxtri/towns/towns`, {
          headers: apx.data.headers, withCredentials:true
        })
        .then((rep) => {
          console.log(rep)
          if (rep.status==200){
            apx.data.itms.towns=rep.data.data.idx
            data.townsnumber= Object.keys(apx.data.itms.towns).length;
            apx.data.wco.townsnumber={textContent:Object.keys(apx.data.itms.towns).length};
            apx.listendatawco('townsnumber');
            apx.save()
          }
        })
        .catch((err) => {
          console.log("ERROR, geting towns itms not available",err)
        });
      axios
        .get(`/api/apxtri/odmdb/idx/apxtri/pagans/lst_alias`, {
          headers: apx.data.headers, withCredentials:true
        })
        .then((rep) => {
          if (rep.status==200){
            console.log(rep)
            data.pagansnumber=rep.data.data.idx.length
            apx.data.wco.pagansnumber={textContent:rep.data.data.idx.length};
            apx.listendatawco('pagansnumber');
            apx.save();
          }
        })
        .catch((err) => {
          console.log("ERROR, geting pagans itms not available",err)
        });
      break;
    default:
      break;
  }
  console.log("data for tpl:", data);
  return data;
};

apx.apxauth.redirecturlwithauth = (
  url,
  tribe,
  webapp,
  newwindow,
  windowname = "_blank"
) => {
  url = url.replace(/_[a-zA-Z0-9]{2}\.html/, `_${apx.data.headers.xlang}.html`);
  url += `?xtribe=${tribe}&xapp=${webapp}&xalias=${apx.data.headers.xalias}`;
  url += `&xdays=${apx.data.headers.xdays}&xhash=${apx.data.headers.xhash}`;
  url += `&xprofils=${apx.data.headers.xprofils.join(",")}`;
  url += `&xtrkversion=${apx.data.headers.xtrkversion}&xuuid=${apx.data.headers.xuuid}`;
  if (newwindow) {
    try {
      const newwin = window.open(url, windowname);
      if (newwin === null || typeof newwin === "undefined") {
        console.warn(
          "L'ouverture de la fenêtre a été bloquée par un bloqueur de pop-up."
        );
        // Vous pouvez informer l'utilisateur ici qu'il doit désactiver son bloqueur de pop-up
        alert(
          "Votre navigateur a bloqué l'ouverture d'un nouvel onglet. Veuillez autoriser les pop-ups pour ce site."
        );
      } else {
        // Optionnel: Mettre le focus sur la nouvelle fenêtre/onglet
        newwin.focus();
      }
      return newwin;
    } catch (error) {
      console.error(
        "Une erreur est survenue lors de l'ouverture de l'onglet :",
        error
      );
      return null;
    }
  }
};

/**
 * logout
 * Clean any private key into memory of this app and in the backend
 */
apx.apxauth.logout = () => {
  axios
    .get(`/api/apxtri/pagans/logout`, {
      headers: apx.data.headers, withCredentials:true
    })
    .then((rep) => {
      console.log("logout", rep);
    })
    .catch((err) => {
      console.log("Erreur logout check:", err);
    });
  apx.data = apxtri;
  apx.save();
  if (apx.pagecontext.hash.url) {
    window.location.href = apx.pagecontext.hash.url;
  } else {
    location.reload();
  }
};

apx.apxauth.setheadersauth = async (
  alias,
  passphrase,
  publickey,
  privatekey,
  rememberme
) => {
  /**
   * Set header with relevant authentification data
   * @return {status=200 if apx.data.headers and apx.data.auth properly set}
   *         {status: 406 or 500 in case issue}
   */
  //console.log(alias, passphrase, publickey, privatekey);
  if (
    alias.length < 3 ||
    publickey.length < 200 ||
    (privatekey && privatekey.lengtht < 200)
  ) {
    return {
      status: 406,
      ref: "Pagans",
      msg: "aliasorprivkeytooshort",
      data: {},
    };
  }
  if (!passphrase) passphrase = "";
  if (rememberme) {
    apx.data.auth = {
      alias: alias,
      publickey: publickey,
      privatekey: privatekey,
      passphrase: passphrase,
    };
  } else if (apx.data.auth) {
    delete apx.data.auth;
    apx.save();
  }
  apx.data.headers.xalias = alias;
  apx.data.headers.xdays = dayjs().valueOf();
  const msg = `${alias}_${apx.data.headers.xdays}`;
 
  try {
    apx.data.headers.xhash = await apx.apxauth.clearmsgSignature(
      publickey,
      privatekey,
      passphrase,
      msg
    );
  } catch (err) {
    return {
      status: 500,
      ref: "Middlewares",
      msg: "unconsistentpgp",
      data: { err: err },
    };
  }
  apx.save();
  console.log("xhash set with:", apx.data.headers.xhash);
  return { status: 200 };
};
apx.apxauth.authentifyme = async (
  id,
  alias,
  passphrase,
  privatekey,
  rememberme
) => {
  /**
   * Set apx.data.auth with pub, priv, passphrase alias that allow authentification
   * set headers with xdays (timestamp) and xhash of message: {alias}_{timestamp} generate with pub & priv key
   *
   * @Param {key} publickeycreate  optional when alias does not exist
   */
  //console.log(alias, passphrase);
  //console.log(privatekey);
  //clean previous answer if exist

  const idparent = document
    .getElementById(id)
    .parentElement?.closest("[wco-name]")
    .getAttribute("id");
  document.querySelector(`#${id} .msginfo`).innerHTML = "";
  if (alias.length < 3 || privatekey.length < 200) {
    apx.notification(`#${id} .msginfo`, {
      status: 500,
      ref: "Pagans",
      msg: "aliasorprivkeytooshort",
      data: {},
    });
    return false;
  }
  console.log(`get /api/apxtri/pagans/alias/${alias}`);
  axios
    .get(`/api/apxtri/pagans/alias/${alias}`, {
      headers: apx.data.headers, withCredentials:true
    })
    .then(async (rep) => {
      //console.log(rep.data);
      const setheaders = await apx.apxauth.setheadersauth(
        alias,
        passphrase,
        rep.data.data.publickey,
        privatekey,
        rememberme
      );
      if (setheaders.status != 200) {
        apx.notification(`#${id} .msginfo`, setheaders);
      } else {
        console.log("SetheadersOK");
        console.log(`/api/apxtri/pagans/isauth`);
        axios
          .get(`/api/apxtri/pagans/isauth`, {
            headers: apx.data.headers,
            withCredentials: true,
          })
          .then((rep) => {
            // Authenticate then store profils in header
            // remove xhash for security this xhaskl is stored from the server as cookie http only.
            apx.data.headers.xprofils = rep.data.data.xprofils;
            delete apx.data.headers.xhash;
            apx.save();
            // if this page is call with apxid_fr.html?url=httpsxxx then it redirect to this page.
            //alert(`${window.location.href.includes("/src/")?"/src/":""}${apx.pagecontext.hash.url}`)
            if (apx.pagecontext.hash.url) {
              window.location.href = `${apx.pagecontext.hash.url}`;
            } else {
              //location.reload();
              document
                .getElementById(idparent)
                .setAttribute("wco-link", "myworld");
            }
          })
          .catch((err) => {
            console.log("Not authentify:", err);
            delete apx.data.auth;
            apx.save();
            document
              .getElementById(idparent)
              .setAttribute("wco-link", "signin");
            if (err.response) {
              apx.notification(`#${id} .msginfo`, err.response.data);
            } else if (err.request) {
              apx.notification(`#${id} .msginfo`, {
                status: 500,
                ref: "Middlewares",
                msg: "errrequest",
                data: { err: err.request.response },
              });
            }
          });
      }
    })
    .catch((err) => {
      //console.log(err.response);
      //console.log(err.request);
      console.log("checkalias:", err);
      if (err.response && err.response.data.msg) {
        //remove auth if not well created previously
        //console.log(err.response.data.msg);
        if (err.response.data.msg == "aliasdoesnotexist") {
          delete apx.data.auth;
          apx.save();
          apx.notification(`#${id} .msginfo`, {
            status: 404,
            ref: "Pagans",
            msg: "aliasdoesnotexist",
            data: { alias },
          });
          //document.getElementById("inputaliasauth").value="";
          //document.getElementById("inputpassphraseauth").value="";
          //document.getElementById("privatekeyauth").value=""
          //window.location.reload();
        }
        apx.notification(`#${id} .msginfo`, err.response.data);
      } else {
        apx.notification(`#${id} .msginfo`, {
          status: 500,
          ref: "Middlewares",
          msg: "errrequest",
          data: { err },
        });
      }
    });
};
apx.apxauth.recoverykey = (id, aliasoremail) => {
  if (aliasoremail.length < 3) {
    apx.notification(`#${id} .msginfo`, {
      status: 406,
      ref: "Pagans",
      msg: "recoveryemailnotfound",
      data: { tribe: apx.data.headers.xtribe, search: aliasoremail },
    });
    return false;
  }
  const recodata = { tribe: apx.data.headers.xtribe, search: aliasoremail };
  const validator= new Checkjson({properties:{email:{type:"string",format:"email"}}});
  recodata.emailalias = validator.verify({email:aliasoremail})
    ? "email"
    : "alias";
  document.querySelector(`#${id} .msginfo`).innerHTML = "";
  axios
    .post(`/api/apxtri/pagans/keyrecovery`, recodata, {
      headers: apx.data.headers
    })
    .then((rep) => {
      rep.data.data.search = aliasoremail;
      apx.notification(`#${id} .msginfo`, rep.data, true);
    })
    .catch((err) => {
      //console.log("error:", err);
      const dataerr =
        err.response && err.response.data
          ? err.response.data
          : { status: 500, ref: "Pagans", msg: "checkconsole", data: {} };
      dataerr.data.search = aliasoremail;
      apx.notification(`#${id} .msginfo`, dataerr, true);
    });
};
apx.apxauth.generateKey = async (alias, passphrase) => {
  /**
   * @param {string} alias a unique alias that identify an identity
   * @param {string} passphrase a string to cipher the publickey (can be empty, less secure but simpler)
   * @return {publickey,privatekey} with userIds = [{alias}]
   */
  const pgpparam = {
    type: "ecc", // Type of the key, defaults to ECC
    curve: "curve25519", // ECC curve name, defaults to curve25519
    userIDs: [{ alias: alias }], // you can pass multiple user IDs
    passphrase: passphrase, // protects the private key
    format: "armored", // output key format, defaults to 'armored' (options: 'armored', 'binary' or 'object')
  };
  const { privateKey, publicKey } = await openpgp.generateKey(pgpparam);
  // key start by '-----BEGIN PGP PRIVATE KEY BLOCK ... '
  // get liste  of alias:pubklickey await axios.get('api/v0/pagans')
  // check alias does not exist
  return { alias, privatekey: privateKey, publickey: publicKey };
};

apx.apxauth.verifyKeys = async (
  publicKeyArmored,
  privateKeyArmored,
  passphrase
) => {
  try {
    // Charger la clé publique
    const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });

    // Charger la clé privée
    const privateKey = await openpgp.decryptKey({
      privateKey: await openpgp.readPrivateKey({
        armoredKey: privateKeyArmored,
      }),
      passphrase: passphrase, // Passphrase de la clé privée (si nécessaire)
    });

    // Créer un message simple à signer
    const message = await openpgp.createMessage({ text: "Test message" });

    // Signer le message avec la clé privée
    const signedMessage = await openpgp.sign({
      message: message, // Message à signer
      signingKeys: privateKey, // Clé privée pour signer
    });

    // Vérifier la signature avec la clé publique
    const verificationResult = await openpgp.verify({
      message: await openpgp.readCleartextMessage({
        cleartextMessage: signedMessage,
      }),
      verificationKeys: publicKey, // Clé publique pour vérifier
    });

    // Vérifier si la signature est valide
    const { verified } = verificationResult.signatures[0];
    await verified; // Resolve la promesse

    console.log("Les clés correspondent et sont valides !");
    return true;
  } catch (error) {
    console.error("Erreur lors de la vérification des clés : ", error);
    return false;
  }
};
apx.apxauth.testcreatekey = async (alias, passphrase) => {
  const pgpparam = {
    type: "ecc", // Type of the key, defaults to ECC
    curve: "curve25519", // ECC curve name, defaults to curve25519
    userIDs: [{ alias: alias }], // you can pass multiple user IDs
    passphrase: passphrase, // protects the private key
    format: "armored", // output key format, defaults to 'armored' (options: 'armored', 'binary' or 'object')
  };
  const { privateKey, publicKey } = await openpgp.generateKey(pgpparam);

  console.log(verifyKeys(publicKey, privateKey, passphrase));
};
apx.apxauth.detachedSignature = async (privK, passphrase, message) => {
  /**
   * @privK {string} a test priv key
   * @passphrase {string} used to read privK
   * @message {string} message to sign
   * @Return a detached Signature of the message
   */
  let privatekey;
  if (passphrase == "" || passphrase == undefined) {
    privatekey = await openpgp.readKey({ armoredKey: privK });
  } else {
    privatekey = await openpgp.decryptKey({
      privateKey: await openpgp.readPrivateKey({ armoredKey: privK }),
      passphrase,
    });
  }
  //console.log(message);
  const msg = await openpgp.createMessage({ text: message });
  //console.log(msg);
  const sig = await openpgp.sign({
    message: msg,
    signingKeys: privatekey,
    detached: true,
  });
  return btoa(sig);
};
apx.apxauth.clearmsgSignature = async (pubK, privK, passphrase, message) => {
  /**
   * @privK {string} a test priv key
   * @passphrase {string} used to read privK
   * @message {string} message to sign
   * @Return an base64 Signature of the message or error
   */
  const publickey = await openpgp.readKey({ armoredKey: pubK });
  let privatekey;
  if (passphrase == "" || passphrase == undefined) {
    privatekey = await openpgp.readKey({ armoredKey: privK });
  } else {
    privatekey = await openpgp.decryptKey({
      privateKey: await openpgp.readPrivateKey({ armoredKey: privK }),
      passphrase,
    });
  }
  const cleartextMessage = await openpgp.sign({
    message: await openpgp.createCleartextMessage({ text: message }),
    signingKeys: privatekey,
  });
  console.log(cleartextMessage);
  const verificationResult = await openpgp.verify({
    message: await openpgp.readCleartextMessage({ cleartextMessage }),
    verificationKeys: publickey,
  });

  const verified = verificationResult.signatures[0];
  const validity = await verified.verified;
  if (!validity) throw new Error("invalidsignature");

  return btoa(cleartextMessage);
};
apx.apxauth.authenticatedetachedSignature = async (
  alias,
  pubK,
  detachedSignature,
  message
) => {
  /**
   *  Check that alias (pubkey) sign a message
   *  @alias {string} alias link to the publickey
   *  @pubK {string} publiKey text format
   *  @detachedSignature  {string} a detachedsignatured get from apx.apxauth.detachedSignature
   *  @message {string} the message signed
   *  @return {boolean} true the message was signed by alias
   *                    false the message was not signed by alias
   */
  const publickey = await openpgp.readKey({ armoredKey: pubK });
  const msg = await openpgp.createMessage({ text: message });
  const signature = await openpgp.readSignature({
    armoredSignature: atob(detachedSignature), // parse detached signature
  });
  const verificationResult = await openpgp.verify({
    msg, // Message object
    signature,
    verificationKeys: publickey,
  });
  const { verified, keyID } = verificationResult.signatures[0];
  try {
    await verified; // throws on invalid signature
    //console.log("Signed by key id " + keyID.toHex());
    return KeyId.toHex().alias == alias;
  } catch (e) {
    console.log("Signature could not be verified: " + e.message);
    return false;
  }
};
apx.apxauth.createIdentity = async (id, alias, recoemail, passphrase = "") => {
  document.querySelector(`#${id} .msginfo`).innerHTML = "";
  const aliasregex = /^[a-z0-9]*$/;
  //console.log(aliasregex.test(alias));
  if (!(alias && alias.length > 3 && aliasregex.test(alias))) {
    apx.notification(
      `#${id} .msginfo`,
      {
        status: "406",
        ref: "Pagans",
        msg: "invalidalias",
        data: {},
      },
      true
    );
    return false;
  }
  const validator= new Checkjson({properties:{email:{type:"string",format:"email"}}});
  if (recoemail.length > 0 && !validator.verify({email:recoemail})) {
    apx.notification(`#${id} .msginfo`, {
      status: 406,
      ref: "Pagans",
      msg: "invalidemail",
      data: {},
    });
    return false;
  }
  axios
    .get(`/api/apxtri/pagans/alias/${alias}`, {
      headers: apx.data.headers,
    })
    .then((rep) => {
      console.log(rep);
      apx.notification(
        `#${id} .msginfo`,
        {
          ref: "Pagans",
          msg: "aliasexist",
          data: { alias },
        },
        true
      );
    })
    .catch(async (err) => {
      console.log("checkalias:", err);
      if (err.response && err.response.status == 404) {
        // alias does not exist create it is possible
        const keys = await apx.apxauth.generateKey(alias, passphrase);
        apx.data.tmpauth = { ...keys, recoemail, passphrase };
        apx.save();
        console.log(apx.data.tmpauth);
        ["publickey", "privatekey"].forEach((k) => {
          console.log(`${id} button.signup${k}`);
          const btn = document.querySelector(`#${id} button.signup${k}`);
          btn.addEventListener("click", () => {
            const blob = new Blob([keys[k]], { type: "text/plain" });
            const url = URL.createObjectURL(blob);
            const a = document.createElement("a");
            a.href = url;
            a.download = `${alias}_${k}.txt`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
          });
        });
        document
          .querySelectorAll(
            `#${id} .signupalias, #${id} .signupemailrecovery, #${id} .signuppassphrase`
          )
          .forEach((e) => e.setAttribute("disabled", "disabled"));
        document.querySelector(`#${id} .getmykeys`).classList.remove("hidden");
        document.querySelector(`#${id} .btncreatekey`).classList.add("hidden");
      } else {
        apx.notification(
          `#${id} .msginfo`,
          {
            ref: "Middlewares",
            msg: "errrequest",
            data: {},
          },
          true
        );
      }
    });
};

/**
 *
 * @param {string} alias to create
 * @param {string} publickey
 * @param {string} trustedtribe if none => means no passphrase, no privatekey, no trustedtribe
 * @param {string} passphrase
 * @param {string} privatekey
 * @param {string} email  if none => means no passphrase, no privatekey, no trustedtribe
 *
 * if email!=none and trustedtribe!= none create a person with parson profil in trustedtribe
 * if email!=none and trustedtribe==none then send an email at registration with all element but doi not store in backend for futur recovery
 *
 */
apx.apxauth.test = () => {
  //"apx.apxauth.registerIdentity(document.getElementById('inputalias').value,document.getElementById('publickey').document.getElementById('inputpassphrase').value)"
  console.log(apx.data.tmpauth);
};
apx.apxauth.registerIdentity = async (id, trustedtribe) => {
  const authid = document.getElementById(id);
  console.log("trustedtribe",trustedtribe)
  // trustedtribe boolean
  //previously store in apx.data.tmpauth={keys:{alias,privatekey,publickey},recoemail,passphrase}
  
  console.log("tmpauth:",apx.data.tmpauth)
  const setheaders = await apx.apxauth.setheadersauth(
    apx.data.tmpauth.alias,
    apx.data.tmpauth.passphrase,
    apx.data.tmpauth.publickey,
    apx.data.tmpauth.privatekey,
    false
  );
  if (setheaders.status != 200) {
    apx.notification(`#${id} .msginfo`, setheaders);
  } else {
    // add withpublickeyforcreate to check isAuthenticated alias does not already exist

    const data = {};
    data.alias = apx.data.tmpauth.alias;
    data.publickey = apx.data.tmpauth.publickey;
    if (apx.data.tmpauth.recoemail) {
      data.passphrase = apx.data.tmpauth.passphrase;
      data.privatekey = apx.data.tmpauth.privatekey;
      data.email = apx.data.tmpauth.recoemail;
    }
    data.trustedtribe = trustedtribe;
    console.log(data)
    axios
      .post(`/api/apxtri/pagans`, data, { headers: apx.data.headers,  withCredentials:true})
      .then((reppagan) => {
        //console.log(reppagan.data);
        apx.notification(`#${id} .msginfo`, reppagan.data);
        authid.querySelector(`.btncreateidentity`).classList.add("hidden");
        authid.querySelector(`.signupbtnreload`).classList.remove("hidden");
        apx.data.headers.xprofils=reppagan.data.profils;
        apx.data.save();
      })
      .catch((err) => {
        console.log("error:", err);
        const dataerr =
          err.response && err.response.data
            ? err.response.data
            : { status: 500, ref: "Pagans", msg: "", data: {} };
        apx.notification(`#${id} .msginfo`, dataerr);
      });
  }
};
apx.apxauth.jointribe = (id) => {
  /**
   * Allow a pagan to register as a person into a tribe
   * header must be authenticated with alias into an app belonging to xtribe AND schema person must have apxaccessright with role "pagan": {"C": []}
   */
  //console.log(apx.data);
  if (!apx.data.headers.xprofils.includes("persons")) {
    apx.data.headers.xprofils.push("persons");
  }
  const data = {
    alias: apx.data.headers.xalias,
    profils: apx.data.headers.xprofils,
  };
  axios
    .put(`/api/apxtri/pagans/person/${apx.data.headers.xtribe}`, data, {
      headers: apx.data.headers, withCredentials:true
    })
    .then((rep) => {
      apx.notification(`#${id} .msginfo`, rep.data);
      axios
        .get(`/api/apxtri/pagans/logout`, {
          headers: apx.data.headers, withCredentials:true
        })
        .then((rep) => {
          console.log("logout", rep);
          apx.apxauth.authentifyme(
            id,
            apx.data.auth.alias,
            apx.data.auth.passphrase,
            apx.data.auth.privatekey
          );
        })
        .catch((err) => {
          console.log("Erreur logout check:", err);
        });
    })
    .catch((err) => {
      console.log("sorry", err);
      if (err.response && err.response.data)
        apx.notification("#msginfo", err.response.data);
      else
        apx.notification("#msginfo", {
          status: 500,
          ref: "Pagans",
          msg: "errcreate",
          data: {},
        });
    });
};
