UGATU SDO ANSWERS SCRIPT

Показ верных ответов на сайте СДО УГАТУ!

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         UGATU SDO ANSWERS SCRIPT
// @namespace    https://t.me/+AzlTc2COncJmYzAy
// @version      2.2.3
// @description  Показ верных ответов на сайте СДО УГАТУ!
// @author       GuFFy_OwO
// @match        https://sdo.uust.ru/*
// @icon         https://sdo.uust.ru/pluginfile.php/1/theme_opentechnology/settings_setugatu_header_logoimage/1664187092/Z3_222.png
// @grant        GM_xmlhttpRequest
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ([
/* 0 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const getAnswersData_module_1 = __importDefault(__webpack_require__(1));
const getQuizPercent_module_1 = __importDefault(__webpack_require__(6));
const postQuizzesData_module_1 = __importDefault(__webpack_require__(7));
const responseFormPatch_module_1 = __importDefault(__webpack_require__(8));
const getCmId_util_1 = __importDefault(__webpack_require__(9));
const cmId = (0, getCmId_util_1.default)();
const responseForm = document.getElementById('responseform');
if (cmId && responseForm) {
    (0, responseFormPatch_module_1.default)(cmId, responseForm);
    (0, getAnswersData_module_1.default)(cmId, responseForm);
}
const quizAttemptSummaryTable = document.querySelector('.generaltable.quizattemptsummary');
if (cmId && quizAttemptSummaryTable) {
    (0, getQuizPercent_module_1.default)(cmId, quizAttemptSummaryTable);
    (0, postQuizzesData_module_1.default)();
}


/***/ }),
/* 1 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const getQuestionsData_util_1 = __importDefault(__webpack_require__(2));
const createAnswerTable_module_1 = __importDefault(__webpack_require__(5));
exports["default"] = (cmId, responseForm) => {
    const questionsData = (0, getQuestionsData_util_1.default)(responseForm);
    if (!questionsData)
        return;
    questionsData.forEach((questionData) => {
        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://vernibabki.ru/usatu-sdo-answers/api/v1/getAnswerData',
            data: JSON.stringify({
                cmId,
                question: questionData.question,
                answersOptions: questionData.answersOptions,
            }),
            headers: {
                'Content-Type': 'application/json',
            },
            onload: function (response) {
                if (response) {
                    if (response.status === 200) {
                        (0, createAnswerTable_module_1.default)(JSON.parse(response.responseText), questionData.questionParams);
                    }
                    console.log('Get Answer response =>', response);
                }
            },
        });
    });
};


/***/ }),
/* 2 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const innerHtmlParser_util_1 = __importDefault(__webpack_require__(3));
const questionDataParsers_util_1 = __webpack_require__(4);
exports["default"] = (responseForm) => {
    return Array.from(responseForm.querySelectorAll('div > *[id^="question"]')).reduce((questionsData, questionBlockElement) => {
        var _a;
        const question = (_a = questionBlockElement.querySelector('.qtext')) === null || _a === void 0 ? void 0 : _a.innerHTML;
        if (!question)
            return questionsData;
        const choiceQuestion = (0, questionDataParsers_util_1.choiceQuestionParser)(questionBlockElement);
        const textQuestion = (0, questionDataParsers_util_1.textQuestionParser)(questionBlockElement);
        const matchQuestion = (0, questionDataParsers_util_1.matchQuestionParser)(questionBlockElement);
        const essayQuestion = (0, questionDataParsers_util_1.essayQuestionParser)(questionBlockElement);
        questionsData.push({
            question: (0, innerHtmlParser_util_1.default)(question),
            questionParams: {
                questionId: questionBlockElement.id.split('-')[1],
                questionNumber: questionBlockElement.id.split('-')[2],
            },
            answersOptions: [
                ...choiceQuestion.answersOptions,
                ...textQuestion.answersOptions,
                ...matchQuestion.answersOptions,
                ...essayQuestion.answersOptions,
            ].sort(),
            answers: [
                ...choiceQuestion.answers,
                ...textQuestion.answers,
                ...matchQuestion.answers,
                ...essayQuestion.answers,
            ].sort(),
        });
        return questionsData;
    }, []);
};


/***/ }),
/* 3 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = (innerHTML) => {
    return replaceHtmlEntities(innerHTML
        .replace(/<span class="answernumber">\w. <\/span>/g, '')
        .replace(/<img[^>]+src="([^">]+)".*>/g, '$1')
        .replace(/<\/?[^>]+(>|$)/g, ' ')
        .replace(/\/question\/questiontext\/\d+\/\d+\//g, '/question/questiontext/QUESTIONID/QUESTIONNUMBER/')
        .replace(/\/question\/answer\/\d+\/\d+\//g, '/question/answer/QUESTIONID/QUESTIONNUMBER/'))
        .replace(/\s\s+/g, ' ')
        .trim();
};
const translate_re = /&(nbsp|amp|quot|lt|gt);/g;
const translate = {
    nbsp: ' ',
    amp: '&',
    quot: '"',
    lt: '<',
    gt: '>',
};
const replaceHtmlEntities = (string) => {
    return string.replace(translate_re, (match, entity) => {
        return translate[entity];
    });
};


/***/ }),
/* 4 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.essayQuestionParser = exports.matchQuestionParser = exports.textQuestionParser = exports.choiceQuestionParser = void 0;
const innerHtmlParser_util_1 = __importDefault(__webpack_require__(3));
const arrayToString = (array) => {
    return '[' + array.map((el) => `"${(0, innerHtmlParser_util_1.default)(el.innerHTML)}"`).join(', ') + ']';
};
const choiceQuestionParser = (questionBlockElement) => {
    return Array.from(questionBlockElement.querySelectorAll('.answer input[type="checkbox"], .answer input[type="radio"]')).reduce((result = { answersOptions: [], answers: [] }, item) => {
        if (!item.nextElementSibling)
            return result;
        const innerHTML = (0, innerHtmlParser_util_1.default)(item.nextElementSibling.innerHTML);
        result.answersOptions.push(innerHTML);
        if (item.checked)
            result.answers.push(innerHTML);
        return result;
    }, { answersOptions: [], answers: [] });
};
exports.choiceQuestionParser = choiceQuestionParser;
const textQuestionParser = (questionBlockElement) => {
    return Array.from(questionBlockElement.querySelectorAll('.answer input[type="text"]')).reduce((result = { answersOptions: [], answers: [] }, item) => {
        result.answers.push((0, innerHtmlParser_util_1.default)(item.value));
        return result;
    }, { answersOptions: [], answers: [] });
};
exports.textQuestionParser = textQuestionParser;
const matchQuestionParser = (questionBlockElement) => {
    return Array.from(questionBlockElement.querySelectorAll('.answer select')).reduce((result = { answersOptions: [], answers: [] }, item) => {
        if (!item.parentElement || !item.parentElement.previousElementSibling)
            return result;
        result.answersOptions.push(`${(0, innerHtmlParser_util_1.default)(item.parentElement.previousElementSibling.innerHTML)}: ${arrayToString(Array.from(item.options))}`);
        result.answers.push(`${(0, innerHtmlParser_util_1.default)(item.parentElement.previousElementSibling.innerHTML)}: ${(0, innerHtmlParser_util_1.default)(item.options[item.selectedIndex].innerHTML)}`);
        return result;
    }, { answersOptions: [], answers: [] });
};
exports.matchQuestionParser = matchQuestionParser;
const essayQuestionParser = (questionBlockElement) => {
    return Array.from(questionBlockElement.querySelectorAll('.answer textarea')).reduce((result = { answersOptions: [], answers: [] }, item) => {
        result.answers.push((0, innerHtmlParser_util_1.default)(item.value));
        return result;
    }, { answersOptions: [], answers: [] });
};
exports.essayQuestionParser = essayQuestionParser;


/***/ }),
/* 5 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = (answersData, { questionId, questionNumber }) => {
    const table = document.createElement('table');
    table.classList.add('styled-table');
    const thead = document.createElement('thead');
    const tr = document.createElement('tr');
    const thPercent = document.createElement('th');
    thPercent.textContent = 'Процент';
    thPercent.style.color = 'white';
    const thUsage = document.createElement('th');
    thUsage.textContent = 'Количество использований';
    thUsage.style.color = 'white';
    const thLastUsage = document.createElement('th');
    thLastUsage.textContent = 'Дата последнего использования';
    thLastUsage.style.color = 'white';
    const thAnswer = document.createElement('th');
    thAnswer.textContent = 'Ответ';
    thAnswer.style.color = 'white';
    tr.appendChild(thPercent);
    tr.appendChild(thUsage);
    tr.appendChild(thLastUsage);
    tr.appendChild(thAnswer);
    thead.appendChild(tr);
    table.appendChild(thead);
    const tbody = document.createElement('tbody');
    answersData.forEach((answerData) => {
        const tr = document.createElement('tr');
        const tdPercent = document.createElement('td');
        tdPercent.textContent = answerData.percent ? answerData.percent.toString() : 'Не известен';
        const tdUsage = document.createElement('td');
        tdUsage.textContent = answerData.count.toString();
        const tdLastUsage = document.createElement('td');
        tdLastUsage.textContent = new Date(answerData.updatedAt).toLocaleString('en-GB');
        const tdAnswers = document.createElement('td');
        tdAnswers.textContent = JSON.stringify(answerData._id.map((answer) => answer.replace('QUESTIONID', questionId).replace('QUESTIONNUMBER', questionNumber)));
        tr.appendChild(tdPercent);
        tr.appendChild(tdUsage);
        tr.appendChild(tdLastUsage);
        tr.appendChild(tdAnswers);
        tbody.appendChild(tr);
    });
    table.appendChild(tbody);
    table.style.borderCollapse = 'collapse';
    table.style.margin = '25px auto';
    table.style.fontSize = '0.9em';
    table.style.fontFamily = 'sans-serif';
    table.style.minWidth = '400px';
    table.style.boxShadow = '0 0 20px rgba(0, 0, 0, 0.15)';
    thead.style.backgroundColor = '#009879';
    thead.style.color = '#009879';
    thead.style.textAlign = 'left';
    const ths = tr.querySelectorAll('th');
    const tds = tr.querySelectorAll('td');
    ths.forEach((th) => {
        th.style.padding = '12px 15px';
    });
    tds.forEach((td) => {
        td.style.padding = '12px 15px';
    });
    const trs = tbody.querySelectorAll('tr');
    trs.forEach((tr, index) => {
        if (index % 2 === 0) {
            tr.style.backgroundColor = '#f3f3f3';
        }
        tr.style.borderBottom = '1px solid #dddddd';
    });
    const lastRow = document.querySelector('tr:last-of-type');
    if (lastRow) {
        lastRow.style.borderBottom = '2px solid #009879';
    }
    const activeRow = document.querySelector('.active-row');
    if (activeRow) {
        activeRow.style.fontWeight = 'bold';
        activeRow.style.color = '#009879';
    }
    document.body.appendChild(table);
};


/***/ }),
/* 6 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = (cmId, quizAttemptSummaryTable) => {
    var _a;
    if (!localStorage.quizzesData)
        localStorage.quizzesData = JSON.stringify({});
    const quizzesData = JSON.parse(localStorage.quizzesData);
    const rateColumn = quizAttemptSummaryTable.querySelectorAll('td.cell.c2');
    const score = rateColumn[rateColumn.length - 1].innerHTML.replace(',', '.');
    const rateHeader = (_a = quizAttemptSummaryTable.querySelector('th.header.c2')) === null || _a === void 0 ? void 0 : _a.textContent;
    if (!rateHeader)
        return "Can't find rate header";
    const maxScoreRegexp = rateHeader.match(/\d+,\d+/);
    if (!maxScoreRegexp)
        return "Can't find max score";
    const maxScore = maxScoreRegexp[0].replace(',', '.');
    const percent = (parseFloat(score) / parseFloat(maxScore)) * 100;
    if (!Object.keys(quizzesData).includes(cmId)) {
        return "Can't find quiz data, maybe you haven't passed the quiz";
    }
    else if (score === '') {
        return "Can't find score, quiz is not finished";
    }
    else if (score === 'Еще не оценено') {
        quizzesData[cmId].percent = undefined;
    }
    else if (!isNaN(percent)) {
        quizzesData[cmId].percent = percent;
    }
    else {
        return "Can't parse score, table is broken";
    }
    localStorage.quizzesData = JSON.stringify(quizzesData);
};


/***/ }),
/* 7 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = () => {
    if (!localStorage.quizzesData)
        localStorage.quizzesData = JSON.stringify({});
    const quizzesData = JSON.parse(localStorage.quizzesData);
    Object.keys(quizzesData).forEach((cmId) => {
        if (quizzesData[cmId].percent === null)
            return `Quiz with cmId ${cmId} is not finished`;
        GM_xmlhttpRequest({
            method: 'POST',
            url: 'https://vernibabki.ru/usatu-sdo-answers/api/v1/postQuizData',
            data: JSON.stringify({
                cmId,
                percent: quizzesData[cmId].percent,
                questionsData: quizzesData[cmId].questionsData,
            }),
            headers: {
                'Content-Type': 'application/json',
            },
            onload: function (response) {
                if (response && response.status !== 429) {
                    delete quizzesData[cmId];
                    localStorage.quizzesData = JSON.stringify(quizzesData);
                }
                console.log('Post Quiz Data response =>', response);
            },
        });
    });
};


/***/ }),
/* 8 */
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const getQuestionsData_util_1 = __importDefault(__webpack_require__(2));
exports["default"] = (cmId, responseForm) => {
    responseForm.addEventListener('submit', () => {
        if (!localStorage.quizzesData)
            localStorage.quizzesData = JSON.stringify({});
        const quizzesData = JSON.parse(localStorage.quizzesData);
        if (!quizzesData[cmId]) {
            quizzesData[cmId] = {
                percent: null,
                questionsData: [],
            };
        }
        const quizData = quizzesData[cmId];
        const questionsData = (0, getQuestionsData_util_1.default)(responseForm);
        if (!questionsData)
            return "Can't get questions data";
        questionsData.forEach((questionData) => {
            const foundedQuestionData = quizData.questionsData.find((item) => item.question === questionData.question &&
                JSON.stringify(item.answersOptions) === JSON.stringify(questionData.answersOptions));
            if (foundedQuestionData) {
                foundedQuestionData.answers = questionData.answers;
            }
            else {
                quizData.questionsData.push(questionData);
            }
        });
        localStorage.quizzesData = JSON.stringify(quizzesData);
    });
};


/***/ }),
/* 9 */
/***/ ((__unused_webpack_module, exports) => {


Object.defineProperty(exports, "__esModule", ({ value: true }));
exports["default"] = () => {
    var _a;
    return (_a = Array.from(document.body.classList)
        .find((className) => className.includes('cmid-'))) === null || _a === void 0 ? void 0 : _a.split('-')[1];
};


/***/ })
/******/ 	]);
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/************************************************************************/
/******/
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module is referenced by other modules so it can't be inlined
/******/ 	var __webpack_exports__ = __webpack_require__(0);
/******/
/******/ })()
;