WikiLerni/front/public/JS/unsubscribe.app.js

1271 lines
156 KiB
JavaScript
Raw Normal View History

/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/unsubscribe.js");
/******/ })
/************************************************************************/
/******/ ({
/***/ "../config/instance.js":
/*!*****************************!*\
!*** ../config/instance.js ***!
\*****************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var _module$exports;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var users = __webpack_require__(/*! ./users */ "../config/users.js");
var questionnaires = __webpack_require__(/*! ./questionnaires */ "../config/questionnaires.js");
module.exports = (_module$exports = {
apiUrl: "http://localhost:3000/api",
siteUrl: "http://localhost:8080",
adminName: "Fabrice",
adminEmail: "dev@wikilerni.com",
2020-08-07 12:38:19 +02:00
senderName: "WikiLerni (local)",
senderEmail: "bonjour@wikilerni.com",
adminLang: "fr",
2020-08-07 12:38:19 +02:00
theme: "wikilerni",
// le thème utilisé (dans /views) pour générer les pages HTML. Contient ses propres fichiers de configuration.
availableLangs: ["fr"],
// Languages in which the site is available. The first one is the default one.
2020-08-07 12:38:19 +02:00
siteName: "WikiLerni (local)",
beginCodeGodfather: "WL",
// case-sensitive and can't contain "@" !
defaultReceiptDays: "147",
// Par défaut, quel(s) jour(s) de la semaine, l'utilisateur reçoit-il quelque chose ? (1=dimanche, 2=lundi... 7=samedi)
cronTimingAlertInSeconde: 120,
// for logs
responseTimingAlertInSeconde: 3,
// idem
tokenSignupValidationTimeInHours: "48h",
// https://github.com/zeit/ms
tokenLoginLinkTimeInHours: "1h",
tokenConnexionMinTimeInHours: "24h",
tokenConnexionMaxTimeInDays: "180 days",
tokenLoginChangingTimeInHours: "1h",
// for email & password changing
tokenDeleteUserTimeInHours: "1h",
tokenUnsubscribeLinkTimeInDays: "7 days",
// token send with subscription's emails
2021-01-25 16:54:16 +01:00
freeAccountTimingInDays: 0,
// if 0 = unlimited
freeAccountExpirationNotificationInDays: 3,
accountExpirationFirstNotificationInDays: 10,
accountExpirationSecondNotificationInDays: 3,
inactiveAccountTimeToDeleteInDays: 180,
// Questionnaires:
nbQuestionsMin: 1,
// minimum number of questions for the questionnaire to be publishable
2020-08-07 12:38:19 +02:00
nbQuestionsMax: 2,
// if 0 = not maximum
nbChoicesMax: 10,
nbNewQuestionnaires: 12,
// for RSS, etc.
hourGiveNewQuestionnaireBegin: 7,
// in user local time
hourGiveNewQuestionnaireEnd: 21,
// idem
2020-11-04 10:33:14 +01:00
maxQuestionnaireSendedAtSameTime: 50,
// for subscription's e-mailing
minSearchQuestionnaires: 3,
fieldNewQuestionnaires: "publishingAt",
// field to be used to create the list of the last questionnaires, can be "createdAt", "updatedAt" or "publishingAt"
// Groups :
2021-01-25 16:54:16 +01:00
nbQuestionnairesByGroupMin: 1,
nbQuestionnairesByGroupMax: 0,
// Illustrations:
2020-11-04 10:33:14 +01:00
nbIllustrationsMin: 1,
nbIllustrationsMax: 1,
maxIllustrationSizeinOctet: 1000000,
// pas contrôlé pour l'instant. À revoir.
mimeTypesForIllustration: ["image/jpg", "image/jpeg", "image/png", "image/gif", "image/png"],
// -- Upload and resize:
illustrationsWidthMaxInPx: 500,
illustrationsMiniaturesWidthMaxInPx: 200,
// Links:
nbLinksMin: 1,
2021-01-25 16:54:16 +01:00
nbLinksMax: 0
}, _defineProperty(_module$exports, "nbQuestionsMin", 1), _defineProperty(_module$exports, "nbQuestionsMax", 0), _defineProperty(_module$exports, "nbChoicesMax", 10), _defineProperty(_module$exports, "passwordMinLength", users.password.minlength), _defineProperty(_module$exports, "dirCacheUsers", users.dirCacheUsers), _defineProperty(_module$exports, "dirCacheUsersAnswers", users.dirCacheUsersAnswers), _defineProperty(_module$exports, "dirCacheQuestionnaires", questionnaires.dirCacheQuestionnaires), _defineProperty(_module$exports, "dirCacheQuestions", questionnaires.dirCacheQuestions), _defineProperty(_module$exports, "dirCacheUsersQuestionnaires", questionnaires.dirCacheUsersQuestionnaires), _defineProperty(_module$exports, "dirHTMLQuestionnaires", questionnaires.dirHTMLQuestionnaires), _defineProperty(_module$exports, "dirWebQuestionnaires", questionnaires.dirWebQuestionnaires), _module$exports);
/***/ }),
/***/ "../config/questionnaires.js":
/*!***********************************!*\
!*** ../config/questionnaires.js ***!
\***********************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = {
// API'routes (after "apiUrl" defined in instance.js)
questionnaireRoutes: "/questionnaire",
// la base à laquelle s'ajoute les routes suivantes
getListNextQuestionnaires: "/getlistnextquestionnaires/",
getQuestionnaireRoutes: "/get",
getRandomQuestionnairesRoute: "/getrandom",
getStatsQuestionnaires: "/stats/",
previewQuestionnaireRoutes: "/preview",
publishedQuestionnaireRoutes: "/quiz/",
regenerateHTML: "/htmlregenerated",
searchAdminQuestionnairesRoute: "/searchadmin",
searchQuestionnairesRoute: "/search",
2020-11-04 10:33:14 +01:00
// -- groupes :
groupRoutes: "/group",
getGroupRoute: "/get/",
previewGroupRoutes: "/preview",
searchGroupsRoute: "/search",
// -- questions & choices :
questionsRoute: "/question/",
// -- tags :
tagsSearchRoute: "/tags/search/",
// -- answers :
getAdminStats: "/getadminstats/",
getPreviousAnswers: "/user/answers/",
getStatsAnswers: "/user/anwswers/stats/",
2020-11-04 10:33:14 +01:00
// fonctionne aussi pour les groupes
saveAnswersRoute: "/answer/",
// idem
// forms : à compléter avec valeurs par défaut, etc. cf modèle
Questionnaire: {
title: {
maxlength: 255,
required: true
},
slug: {
maxlength: 150
},
// champ requis mais calculé à partir du titre qd laissé vide dans le formulaire
introduction: {
required: true
}
},
searchQuestionnaires: {
minlength: 3,
required: true
},
2020-11-04 10:33:14 +01:00
Group: {
title: {
maxlength: 255,
required: true
},
slug: {
maxlength: 150
} // champ requis mais calculé à partir du titre qd laissé vide dans le formulaire
},
Question: {
text: {
maxlength: 255,
required: true
},
rank: {
required: true,
min: 1,
defaultValue: 1
}
},
Choice: {
text: {
maxlength: 255,
required: true
}
},
search: {
minlength: 3,
required: true
},
searchGroups: {
minlength: 3,
required: true
},
// Emplacement des fichiers JSON générés :
dirCacheGroups: "datas/questionnaires/groups",
dirCacheQuestionnaires: "datas/questionnaires",
dirCacheQuestions: "datas/questionnaires/questions",
dirCacheTags: "datas/questionnaires/tags",
dirCacheUsersQuestionnaires: "datas/users/questionnaires",
// Emplacement des fichiers HTML générés :
2020-11-04 10:33:14 +01:00
dirHTMLGroups: "front/public/quiz/gp",
dirHTMLQuestionnaires: "front/public/quiz",
2020-11-04 10:33:14 +01:00
dirHTMLNews: "front/public/quizs",
dirHTMLTags: "front/public/quizs",
// Idem mais pour urls :
2020-11-04 10:33:14 +01:00
dirWebGroups: "quiz/gp",
dirWebQuestionnaires: "quiz",
2020-11-04 10:33:14 +01:00
dirWebNews: "quizs/",
dirWebTags: "quizs/",
// limite des résultat du moteur de recherche, quand demande de résultats au hasard :
nbRandomResults: 3,
/* Valeurs en fait définies dans instance.js donc à supprimer quand plus utilisées ailleurs : */
nbQuestionsMin: 1,
nbQuestionsMax: 0,
nbChoicesMax: 10,
nbTagsMin: 0,
nbTagsMax: 0 // 0 = not max
};
/***/ }),
/***/ "../config/users.js":
/*!**************************!*\
!*** ../config/users.js ***!
\**************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = {
// API'routes (after "apiUrl" defined in instance.js)
userRoutes: "/user",
checkDeleteLinkRoute: "/confirmdelete/",
checkIfIsEmailfreeRoute: "/isemailfree",
checkLoginRoute: "/checklogin/",
checkNewLoginLinkRoute: "/confirmnewlogin/",
checkSubscribeTokenRoute: "/validation/",
connectionRoute: "/login",
connectionWithLinkRoute: "/checkloginlink",
createUserRoute: "/create",
getAdminStats: "/getadminstats/",
getGodChilds: "/getgodchilds/",
getGodfatherRoute: "/getgodfatherid",
getLoginLinkRoute: "/getloginlink",
getPayments: "/payment/getforoneuser/",
getUserInfos: "/get/",
2020-11-04 10:33:14 +01:00
getUsersQuestionnairesRoute: "/getusersquestionnaires/",
// les questionnaires auxquels l'utilisateur a déjà eu accès via son abonnement
searchUserRoute: "/search/",
2020-11-04 10:33:14 +01:00
signupCompletionRoute: "/signupcompletion/",
subscribeRoute: "/signup",
unsubscribeRoute: "/subscription/stop/",
updateUserInfos: "/modify/",
validateUserRoute: "/validate/",
// forms : à compléter avec valeurs par défaut, etc. cf modèle
name: {
maxlength: 70,
required: true
},
email: {
maxlength: 255,
required: true
},
password: {
minlength: 8,
maxlength: 72,
required: true
},
// https://www.npmjs.com/package/bcrypt#security-issues-and-concerns
newPassword: {
minlength: 8,
maxlength: 72
},
codeGodfather: {
maxlength: 255
},
cguOk: {
value: "true",
required: true
},
search: {
minlength: 1,
required: true
},
timeDifferenceMin: -720,
timeDifferenceMax: 840,
// JSON dir
dirCacheUsers: "datas/users",
dirCacheUsersAnswers: "datas/users/questionnaires/answers",
dirCacheUsersWithoutAnswers: "datas/users/questionnaires/without"
};
/***/ }),
/***/ "../lang sync recursive ^\\.\\/.*\\/general$":
/*!**************************************!*\
!*** ../lang sync ^\.\/.*\/general$ ***!
\**************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var map = {
"./fr/general": "../lang/fr/general.js"
};
function webpackContext(req) {
var id = webpackContextResolve(req);
return __webpack_require__(id);
}
function webpackContextResolve(req) {
if(!__webpack_require__.o(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return map[req];
}
webpackContext.keys = function webpackContextKeys() {
return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "../lang sync recursive ^\\.\\/.*\\/general$";
/***/ }),
/***/ "../lang sync recursive ^\\.\\/.*\\/subscription$":
/*!*******************************************!*\
!*** ../lang sync ^\.\/.*\/subscription$ ***!
\*******************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var map = {
"./fr/subscription": "../lang/fr/subscription.js"
};
function webpackContext(req) {
var id = webpackContextResolve(req);
return __webpack_require__(id);
}
function webpackContextResolve(req) {
if(!__webpack_require__.o(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return map[req];
}
webpackContext.keys = function webpackContextKeys() {
return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "../lang sync recursive ^\\.\\/.*\\/subscription$";
/***/ }),
/***/ "../lang/fr/general.js":
/*!*****************************!*\
!*** ../lang/fr/general.js ***!
\*****************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = {
addBtnTxt: "Ajouter",
addOkMessage: "Les données ont bien été enregistrées.",
alertNewWindow: "nouvelle fenêtre",
badUrl: "Tentative d'accès à une page n'existant pas :",
2020-11-04 10:33:14 +01:00
btnLinkToQuestionnaire: "Afficher !",
btnProposeConnection: "Je me connecte.",
btnProposeSubscribe: "Je crée mon compte.",
2021-01-25 16:54:16 +01:00
btnShowOnWebSite: "Lire la suite sur #SITE_NAME",
deleteBtnTxt: "Supprimer",
2020-11-04 10:33:14 +01:00
deleteFailMessage: "La suppression de l'enregistrement #ID a échoué.",
deleteOkMessage: "La suppression a bien été enregistrée.",
failAuth: "Erreur d'authentification.",
failAuthCron: "Tentative de lancement d'un cron sans le bon token.",
failAuthHeader: "Absence de header Authorization.",
failAuthId: "Identifiant non valide : ",
failAuthToken: "Token invalide ou utilisateur non trouvé.",
neededParams: "Des paramètres nécessaires manquants sont manquants.",
nextPage: "Page suivante",
notAllowed: "Vous n'avez pas les droits nécessaires pour cette action.",
notRequired: "Facultatif.",
notValidFormat: "Format non valide.",
previousPage: "Page précédente",
serverError: "Désolé. Une erreur imprévue est survenue. Si cela persiste, n'hésitez à prévenir l'administrateur du site.",
serverErrorAdmin: "Bug de l'application :",
2020-11-04 10:33:14 +01:00
siteHTMLTitle: "WikiLerni : la culture générale en liberté",
2021-01-25 16:54:16 +01:00
siteMetaDescription: "Avec WikiLerni, vous apprenez régulièrement de nouvelles choses. Vous recevez de courts articles lisibles en quelques minutes. Des quizs vous permettent ensuite de tester ce que vous avez retenu.",
scriptTimingAlert: "*** Script lent : SCRIPT_TIMING millisecondes, route : SCRIPT_URL",
scriptTimingInfo: "Durée de la réponse : SCRIPT_TIMING millisecondes, route : SCRIPT_URL",
statsAdmin: "Durant les dernières 24h : NB_USERS_24H comptes ont été créés, NB_SUBSCRIPTIONS_24H validés et NB_USERS_DELETED_24H supprimés. NB_ANSWERS_24H réponses aux quizs ont été enregistrées.<br>En tout, il y a : NB_USERS_TOT comptes, dont NB_SUBSCRIPTIONS_TOT validés et NB_SUBSCRIPTIONS_PREMIUM comptes prémium. NB_ANSWERS_TOT réponses aux quizs ont été enregistrées.<br>Parmi les NB_USERS_DELETED_TOT comptes supprimés, NB_USERS_DELETED_VALIDED avaient validé leur compte et NB_USERS_DELETED_PREMIUM avaient souscrit un compte prémium.",
2020-11-04 10:33:14 +01:00
subscriptionCall: "Inscrivez-vous !",
updateBtnTxt: "Modifier",
updateOkMessage: "La mise à jour à jour a bien été enregistrée."
};
/***/ }),
/***/ "../lang/fr/subscription.js":
/*!**********************************!*\
!*** ../lang/fr/subscription.js ***!
\**********************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = {
allSubscriptionProcessed: "Tous les abonnés ont été traités pour le moment.",
infosExpirated: "Votre abonnement a expiré, mais il vous reste encore quelques jours avant que votre compte et vos données ne soient complètement supprimées.<br>Pour ce faire, suivez sans tarder les indications ci-dessous :",
infosExpiratedAdmin: "Cet abonnement a expiré.",
infosNbDays: "Votre abonnement est encore valable <b>pendant NB_DAYS jours</b>.<br>Vous pouvez à tout moment prolonger votre abonnement en suivant les indications ci-dessous :",
infosNbDaysAdmin: "Cet abonnement est encore valable <b>pendant NB_DAYS jours</b>.",
infosPaymentsAdmin: "DATE_PAYMENT : paiement de AMOUNT € au nom de CLIENT_NAME.",
isNotValided: "Cet utilisateur n'a pas encore validé son compte.<br>Vous pouvez le faire à sa place <a href='#validationOk'>en cochant la case indiquée</a> et enregistrant.",
2020-08-07 12:38:19 +02:00
mailEndFreeTimeBodyHTML: "<h3>Bonjour USER_NAME,</h3><p>Votre abonnement gratuit à SITE_NAME va expirer d'ici quelques jours.<br><br>Pour continuer à utiliser le site, vous pouvez souscrire à un abonnement sans tarder en cliquant sur le lien ci-dessous.</p>",
mailEndFreeTimeBodyTxt: "Bonjour USER_NAME,\n\nVotre abonnement gratuit à SITE_NAME va expirer d'ici quelques jours.\n\nPour continuer à utiliser le site, vous pouvez sans attendre souscrire à un abonnement :\nLINK_URL",
mailEndFreeTimeLinkTxt: "M'abonner.",
mailEndFreeTimeMessage: " relances envoyées.",
mailEndFreeTimeSubject: "Votre abonnement gratuit va expirer",
2020-08-07 12:38:19 +02:00
mailExpirationBodyHTML: "<h3>Bonjour USER_NAME,</h3><p>Votre abonnement à SITE_NAME va expirer d'ici quelques jours.<br><br>Pour continuer à utiliser SITE_NAME, vous pouvez le prolonger dès aujourd'hui en cliquant sur le lien ci-dessous.</p>",
mailExpirationBodyTxt: "Bonjour USER_NAME,\n\nVotre abonnement à SITE_NAME va expirer d'ici quelques jours.\n\nPour continuer à utiliser SITE_NAME, vous pouvez le prolonger dès aujourd'hui :\nLINK_URL",
mailExpirationLinkTxt: "Prolonger mon abonnement.",
mailExpirationMessage: "FIRST premières et SECOND deuxièmes relances envoyées pour des abonnements expirant d'ici peu.",
mailExpirationRelaunchTxt: "[Rappel] ",
mailExpirationSubject: "Votre abonnement va bientôt expirer",
2020-11-04 10:33:14 +01:00
mailNewElementForGroupTxt: "Bonjour USER_NAME,\n\nVoici le lien vers le nouvel article à lire :\n\nQUESTIONNAIRE_URL\n\nBonne lecture !\n\nStopper les envois ?\nUNSUBSCRIBE_URL",
mailNewQuestionnaireBodyTxt: "Bonjour USER_NAME,\n\nVoici le lien vers le nouveau quiz :\n\nQUESTIONNAIRE_URL\n\nBonne lecture !\n\nStopper les envois ?\nUNSUBSCRIBE_URL",
mailStopMailLinkTxt: "Stopper les envois.",
needKnowIfNoticeOk: "Il manque l'information sur l'acceptation ou non de recevoir des notifications.",
needIntegerNumberOfDays: "Le nombre de jours de l'abonnement doit être un nombre entier.",
needMinNumberOfDays: "Le nombre de jours de l'abonnement ne peut être négatif !",
needNotTooLongDaysList: "La liste de jours sélectionnés n'a pas le bon format (trop longue).",
needNumberOfDays: "Il faut un nombre de jours pour l'abonnement.",
needUniqueDaysList: "La liste de jours sélectionnés n'a pas le bon format. Doublon : ",
needValidDaysList: "La liste de jours sélectionnés n'a pas le bon format. Caractère non valide : ",
noNewQuestionnaireForUser: "Aucun nouveau questionnaire trouvé pour un abonné : ",
unsubscriptionOk: "Votre demande a bien été prise en compte. Vous ne recevrez plus de messages venant du site, sauf pour vous signaler la fin de votre abonnement.<br>N'hésitez pas <a href='/#URL'>à accéder à votre compte</a> pour de nouveau autoriser certains envois.",
unsubscriptionFail: "Si vous voyez ce message, c'est que votre lien de désabonnement ne fonctionne pas.<br>Vous pouvez <a href='/#URL'>accéder à votre compte</a> pour désactiver les envois manuellement."
};
/***/ }),
/***/ "../tools/main.js":
/*!************************!*\
!*** ../tools/main.js ***!
\************************/
/*! no static exports found */
/***/ (function(module, exports) {
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
// Quelques fonctions utiles pour les chaînes
var Tool = /*#__PURE__*/function () {
function Tool() {
_classCallCheck(this, Tool);
}
_createClass(Tool, null, [{
key: "isEmpty",
value: function isEmpty(myVar) {
if (myVar === undefined || myVar === null) return true;else {
myVar += ""; // si autre chose qu'une chaîne envoyé...
myVar = myVar.trim();
if (myVar === "") return true;else return false;
}
}
}, {
key: "trimIfNotNull",
value: function trimIfNotNull(myString) {
if (Tool.isEmpty(myString)) myString = null;else {
myString += ""; // si autre chose qu'une chaîne envoyé...
myString = myString.trim();
}
return myString;
}
}, {
key: "shortenIfLongerThan",
value: function shortenIfLongerThan(myString, max) {
myString += ""; // au cas où cela ne serait pas une chaîne...
2021-01-25 16:54:16 +01:00
if (myString.length > max) myString = myString.substring(0, max - 3) + "…";
return myString;
} // source : https://stackoverflow.com/questions/15604140/replace-multiple-strings-with-multiple-other-strings
}, {
key: "replaceAll",
value: function replaceAll(myString, mapObj) {
var replaceElts = new RegExp(Object.keys(mapObj).join("|"), "gi");
return myString.replace(replaceElts, function (matched) {
return mapObj[matched];
});
} // source : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Math/random
}, {
key: "getRandomInt",
value: function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
} // à compléter : https://en.wikipedia.org/wiki/Date_format_by_country
}, {
key: "dateFormat",
value: function dateFormat(dateString) {
var lang = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "fr";
if (Tool.isEmpty(dateString)) return "";
var myDate = new Date(dateString);
var myDay = myDate.getDate() + "";
if (myDay.length === 1) myDay = "0" + myDay;
var myMounth = myDate.getMonth() + 1 + "";
if (myMounth.length === 1) myMounth = "0" + myMounth;
var myYear = myDate.getFullYear();
if (lang === "fr") return myDay + "/" + myMounth + "/" + myYear;else if (lang === "form") // 2014-02-09
return myYear + "-" + myMounth + "-" + myDay;else return myMounth + "/" + myDay + "/" + myYear;
2020-11-04 10:33:14 +01:00
} // On enlève volontairement les 0/O pour éviter les confusions !
// Et mieux vaut aussi débuter et finir par une lettre simple.
}, {
key: "getPassword",
value: function getPassword(nbCarMin, nbCarMax) {
var nbCar = nbCarMin + Math.floor(Math.random() * (nbCarMax - nbCarMin));
var letters = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz";
var others = "123456789!?.*-_%@&ÉÀÈÙ€$ÂÊÛÎ";
var password = letters[Math.floor(Math.random() * letters.length)];
for (var i = 1; i < nbCar - 1; i++) {
if (i % 2 === 1) password += others[Math.floor(Math.random() * others.length)];else password += letters[Math.floor(Math.random() * letters.length)];
}
password += letters[Math.floor(Math.random() * letters.length)];
return password;
}
}]);
return Tool;
}();
module.exports = Tool;
/***/ }),
/***/ "../views sync recursive ^\\.\\/.*\\.js$":
/*!**********************************!*\
!*** ../views sync ^\.\/.*\.js$ ***!
\**********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var map = {
2020-08-07 12:38:19 +02:00
"./default/config/fr.js": "../views/default/config/fr.js",
"./wikilerni/config/fr.js": "../views/wikilerni/config/fr.js"
};
function webpackContext(req) {
var id = webpackContextResolve(req);
return __webpack_require__(id);
}
function webpackContextResolve(req) {
if(!__webpack_require__.o(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return map[req];
}
webpackContext.keys = function webpackContextKeys() {
return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "../views sync recursive ^\\.\\/.*\\.js$";
/***/ }),
/***/ "../views/default/config/fr.js":
/*!*************************************!*\
!*** ../views/default/config/fr.js ***!
\*************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = {
headLinks: [{
anchor: "Accueil",
attributes: {
href: "/"
}
}, {
anchor: "Mon compte",
attributes: {
2020-08-07 12:38:19 +02:00
href: "/connexion.html",
id: "accountHeadLink"
}
}, {
anchor: "À propos",
attributes: {
href: "/a-propos.html"
}
}, {
anchor: "Contact",
attributes: {
href: "/contact.html"
}
}],
footLinks: [{
anchor: "Crédits",
attributes: {
href: "/credits.html"
}
}, {
anchor: "Mentions légales",
attributes: {
href: "/mentions-legales.html",
rel: "nofollow"
}
}, {
anchor: "Données personnelles",
attributes: {
href: "/donnees.html"
}
}, {
anchor: "C.G.U.",
attributes: {
href: "/cgu.html",
rel: "nofollow"
}
}, {
anchor: "C.G.V.",
attributes: {
href: "/cgv.html",
rel: "nofollow"
}
}],
maxQuestionnairesByPage: 10,
userHomePage: "accueil.html",
adminHomePage: "admin.html",
managerHomePage: "gestion.html",
subscribePage: "inscription.html",
connectionPage: "connexion.html",
accountPage: "compte.html",
questionnairesManagementPage: "gestion-quizs.html",
usersManagementPage: "gestion-utilisateurs.html",
nbQuestionnairesUserHomePage: 10,
illustrationDir: "/img/quizs/",
siteSlogan: "Cultivons notre jardin !",
homeTitle1: "De nature curieuse ?",
homeP1: "Avec WikiLerni vous apprenez chaque jour de nouvelles choses.<br>Des articles de Wikipédia sont sélectionnés pour vous et sont suivis d'un quiz vous permettant de tester ce que vous en avez retenu.<br>De jour en jour de nouvelles graines de savoir sont ainsi semées dans votre \"jardin\".",
homeTitle2: "La culture en liberté",
homeP2: "Tout comme sur Wikipédia (*), le logiciel et le contenu partagé sur WikiLerni sont libres.<br>Vous pouvez les utiliser, les modifier et les diffuser selon votre souhait.<br>Sur WikiLerni, pas de publicité, ni de commercialisation de vos données personnelles.<br>Vous pouvez venir y \"cultiver votre jardin\" en toute tranquillité.<br><br><small><em>(*) Bien que partageant ses valeurs, WikiLerni est un projet indépendant de la fondation Wikipédia.</em></small>",
newQuestionnairesTitle: "Les derniers quizs publiés sur WikiLerni",
newQuestionnairesIntro: "Liste des derniers quizs publiés sur WikiLerni.",
explanationTitle: "Vous découvrez WikiLerni ?",
explanationTxt: "Le principe est simple : vous commencez par lire l'article Wikipédia dont le lien vous est proposé.<br>Puis vous afficher le quiz pour vérifier ce que vous en avez retenu de votre lecture. Vous obtenez alors votre résultat immédiatement.<br><br>Toutes les réponses se trouvent dans l'article proposé à la lecture. <b>Vous êtes ici pour apprendre de nouvelles choses</b>, mais libre à vous d'essayer d'y répondre immédiatement.<br><br>Quand le sujet s'y prête, ne vous étonnez pas si certaines des réponses proposées peuvent être un peu décalées, absurdes... On peut apprendre avec le sourire, non ? :-)<br><br>Une fois votre résultat obtenu, il vous sera proposé de créer un compte pour le sauvegarder.<br>Ce compte vous permettra de tester de nouveau ce quiz pour vérifier ce que vous en avez retenu plusieurs jours, semaines, mois... Et de recevoir régulièrement de nouvelles suggestions de lectures.<br><br>Mais <b>la création de ce compte est facultative</b> et <a href='/quizs/' title='Les derniers quizs publiés'>vous pouvez parcourir WikiLerni librement</a>.",
2020-08-07 12:38:19 +02:00
noJSNotification: "Désolé, mais pour l'instant, l'utilisation de WikiLerni nécessite l'activation du JavaScript.",
tagsListTxt: "Parcourir les rubriques :"
};
/***/ }),
/***/ "../views/wikilerni/config/fr.js":
/*!***************************************!*\
!*** ../views/wikilerni/config/fr.js ***!
\***************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = {
// liens de l'interface
2020-08-07 12:38:19 +02:00
headLinks: [{
anchor: "Contact",
attributes: {
href: "/contact.html",
rel: "nofollow"
}
}, {
anchor: "Parcourir",
attributes: {
href: "/quizs/",
id: "indexHeadLink",
2020-11-04 10:33:14 +01:00
title: "Les dernières publications"
2020-08-07 12:38:19 +02:00
}
}, {
anchor: "Mon compte",
attributes: {
href: "/connexion.html",
id: "accountHeadLink",
title: "Accéder ou créez votre compte WikiLerni"
2020-08-07 12:38:19 +02:00
}
}, {
anchor: "À propos",
attributes: {
href: "/a-propos.html",
title: "En savoir + sur WikiLerni"
}
}, {
anchor: "Accueil",
attributes: {
href: "/",
title: "Page d'accueil"
2020-08-07 12:38:19 +02:00
}
}],
footLinks: [{
anchor: "Blog",
attributes: {
href: "https://framasphere.org/people/7e54b7a0b53201389eef2a0000053625",
title: "Le blog WikiLerni sur diaspora*"
2020-08-07 12:38:19 +02:00
}
}, {
anchor: "Crédits",
attributes: {
href: "/credits.html",
title: "Qui a créé WikiLerni ? Quels sont vos droits ?"
2020-08-07 12:38:19 +02:00
}
}, {
anchor: "Mentions légales",
attributes: {
href: "/mentions-legales.html",
rel: "nofollow"
}
}, {
anchor: "Données personnelles",
attributes: {
href: "/donnees.html",
title: "Vos données personnelles sur WikiLerni"
2020-08-07 12:38:19 +02:00
}
}, {
anchor: "CGV & CGU",
attributes: {
href: "/CGV-CGU.html",
rel: "nofollow"
}
}],
accountPage: "compte.html",
aboutPage: "a-propos.html",
2020-08-07 12:38:19 +02:00
adminHomePage: "admin.html",
cguPage: "CGV-CGU.html",
2020-08-07 12:38:19 +02:00
connectionPage: "connexion.html",
deleteLinkPage: "aurevoir.html?t=",
2020-08-07 12:38:19 +02:00
loginLinkPage: "login.html?t=",
managerHomePage: "gestion.html",
2020-08-07 12:38:19 +02:00
newLoginLinkPage: "newlogin.html?t=",
questionnairesManagementPage: "gestion-quizs.html",
2020-08-07 12:38:19 +02:00
stopMailPage: "stop-mail.html?t=",
subscribePage: "inscription.html",
updateAccountPage: "compte.html",
userHomePage: "accueil.html",
userHomePageTxt: "Ma page d'accueil.",
2020-08-07 12:38:19 +02:00
usersManagementPage: "gestion-utilisateurs.html",
validationLinkPage: "validation.html?t=",
/* Textes (général) */
2020-08-07 12:38:19 +02:00
siteSlogan: "Cultivons notre jardin !",
noJSNotification: "Désolé, mais pour l'instant, l'utilisation de WikiLerni nécessite l'activation du JavaScript.",
mailRecipientTxt: "Message envoyé à :",
2021-01-25 16:54:16 +01:00
licenceTxt: "@copyleft Le contenu de WikiLerni <a href=\"/credits.html\" title=\"En savoir plus ?\">est libre</a> et vous est offert sans publicité. Vous pouvez <a href=\"/participer-financement.html\" title=\"Financement participatif avec contre-parties\">participer à son financement en cliquant ici</a>.",
/* Page d'accueil */
2020-08-07 12:38:19 +02:00
homePageTxt: "Page d'accueil",
homeTitle1: "De nature curieuse ?",
2021-01-25 16:54:16 +01:00
homeP1: "<b>Avec WikiLerni, vous apprenez régulièrement de nouvelles choses</b>.<br>Vous recevez de courts articles, lisibles en quelques minutes.<br>Des quizs vous permettent ensuite de tester ce que vous avez retenu.<br>De jour en jour <b>de nouvelles graines de culture sont ainsi semées dans votre jardin</b>.",
2020-11-04 10:33:14 +01:00
homeTitle2: "La culture générale en liberté",
2021-01-25 16:54:16 +01:00
homeP2: "<b>Pas de faits alternatifs</b>, tous les contenus sont <b>sourcés par des articles Wikipédia</b>.<br>Et tout comme sur Wikipédia, le logiciel et le contenu publié sur WikiLerni <a href=\"/credits.html\" title=\"En savoir plus sur ce sujet\">sont partagés sous licences libres</a>.<br>Le tout sans publicité, ni commercialisation de vos données.<br><b>Sur WikiLerni, vous cultivez votre jardin en toute tranquillité.</b>",
homeBtnAboutTxt: "En savoir plus sur WikiLerni ?",
2021-01-25 16:54:16 +01:00
homeBtnSubscribeTxt: "Testez WikiLerni",
homeSubcriptionFormTitle: "Recevez les prochains articles WikiLerni",
/* Page dernières publications... */
newQuestionnairesTitle: "Culture générale - apprenez de nouvelles choses avec WikiLerni",
2020-11-04 10:33:14 +01:00
newQuestionnairesIntro: "WikiLerni : testez vos connaissances et apprenez de nouvelles choses avec WikiLerni.",
newsListTitle: "<p><b>Avec WikiLerni, vous apprenez chaque jour quelque chose de nouveau</b><br>Si dessous les dernières publications. Vous pouvez aussi <a href='/quizs/themes.html'>parcourir le site par thèmes ou mots-clés</a>.</p>",
/* Plan du site, liste des tags */
tagListTitle: "Culture générale - des articles et quizs sur de nombreux thèmes !",
tagListMetaDesc: "WikiLerni : découvrir les différents thèmes abordés par WikiLerni. Inxex du site.",
tagListIntro: "<h3>Avec WikiLerni, devenez fort en thèmes... Oui mais quels thèmes ? :)</h3><blockquote>Aristote: «Lhomme a naturellement la passion de connaître…»</blockquote>",
/* Page quizs */
2021-01-25 16:54:16 +01:00
answersExplanationsLinkText: "Relire",
quizElementLinksIntro: "En savoir plus",
2020-11-04 10:33:14 +01:00
quizElementSubcriptionFormTitle: "Recevez les prochains articles WikiLerni",
explanationTitle: "Vous découvrez WikiLerni?",
explanationTxt: "<p>Le principe est simple: <b>vous commencez par lire larticle Wikipédia dont le lien vous est proposé</b>. Puis vous <b>afficher le quiz pour vérifier ce que vous avez retenu de votre lecture</b>. Suivant les questions, <b>une ou plusieurs réponses peuvent être correctes</b> et doivent donc être cochées. Cest toujours <b>le contenu de larticle Wikipédia qui fait foi</b> concernant les «bonnes» réponses. Cest une façon de tester à la fois votre capacité dattention et votre mémoire. Les articles de Wikipédia peuvent évoluer, donc nhésitez pas <a href='/contact.html'>à me signaler une erreur</a>.</p><p><b>WikiLerni vous propose dautres solutions pour améliorer votre culture générale</b>. Pour en savoir plus, cliquez sur le bouton ci-dessous.</p>",
2021-01-25 16:54:16 +01:00
explanationElementTxt: "<p>WikiLerni vous propose de <b>recevoir par e-mail à la fréquence choisie, de courts articles lisibles en quelques minutes</b> et portant sur des sujets très variés de <b>culture générale</b> (arts, histoire, littérature, sciences, etc.).</p><p>Ces articles sont basés sur <b>une ou plusieurs pages de Wikipédia</b> (fournies en lien), dont <b>ils extraient certaines informations</b>.</p><p>Chaque série darticles est <b>suivie dun quiz</b> permettant de tester ce que vous en avez retenu.</p><p><b>Vous apprenez ainsi régulièrement de nouvelles choses</b> très simplement.</p>",
/* Autres */
illustrationDir: "/img/quizs/",
twitterAccount: "WikiLerni",
maxQuestionnairesByPage: 12,
maxQuestionnairesSiteHomePage: 3,
nbQuestionnairesUserHomePage: 3
};
/***/ }),
/***/ "./src/tools/clientstorage.js":
/*!************************************!*\
!*** ./src/tools/clientstorage.js ***!
\************************************/
/*! exports provided: saveLocaly, getLocaly, removeLocaly */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "saveLocaly", function() { return saveLocaly; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getLocaly", function() { return getLocaly; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeLocaly", function() { return removeLocaly; });
// FONCTIONS UTILES AU STOCKAGE LOCAL (SESSION, COOKIES, INDEXDB, ETC.)
// Revenir pour gérer le cas où local.storage n'est pas connu pour utiliser cookie
var saveLocaly = function saveLocaly(name, data) {
localStorage.setItem(name, JSON.stringify(data));
};
var getLocaly = function getLocaly(name) {
var json = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (json) return JSON.parse(localStorage.getItem(name));else return localStorage.getItem(name);
};
var removeLocaly = function removeLocaly(name) {
localStorage.removeItem(name);
};
/***/ }),
/***/ "./src/tools/dom.js":
/*!**************************!*\
!*** ./src/tools/dom.js ***!
\**************************/
/*! exports provided: addElement */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addElement", function() { return addElement; });
/* harmony import */ var _tools_main__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../tools/main */ "../tools/main.js");
/* harmony import */ var _tools_main__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_tools_main__WEBPACK_IMPORTED_MODULE_0__);
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
// Fonction associant les attributs fournis à un champ de formulaire
var addElement = function addElement(eltParent, eltType) {
var eltContent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
var eltId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "";
var eltClass = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
var eltAttributes = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
var replace = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : true;
if (Object(_tools_main__WEBPACK_IMPORTED_MODULE_0__["isEmpty"])(eltType) || Object(_tools_main__WEBPACK_IMPORTED_MODULE_0__["isEmpty"])(eltParent)) return false;else {
var newElement = document.createElement(eltType);
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_0__["isEmpty"])(eltId)) // tester si l'id n'est pas déjà utilisé dans le DOM ?
newElement.id = eltId;
if (Array.isArray(eltClass) && eltClass.length != 0) {
for (var i in eltClass) {
newElement.classList.add(eltClass[i]);
}
}
if (_typeof(eltAttributes) === "object") // !! tous les objets ne sont pas ok
{
for (var attributName in eltAttributes) {
newElement.setAttribute(attributName, eltAttributes[attributName]);
}
}
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_0__["isEmpty"])(eltContent)) newElement.innerHTML = eltContent.replace(/\n/g, "<br>"); // innerHTML permet d'ajouter du texte ayant lui-même des balises, etc.
if (replace) eltParent.innerHTML = "";
eltParent.appendChild(newElement);
}
};
/***/ }),
/***/ "./src/tools/everywhere.js":
/*!*********************************!*\
!*** ./src/tools/everywhere.js ***!
\*********************************/
/*! exports provided: helloDev, updateAccountLink */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "helloDev", function() { return helloDev; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "updateAccountLink", function() { return updateAccountLink; });
// Ce script fournit des fonctions utilisées sur toutes les pages du site
var helloDev = function helloDev() {
2021-01-25 16:54:16 +01:00
console.log("**** Hello ami développeur :-)\n\nLe code de WikiLerni est libre et vous pouvez le trouver à cette adresse :\nhttps://forge.chapril.org/Fab_Blab/WikiLerni\n\nPour les suggestions d'amélioration ou questions : dev@wililerni.com ****");
return true;
};
var updateAccountLink = function updateAccountLink(status, configTemplate) {
var link = document.getElementById("accountHeadLink");
var homePage = status + "HomePage";
link.href = "/" + configTemplate[homePage];
};
/***/ }),
/***/ "./src/tools/url.js":
/*!**************************!*\
!*** ./src/tools/url.js ***!
\**************************/
/*! exports provided: getUrlParams */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getUrlParams", function() { return getUrlParams; });
/* harmony import */ var _tools_main__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../tools/main */ "../tools/main.js");
/* harmony import */ var _tools_main__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_tools_main__WEBPACK_IMPORTED_MODULE_0__);
// Fonction récupérant les paramètres passés par l'url
var getUrlParams = function getUrlParams() {
if (Object(_tools_main__WEBPACK_IMPORTED_MODULE_0__["isEmpty"])(location.search)) return false;
var parameters = location.search.substring(1).split("&");
if (!Array.isArray(parameters) || parameters.length === 0) return false;
var param,
datas = {};
for (var i in parameters) {
param = parameters[i].split("=");
if (param.length === 2) datas[param[0]] = decodeURI(param[1]);
}
return datas;
};
/***/ }),
/***/ "./src/tools/users.js":
/*!****************************!*\
!*** ./src/tools/users.js ***!
\****************************/
2020-11-04 10:33:14 +01:00
/*! exports provided: getTimeDifference, setSession, checkAnswerDatas, checkSession */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getTimeDifference", function() { return getTimeDifference; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setSession", function() { return setSession; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "checkAnswerDatas", function() { return checkAnswerDatas; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "checkSession", function() { return checkSession; });
/* harmony import */ var _config_instance_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../config/instance.js */ "../config/instance.js");
/* harmony import */ var _config_instance_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_config_instance_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _config_users_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../config/users.js */ "../config/users.js");
/* harmony import */ var _config_users_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_config_users_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _clientstorage_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clientstorage.js */ "./src/tools/clientstorage.js");
/* harmony import */ var _tools_main__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../tools/main */ "../tools/main.js");
/* harmony import */ var _tools_main__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_tools_main__WEBPACK_IMPORTED_MODULE_3__);
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
var lang = _config_instance_js__WEBPACK_IMPORTED_MODULE_0__["availableLangs"][0];
var configTemplate = __webpack_require__("../views sync recursive ^\\.\\/.*\\.js$")("./" + _config_instance_js__WEBPACK_IMPORTED_MODULE_0__["theme"] + "/config/" + lang + ".js");
var getTimeDifference = function getTimeDifference() {
2020-08-07 12:38:19 +02:00
// multiplier par -1, car c'est ce qu'il faut "ajouter" à l'heure UTC pour revenir en heure locale qui m'intéresse et non l'inverse
var timeLocal = new Date().getTimezoneOffset() * -1;
if (timeLocal > _config_users_js__WEBPACK_IMPORTED_MODULE_1__["timeDifferenceMax"] || timeLocal < _config_users_js__WEBPACK_IMPORTED_MODULE_1__["timeDifferenceMin"]) return 0;else return timeLocal;
}; // J'utilise le stockage local du navigateur pour enregistrer les données permettant de reconnaître l'utilisateur par la suite
// Seul le serveur pourra vérifier que les identifiants sont (toujours) valides.
var setSession = function setSession(userId, token, durationTS) {
var storageUser = {
id: userId,
token: token,
duration: durationTS
};
Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["saveLocaly"])("user", storageUser);
2020-11-04 10:33:14 +01:00
}; // Vérifie qu'il y a des données locales concernant le résultat d'un quiz ou d'un groupe de quizs
// Et les ajoute aux données envoyées par les formulaires d'inscription/connexion si c'est le cas
var checkAnswerDatas = function checkAnswerDatas(datas) {
var lastAnswer = Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["getLocaly"])("lastAnswer");
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(lastAnswer)) {
var answer = JSON.parse(lastAnswer);
2020-11-04 10:33:14 +01:00
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(answer.duration) && !Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(answer.nbCorrectAnswers) && !Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(answer.nbQuestions) && (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(answer.QuestionnaireId) || !Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(answer.GroupId))) {
datas.duration = answer.duration;
datas.nbCorrectAnswers = answer.nbCorrectAnswers;
datas.nbQuestions = answer.nbQuestions;
2020-11-04 10:33:14 +01:00
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(answer.QuestionnaireId)) datas.QuestionnaireId = answer.QuestionnaireId;else datas.GroupId = answer.GroupId;
}
}
return datas;
}; // Cette fonction teste la connexion de l'utilisateur d'une page
// On peut fournis une liste de statuts acceptés (si vide = tous), ainsi qu'une url de redirection si non connecté, un message d'erreur à afficher sur la page de destination et l'url sur laquelle revenir une fois connecté
var checkSession = /*#__PURE__*/function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var status,
urlRedirection,
message,
urlWanted,
_args = arguments;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
status = _args.length > 0 && _args[0] !== undefined ? _args[0] : [];
urlRedirection = _args.length > 1 ? _args[1] : undefined;
message = _args.length > 2 ? _args[2] : undefined;
urlWanted = _args.length > 3 ? _args[3] : undefined;
return _context.abrupt("return", new Promise(function (resolve, reject) {
var userDatas = Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["getLocaly"])("user");
if (Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(userDatas)) {
redirectUser(urlRedirection, message, urlWanted);
resolve(false);
} else {
var user = JSON.parse(userDatas);
if (Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(user.id) || Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(user.token) || Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(user.duration) || user.duration < Date.now()) {
Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["removeLocaly"])("user");
redirectUser(urlRedirection, message, urlWanted);
resolve(false);
} else {
var xhr = new XMLHttpRequest();
xhr.open("GET", _config_instance_js__WEBPACK_IMPORTED_MODULE_0__["apiUrl"] + _config_users_js__WEBPACK_IMPORTED_MODULE_1__["userRoutes"] + _config_users_js__WEBPACK_IMPORTED_MODULE_1__["checkLoginRoute"] + user.token);
xhr.onload = function () {
var response = JSON.parse(xhr.responseText);
if (xhr.status === 200 && response.isValid && response.id != undefined) {
if (response.id === user.id) {
user.name = response.name;
user.language = response.language;
user.timeDifference = response.timeDifference;
2020-08-07 12:38:19 +02:00
user.status = response.status; // c'est le token qui sert à vérifier le statut à chaque requête à l'API
Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["saveLocaly"])("user", user); // si il s'agit d'un "user" et que son abonnement a expiré, je le redirige vers la caisse :-)
if (response.status === "user" && response.nbDaysOk <= 0) {
2020-08-07 12:38:19 +02:00
var urlAccount = _config_instance_js__WEBPACK_IMPORTED_MODULE_0__["siteUrl"] + "/" + configTemplate.accountPage;
if (window.location.href.indexOf(urlAccount) === -1) window.location.assign("/" + configTemplate.accountPage + "#subscribe"); // passée directement ici, l'ancre #subscribe ne fonctionne pas !?
resolve(true);
} else {
if (status.length !== 0 && status.indexOf(response.status) === -1) {
redirectUser(urlRedirection, message, urlWanted);
resolve(false);
} else resolve(true);
}
} else {
Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["removeLocaly"])("user");
redirectUser(urlRedirection, message, urlWanted);
resolve(false);
}
} else {
Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["removeLocaly"])("user");
redirectUser(urlRedirection, message, urlWanted);
resolve(false);
}
};
xhr.onerror = function () {
return reject(xhr.statusText);
};
xhr.send();
}
}
}));
case 5:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function checkSession() {
return _ref.apply(this, arguments);
};
}(); // Cette fonction sert à la précédente en cas de connexion non valide
var redirectUser = function redirectUser(urlRedirection, message, urlWanted) {
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(message)) Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["saveLocaly"])("message", message);
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(urlWanted)) Object(_clientstorage_js__WEBPACK_IMPORTED_MODULE_2__["saveLocaly"])("url", urlWanted);
if (!Object(_tools_main__WEBPACK_IMPORTED_MODULE_3__["isEmpty"])(urlRedirection)) window.location.assign(urlRedirection);
};
/***/ }),
/***/ "./src/unsubscribe.js":
/*!****************************!*\
!*** ./src/unsubscribe.js ***!
\****************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _config_instance_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../config/instance.js */ "../config/instance.js");
/* harmony import */ var _config_instance_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_config_instance_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _tools_clientstorage_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tools/clientstorage.js */ "./src/tools/clientstorage.js");
/* harmony import */ var _tools_dom_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./tools/dom.js */ "./src/tools/dom.js");
/* harmony import */ var _tools_everywhere_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./tools/everywhere.js */ "./src/tools/everywhere.js");
/* harmony import */ var _tools_url_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./tools/url.js */ "./src/tools/url.js");
/* harmony import */ var _tools_users_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./tools/users.js */ "./src/tools/users.js");
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
// -- GESTION DE LA PAGE PERMETTANT DE SE DÉBONNER DE TOUS LES ENVOIS
/// Un token est transmis en paramètre de l'Url. Il a une validité limité dans le temps. Si le token est ok, il n'est pas nécessaire d'être connecté.
/// Dans le cas où il n'est plus valide, on peut proposer à l'utilisateur de se connecter à son compte pour se désabonner.
/// Si le token est ok, on valide enregistrement le désabonnement et affiche un message de confirmation
// Fichier de configuration côté client :
var lang = _config_instance_js__WEBPACK_IMPORTED_MODULE_0__["availableLangs"][0];
var _require = __webpack_require__("../views sync recursive ^\\.\\/.*\\.js$")("./" + _config_instance_js__WEBPACK_IMPORTED_MODULE_0__["theme"] + "/config/" + lang + ".js"),
accountPage = _require.accountPage;
var _require2 = __webpack_require__(/*! ../../config/users */ "../config/users.js"),
userRoutes = _require2.userRoutes,
unsubscribeRoute = _require2.unsubscribeRoute; // Importation des fonctions utile au script :
// Dictionnaires :
var _require3 = __webpack_require__("../lang sync recursive ^\\.\\/.*\\/general$")("./" + lang + "/general"),
serverError = _require3.serverError;
var _require4 = __webpack_require__("../lang sync recursive ^\\.\\/.*\\/subscription$")("./" + lang + "/subscription"),
unsubscriptionFail = _require4.unsubscriptionFail;
var divResponse = document.getElementById("response");
Object(_tools_everywhere_js__WEBPACK_IMPORTED_MODULE_3__["helloDev"])();
var initialise = /*#__PURE__*/function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var datas, xhr;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
try {
datas = Object(_tools_url_js__WEBPACK_IMPORTED_MODULE_4__["getUrlParams"])();
if (datas && datas.t !== undefined) {
xhr = new XMLHttpRequest();
xhr.open("GET", _config_instance_js__WEBPACK_IMPORTED_MODULE_0__["apiUrl"] + userRoutes + unsubscribeRoute + datas.t);
xhr.onreadystatechange = function () {
if (this.readyState == XMLHttpRequest.DONE) {
var response = JSON.parse(this.responseText);
if (this.status === 200 && response.message != undefined) Object(_tools_dom_js__WEBPACK_IMPORTED_MODULE_2__["addElement"])(divResponse, "p", response.message.replace("#URL", accountPage), "", ["success"]);else Object(_tools_dom_js__WEBPACK_IMPORTED_MODULE_2__["addElement"])(divResponse, "p", unsubscriptionFail.replace("#URL", accountPage), "", ["error"]);
}
};
xhr.send();
}
} catch (e) {
Object(_tools_dom_js__WEBPACK_IMPORTED_MODULE_2__["addElement"])(divResponse, "p", serverError, "", ["error"]);
}
case 1:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function initialise() {
return _ref.apply(this, arguments);
};
}();
initialise();
/***/ })
/******/ });
2021-01-25 16:54:16 +01:00
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4uL2NvbmZpZy9pbnN0YW5jZS5qcyIsIndlYnBhY2s6Ly8vLi4vY29uZmlnL3F1ZXN0aW9ubmFpcmVzLmpzIiwid2VicGFjazovLy8uLi9jb25maWcvdXNlcnMuanMiLCJ3ZWJwYWNrOi8vLy4uL2xhbmcgc3luYyBeXFwuXFwvLipcXC9nZW5lcmFsJCIsIndlYnBhY2s6Ly8vLi4vbGFuZyBzeW5jIF5cXC5cXC8uKlxcL3N1YnNjcmlwdGlvbiQiLCJ3ZWJwYWNrOi8vLy4uL2xhbmcvZnIvZ2VuZXJhbC5qcyIsIndlYnBhY2s6Ly8vLi4vbGFuZy9mci9zdWJzY3JpcHRpb24uanMiLCJ3ZWJwYWNrOi8vLy4uL3Rvb2xzL21haW4uanMiLCJ3ZWJwYWNrOi8vLy4uL3ZpZXdzIHN5bmMgXlxcLlxcLy4qXFwuanMkIiwid2VicGFjazovLy8uLi92aWV3cy9kZWZhdWx0L2NvbmZpZy9mci5qcyIsIndlYnBhY2s6Ly8vLi4vdmlld3Mvd2lraWxlcm5pL2NvbmZpZy9mci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvdG9vbHMvY2xpZW50c3RvcmFnZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvdG9vbHMvZG9tLmpzIiwid2VicGFjazovLy8uL3NyYy90b29scy9ldmVyeXdoZXJlLmpzIiwid2VicGFjazovLy8uL3NyYy90b29scy91cmwuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3Rvb2xzL3VzZXJzLmpzIiwid2VicGFjazovLy8uL3NyYy91bnN1YnNjcmliZS5qcyJdLCJuYW1lcyI6WyJ1c2VycyIsInJlcXVpcmUiLCJxdWVzdGlvbm5haXJlcyIsIm1vZHVsZSIsImV4cG9ydHMiLCJhcGlVcmwiLCJzaXRlVXJsIiwiYWRtaW5OYW1lIiwiYWRtaW5FbWFpbCIsInNlbmRlck5hbWUiLCJzZW5kZXJFbWFpbCIsImFkbWluTGFuZyIsInRoZW1lIiwiYXZhaWxhYmxlTGFuZ3MiLCJzaXRlTmFtZSIsImJlZ2luQ29kZUdvZGZhdGhlciIsImRlZmF1bHRSZWNlaXB0RGF5cyIsImNyb25UaW1pbmdBbGVydEluU2Vjb25kZSIsInJlc3BvbnNlVGltaW5nQWxlcnRJblNlY29uZGUiLCJ0b2tlblNpZ251cFZhbGlkYXRpb25UaW1lSW5Ib3VycyIsInRva2VuTG9naW5MaW5rVGltZUluSG91cnMiLCJ0b2tlbkNvbm5leGlvbk1pblRpbWVJbkhvdXJzIiwidG9rZW5Db25uZXhpb25NYXhUaW1lSW5EYXlzIiwidG9rZW5Mb2dpbkNoYW5naW5nVGltZUluSG91cnMiLCJ0b2tlbkRlbGV0ZVVzZXJUaW1lSW5Ib3VycyIsInRva2VuVW5zdWJzY3JpYmVMaW5rVGltZUluRGF5cyIsImZyZWVBY2NvdW50VGltaW5nSW5EYXlzIiwiZnJlZUFjY291bnRFeHBpcmF0aW9uTm90aWZpY2F0aW9uSW5EYXlzIiwiYWNjb3VudEV4cGlyYXRpb25GaXJzdE5vdGlmaWNhdGlvbkluRGF5cyIsImFjY291bnRFeHBpcmF0aW9uU2Vjb25kTm90aWZpY2F0aW9uSW5EYXlzIiwiaW5hY3RpdmVBY2NvdW50VGltZVRvRGVsZXRlSW5EYXlzIiwibmJRdWVzdGlvbnNNaW4iLCJuYlF1ZXN0aW9uc01heCIsIm5iQ2hvaWNlc01heCIsIm5iTmV3UXVlc3Rpb25uYWlyZXMiLCJob3VyR2l2ZU5ld1F1ZXN0aW9ubmFpcmVCZWdpbiIsImhvdXJHaXZlTmV3UXVlc3Rpb25uYWlyZUVuZCIsIm1heFF1ZXN0aW9ubmFpcmVTZW5kZWRBdFNhbWVUaW1lIiwibWluU2VhcmNoUXVlc3Rpb25uYWlyZXMiLCJmaWVsZE5ld1F1ZXN0aW9ubmFpcmVzIiwibmJRdWVzdGlvbm5haXJlc0J5R3JvdXBNaW4iLCJuYlF1ZXN0aW9ubmFpcmVzQnlHcm91cE1heCIsIm5iSWxsdXN0cmF0aW9uc01pbiIsIm5iSWxsdXN0cmF0aW9uc01heCIsIm1heElsbHVzdHJhdGlvblNpemVpbk9jdGV0IiwibWltZVR5cGVzRm9ySWxsdXN0cmF0aW9uIiwiaWxsdXN0cmF0aW9uc1dpZHRoTWF4SW5QeCIsImlsbHVzdHJhdGlvbnNNaW5pYXR1cmVzV2lkdGhNYXhJblB4IiwibmJMaW5rc01pbiIsIm5iTGlua3NNYXgiLCJwYXNzd29yZCIsIm1pbmxlbmd0aCIsImRpckNhY2hlVXNlcnMiLCJkaXJDYWNoZVVzZXJzQW5zd2VycyIsImRpckNhY2hlUXVlc3Rpb25uYWlyZXMiLCJkaXJDYWNoZVF1ZXN0aW9ucyIsImRpckNhY2hlVXNlcnNRdWVzdGlvbm5haXJlcyIsImRpckhUTUxRdWVzdGlvbm5haXJlcyIsImRpcldlYlF1ZXN0aW9ubmFpcmVzIiwicXVlc3Rpb25uYWlyZVJvdXRlcyIsImdldExpc3ROZXh0UXVlc3Rpb25uYWlyZXMiLCJnZXRRdWVzdGlvbm5haXJlUm91dGVzIiwiZ2V0UmFuZG9tUXVlc3Rpb25uYWlyZXNSb3V0ZSIsImdldFN0YXRzUXVlc3Rpb25uYWlyZXMiLCJwcmV2aWV3UXVlc3Rpb25uYWlyZVJvdXRlcyIsInB1Ymxpc2hlZFF1ZXN0aW9ubmFpcmVSb3V0ZXMiLCJyZWdlbmVyYXRlSFRNTCIsInNlYXJjaEFkbWluUXVlc3Rpb25uYWlyZXNSb3V0ZSIsInNlYXJjaFF1ZXN0aW9ubmFpcmVzUm91dGUiLCJncm91cFJvdXRlcyIsImdldEdyb3VwUm91dGUiLCJwcmV2aWV3R3JvdXBSb3V0ZXMiLCJzZWFyY2hHcm91cHNSb3V0ZSIsInF1ZXN0aW9uc1JvdXRlIiwidGFnc1NlYXJjaFJvdXRlIiwiZ2V0QWRtaW5TdGF0cyIsImdldFByZXZpb3VzQW5zd2VycyIsImdldFN0YXRzQW5zd2VycyIsInNhdmVBbnN3ZXJzUm91dGUiLCJRdWVzdGlvbm5haXJlIiwidGl0bGUiLCJtYXhsZW5ndGgiLCJyZXF1aXJlZCIsInNsdWciLCJpbnRyb2R1Y3Rpb24iLCJzZWFyY2hRdWVzdGlvbm5haXJlcyIsIkdyb3VwIiwiUXVlc3Rpb24iLCJ0ZXh0IiwicmFuayIsIm1pbiIsImRlZmF1bHRWYWx1ZSIsIkNob2ljZSIsInNlYXJjaCIsInNlYXJjaEdyb3VwcyIsImRpckNhY2hlR3JvdXBzIiwiZGlyQ2FjaGVUYWdzIiwiZGlySFRNTEdyb3VwcyIsImRpckhUTUxOZXdzIiwiZGlySFRNTFRhZ3MiLCJkaXJXZWJHcm91cHMiLCJkaXJXZWJOZXdzIiwiZGlyV2ViVGFncyIsIm5iUmFuZG9tUmVzdWx0cyIsIm5iVGFnc01pbiIsIm5iVGFnc01heCIsInVzZXJSb3V0ZXMiLCJjaGVja0RlbGV0ZUxpbmtSb3V0ZSIsImNoZWNrSWZJc0VtYWlsZnJlZVJvdXRlIiwiY2hlY2tMb2dpblJvdXRlIiwiY2hlY2tOZXdMb2dpbkxpbmtSb3V0ZSIsImNoZWNrU3Vic2NyaWJlVG9rZW5Sb3V0ZSIsImNvbm5lY3Rpb25Sb3V0ZSIsImNvbm5lY3Rpb25XaXRoTGlua1JvdXRlIiwiY3JlYXR