update
This commit is contained in:
parent
d138738e24
commit
275c572d90
@ -116,7 +116,7 @@ for filename in md_filenames:
|
|||||||
"id": code,
|
"id": code,
|
||||||
"index": index,
|
"index": index,
|
||||||
"isFirst": index == 0,
|
"isFirst": index == 0,
|
||||||
"isLast": index == len(md_filenames) - 1,
|
"isLast": position == len(subjects[subject_index]),
|
||||||
"title": subjects[subject_index][index],
|
"title": subjects[subject_index][index],
|
||||||
"subject": subject_index,
|
"subject": subject_index,
|
||||||
"files": [{"filename": filename, "version": version}],
|
"files": [{"filename": filename, "version": version}],
|
||||||
|
|||||||
@ -47,7 +47,7 @@
|
|||||||
"id": "F0_55",
|
"id": "F0_55",
|
||||||
"index": 54,
|
"index": 54,
|
||||||
"isFirst": false,
|
"isFirst": false,
|
||||||
"isLast": false,
|
"isLast": true,
|
||||||
"title": "Алергия. Алергични заболявания. Анафилактичен шок. Поведение на медицинската сестра при спешни алергични състояния.",
|
"title": "Алергия. Алергични заболявания. Анафилактичен шок. Поведение на медицинската сестра при спешни алергични състояния.",
|
||||||
"subject": 0,
|
"subject": 0,
|
||||||
"files": [
|
"files": [
|
||||||
@ -1102,7 +1102,7 @@
|
|||||||
"id": "F1_21",
|
"id": "F1_21",
|
||||||
"index": 20,
|
"index": 20,
|
||||||
"isFirst": false,
|
"isFirst": false,
|
||||||
"isLast": false,
|
"isLast": true,
|
||||||
"title": "Лекарствени средства, действащи върху храносмилателната система – апетитостимулиращи, апетитопотискащи (анорексигенни), противоповръщащи (антиеметични), противоязвени (антиулкусни).",
|
"title": "Лекарствени средства, действащи върху храносмилателната система – апетитостимулиращи, апетитопотискащи (анорексигенни), противоповръщащи (антиеметични), противоязвени (антиулкусни).",
|
||||||
"subject": 1,
|
"subject": 1,
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@ -30,6 +30,92 @@ export function TitleIcon({ className }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function JustifyTextIcon({ className }) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className={className}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
height="24px"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24px"
|
||||||
|
fill="inherit"
|
||||||
|
>
|
||||||
|
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||||
|
<path d="M14 17H4v2h10v-2zm6-8H4v2h16V9zM4 15h16v-2H4v2zM4 5v2h16V5H4z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TextIncreaseIcon({ className }) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className={className}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
enableBackground="new 0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24px"
|
||||||
|
fill="inherit"
|
||||||
|
>
|
||||||
|
<rect fill="none" height="24" width="24" />
|
||||||
|
<path d="M0.99,19h2.42l1.27-3.58h5.65L11.59,19h2.42L8.75,5h-2.5L0.99,19z M5.41,13.39L7.44,7.6h0.12l2.03,5.79H5.41z M20,11h3v2h-3 v3h-2v-3h-3v-2h3V8h2V11z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TextDecreaseIcon({ className }) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className={className}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
enableBackground="new 0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24px"
|
||||||
|
fill="inherit"
|
||||||
|
>
|
||||||
|
<rect fill="none" height="24" width="24" />
|
||||||
|
<path d="M0.99,19h2.42l1.27-3.58h5.65L11.59,19h2.42L8.75,5h-2.5L0.99,19z M5.41,13.39L7.44,7.6h0.12l2.03,5.79H5.41z M23,11v2h-8 v-2H23z" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function HRuleIcon({ className }) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className={className}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
enable-background="new 0 0 24 24"
|
||||||
|
height="24px"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="8px"
|
||||||
|
fill="inherit"
|
||||||
|
>
|
||||||
|
<g>
|
||||||
|
<rect fill="none" fill-rule="evenodd" height="24" width="24" />
|
||||||
|
<g>
|
||||||
|
<rect fill-rule="evenodd" height="2" width="16" x="4" y="11" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VRuleIcon({ className = "" }) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className={`rotate-90 ${className}`}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
height="24px"
|
||||||
|
viewBox="0 0 8 24" // Match the 8px width
|
||||||
|
width="8px"
|
||||||
|
fill="inherit"
|
||||||
|
>
|
||||||
|
<rect fillRule="evenodd" height="2" width="8" x="0" y="11" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function EllipsisIcon({ className = "" }) {
|
export function EllipsisIcon({ className = "" }) {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
|
|||||||
@ -14,6 +14,10 @@ import {
|
|||||||
WidthIcon,
|
WidthIcon,
|
||||||
EllipsisIcon,
|
EllipsisIcon,
|
||||||
CloseIcon,
|
CloseIcon,
|
||||||
|
JustifyTextIcon,
|
||||||
|
TextIncreaseIcon,
|
||||||
|
TextDecreaseIcon,
|
||||||
|
VRuleIcon,
|
||||||
} from "./icons/Icons";
|
} from "./icons/Icons";
|
||||||
|
|
||||||
createRoot(document.getElementById("root")).render(
|
createRoot(document.getElementById("root")).render(
|
||||||
@ -72,7 +76,9 @@ export function TopicListView() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex-1 overflow-y-scroll pb-[156px]">
|
<div
|
||||||
|
className={`flex-1 overflow-y-scroll ${selectedTopic === null ? "pb-[92px]" : "pb-[156px]"}`}
|
||||||
|
>
|
||||||
{topics.map((topic, i) => (
|
{topics.map((topic, i) => (
|
||||||
<Link
|
<Link
|
||||||
key={topic.id}
|
key={topic.id}
|
||||||
@ -96,7 +102,7 @@ export function TopicListView() {
|
|||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute bottom-0 p-4 pb-6 w-full flex flex-col">
|
<div className="absolute bottom-0 p-4 w-full flex flex-col">
|
||||||
<div className="ml-auto p-2 flex space-x-1 h-[60px]">
|
<div className="ml-auto p-2 flex space-x-1 h-[60px]">
|
||||||
<button
|
<button
|
||||||
className={`cursor-pointer p-2 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
className={`cursor-pointer p-2 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
||||||
@ -164,7 +170,7 @@ export function TopicListView() {
|
|||||||
{selectedTopic !== null && (
|
{selectedTopic !== null && (
|
||||||
<Link
|
<Link
|
||||||
to={`/${selectedTopic.id}`}
|
to={`/${selectedTopic.id}`}
|
||||||
className="w-full p-2 bg-blue-600 hover:bg-blue-700 cursor-pointer truncate rounded-md text-sm text-white text-center shadow-md transition-colors"
|
className="w-full p-2 mb-2 bg-blue-600 hover:bg-blue-700 cursor-pointer truncate rounded-md text-sm text-white text-center shadow-md transition-colors"
|
||||||
>
|
>
|
||||||
<span>Продължи четенето:</span>
|
<span>Продължи четенето:</span>
|
||||||
<br />
|
<br />
|
||||||
@ -208,24 +214,59 @@ export function Reader({ topic }) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<PDFViewer file={topic.files[selectedVersion]} compact={config.narrowMode} />
|
<PDFViewer
|
||||||
|
file={topic.files[selectedVersion]}
|
||||||
|
compact={config.narrowMode}
|
||||||
|
justifyText={config.justifyText}
|
||||||
|
/>
|
||||||
<div className="absolute bottom-10 flex justify-between px-4 py-2 w-full z-999">
|
<div className="absolute bottom-10 flex justify-between px-4 py-2 w-full z-999">
|
||||||
<div className="flex w-full space-x-2">
|
<div className="flex w-full space-x-2">
|
||||||
<Link to="/" className="cursor-pointer p-2 rounded-full bg-blue-600 text-white mr-auto">
|
<Link to="/" className="cursor-pointer p-2 rounded-full bg-blue-600 text-white mr-auto">
|
||||||
<MenuBookIcon className="fill-gray-100" />
|
<MenuBookIcon className="fill-gray-100" />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-1">
|
<div className="flex items-center">
|
||||||
|
<div className="text-sm text-gray-600 rounded bg-gray-300/30 backdrop-blur px-2">
|
||||||
|
{config.contentZoomLevel}%
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={`cursor-pointer p-2 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
className={`cursor-pointer p-2 mx-1 rounded-full text-white bg-gray-100/30 backdrop-blur`}
|
||||||
|
onClick={() =>
|
||||||
|
changeConfig({ contentZoomLevel: Math.max(50, config.contentZoomLevel - 10) })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<TextDecreaseIcon className="fill-gray-600" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`cursor-pointer p-2 rounded-full text-white bg-gray-100/30 backdrop-blur`}
|
||||||
|
onClick={() => {
|
||||||
|
changeConfig({ contentZoomLevel: Math.min(150, config.contentZoomLevel + 10) });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextIncreaseIcon className="fill-gray-600" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<VRuleIcon className="fill-gray-300" />
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`cursor-pointer p-2 mr-1 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
||||||
onClick={() => changeConfig({ displayTitle: !config.displayTitle })}
|
onClick={() => changeConfig({ displayTitle: !config.displayTitle })}
|
||||||
>
|
>
|
||||||
<TitleIcon className="fill-gray-600" />
|
<TitleIcon className="fill-gray-600" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`cursor-pointer p-2 mr-1 rounded-full text-white border ${config.justifyText ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
||||||
|
onClick={() => changeConfig({ justifyText: !config.justifyText })}
|
||||||
|
>
|
||||||
|
<JustifyTextIcon className="fill-gray-600" />
|
||||||
|
</button>
|
||||||
|
|
||||||
{window.innerWidth > 576 && (
|
{window.innerWidth > 576 && (
|
||||||
<button
|
<button
|
||||||
className={`cursor-pointer p-2 rounded-full text-white border ${config.narrowMode ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
className={`cursor-pointer p-2 mr-1 rounded-full text-white border ${config.narrowMode ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
||||||
onClick={() => changeConfig({ narrowMode: !config.narrowMode })}
|
onClick={() => changeConfig({ narrowMode: !config.narrowMode })}
|
||||||
>
|
>
|
||||||
<WidthIcon className="fill-gray-600" />
|
<WidthIcon className="fill-gray-600" />
|
||||||
@ -308,7 +349,8 @@ export function Reader({ topic }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PDFViewer({ file, compact }) {
|
export function PDFViewer({ file, compact, justifyText }) {
|
||||||
|
const iframeRef = useRef(null);
|
||||||
const [content, setContent] = useState(null);
|
const [content, setContent] = useState(null);
|
||||||
const htmlContent = useMemo(() => {
|
const htmlContent = useMemo(() => {
|
||||||
const fileContent = `
|
const fileContent = `
|
||||||
@ -330,12 +372,18 @@ export function PDFViewer({ file, compact }) {
|
|||||||
padding: 0 12px 40px;
|
padding: 0 12px 40px;
|
||||||
${compact ? "max-width: 36rem; margin: 0 auto;" : ""}
|
${compact ? "max-width: 36rem; margin: 0 auto;" : ""}
|
||||||
}
|
}
|
||||||
p {
|
${
|
||||||
text-align: justify;
|
justifyText
|
||||||
text-justify: inter-word;
|
? `
|
||||||
}
|
p {
|
||||||
pre, code {
|
text-align: justify;
|
||||||
font-family: 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
text-justify: inter-word;
|
||||||
|
}
|
||||||
|
pre, code {
|
||||||
|
font-family: 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
: ""
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@ -345,10 +393,18 @@ export function PDFViewer({ file, compact }) {
|
|||||||
</html>
|
</html>
|
||||||
`;
|
`;
|
||||||
return fileContent;
|
return fileContent;
|
||||||
}, [content, compact]);
|
}, [content, compact, justifyText]);
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
|
const contentZoomLevel = useStore((state) => state.config.contentZoomLevel);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (iframeRef.current && iframeRef.current.contentDocument) {
|
||||||
|
iframeRef.current.contentDocument.body.style.zoom = `${contentZoomLevel}%`;
|
||||||
|
}
|
||||||
|
}, [contentZoomLevel]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchFile = async () => {
|
const fetchFile = async () => {
|
||||||
try {
|
try {
|
||||||
@ -387,11 +443,17 @@ export function PDFViewer({ file, compact }) {
|
|||||||
return (
|
return (
|
||||||
<div className={`w-full h-full overflow-hidden`}>
|
<div className={`w-full h-full overflow-hidden`}>
|
||||||
<iframe
|
<iframe
|
||||||
|
ref={iframeRef}
|
||||||
srcDoc={htmlContent}
|
srcDoc={htmlContent}
|
||||||
title={`File: ${file}`}
|
title={`File: ${file}`}
|
||||||
className="w-full h-full border-0"
|
className="w-full h-full border-0"
|
||||||
key={file}
|
key={file}
|
||||||
allow="fullscreen"
|
allow="fullscreen"
|
||||||
|
onLoad={() => {
|
||||||
|
if (iframeRef.current?.contentDocument?.body) {
|
||||||
|
iframeRef.current.contentDocument.body.style.zoom = `${contentZoomLevel}%`;
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,326 +0,0 @@
|
|||||||
import { StrictMode, useLayoutEffect, useRef, useState, useEffect } from "react";
|
|
||||||
import { createRoot } from "react-dom/client";
|
|
||||||
import { useParams, Navigate, BrowserRouter, Link, Outlet, Route, Routes } from "react-router";
|
|
||||||
import "./index.css";
|
|
||||||
import { useShallow } from "zustand/shallow";
|
|
||||||
import { useStore } from "./store.js";
|
|
||||||
import {
|
|
||||||
ArrowBackIcon,
|
|
||||||
ArrowForwardIcon,
|
|
||||||
MenuBookIcon,
|
|
||||||
MyLocationIcon,
|
|
||||||
TitleIcon,
|
|
||||||
WidthIcon,
|
|
||||||
} from "./icons/Icons";
|
|
||||||
|
|
||||||
createRoot(document.getElementById("root")).render(
|
|
||||||
<StrictMode>
|
|
||||||
<BrowserRouter>
|
|
||||||
<Routes>
|
|
||||||
<Route path="/" element={<Layout />}>
|
|
||||||
<Route index element={<TopicListView />} />
|
|
||||||
<Route path=":topicId" element={<FileReader />} />
|
|
||||||
</Route>
|
|
||||||
</Routes>
|
|
||||||
</BrowserRouter>
|
|
||||||
</StrictMode>,
|
|
||||||
);
|
|
||||||
|
|
||||||
function Layout() {
|
|
||||||
const params = useParams();
|
|
||||||
const topic = useStore((state) => params.topicId && state.topics.byId[params.topicId]);
|
|
||||||
const config = useStore((state) => state.config);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="max-w-7xl mx-auto h-full relative flex flex-col">
|
|
||||||
{config.displayTitle && (
|
|
||||||
<div className="w-full px-4 py-2 font-medium text-large text-white bg-blue-600">
|
|
||||||
<span>{topic ? `${topic.index + 1}: ${topic.title}` : "Конспект за Държавен Изпит"}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function TopicListView() {
|
|
||||||
const itemRefs = useRef({});
|
|
||||||
const topics = useStore(
|
|
||||||
useShallow((state) => state.topics.allIds.map((id) => state.topics.byId[id])),
|
|
||||||
);
|
|
||||||
const selectedTopic = useStore((state) => state.selectedTopic);
|
|
||||||
const selectTopic = useStore((state) => state.selectTopic);
|
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (selectedTopic && selectedTopic.id !== null) {
|
|
||||||
itemRefs.current?.[Math.max(selectedTopic.index - 3, 0)].scrollIntoView();
|
|
||||||
}
|
|
||||||
}, [selectedTopic]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="flex-1 overflow-y-scroll">
|
|
||||||
{topics.map((topic, i) => (
|
|
||||||
<Link
|
|
||||||
key={topic.id}
|
|
||||||
ref={(node) => {
|
|
||||||
itemRefs.current[i] = node;
|
|
||||||
}}
|
|
||||||
to={`/${topic.id}`}
|
|
||||||
onClick={() => selectTopic(topic.id)}
|
|
||||||
className={`flex px-2 py-1 rounded-md cursor-pointer border-l-4 ${topic.id === selectedTopic?.id ? "bg-blue-100 border-blue-500" : "border-transparent hover:bg-gray-100"}`}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={`w-6 flex-shrink-0 flex font-medium justify-end ${topic.id === selectedTopic?.id ? "text-blue-600" : "text-blue-800"}`}
|
|
||||||
>
|
|
||||||
{i + 1}
|
|
||||||
</div>
|
|
||||||
<span className="ml-2">
|
|
||||||
<span
|
|
||||||
className={`leading-5 ${topic.id === selectedTopic?.id ? "font-medium" : "font-normal"}`}
|
|
||||||
>
|
|
||||||
{topic.title}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
{selectedTopic !== null && (
|
|
||||||
<div className="sticky bottom-0 p-4 w-full flex flex-col">
|
|
||||||
<div className="w-full flex justify-between items-center gap-2">
|
|
||||||
<Link
|
|
||||||
to={`/${selectedTopic.id}`}
|
|
||||||
className="w-full p-2 bg-blue-600 hover:bg-blue-700 cursor-pointer truncate rounded-md text-sm text-white text-center shadow-md transition-colors"
|
|
||||||
>
|
|
||||||
<span>Продължи четенето:</span>
|
|
||||||
<br />
|
|
||||||
<span className="font-medium">{selectedTopic.title}</span>
|
|
||||||
</Link>
|
|
||||||
<button
|
|
||||||
className="px-3 py-3 bg-teal-500 hover:bg-teal-300 cursor-pointer rounded-full flex items-center justify-center shadow-md transition-colors"
|
|
||||||
onClick={() => {
|
|
||||||
itemRefs.current?.[Math.max(selectedTopic.index - 3, 0)].scrollIntoView({
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MyLocationIcon className="h-5 w-5" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function FileReader() {
|
|
||||||
const params = useParams();
|
|
||||||
const topicsById = useStore((state) => state.topics.byId);
|
|
||||||
const selectTopic = useStore((state) => state.selectTopic);
|
|
||||||
|
|
||||||
const topic = topicsById[params.topicId];
|
|
||||||
if (!topic) {
|
|
||||||
return <Navigate to="/" replace />;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectTopic(topic.id);
|
|
||||||
|
|
||||||
return <Reader topic={topic} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Reader({ topic }) {
|
|
||||||
console.log("render!");
|
|
||||||
const config = useStore((state) => state.config);
|
|
||||||
const changeConfig = useStore((state) => state.changeConfig);
|
|
||||||
const selectedVersion = useStore((state) => state.topicVersions[topic.id] ?? 0);
|
|
||||||
const selectVersion = useStore((state) => state.selectTopicVersion);
|
|
||||||
const getTopicAtIndex = useStore((state) => state.getTopicAtIndex);
|
|
||||||
|
|
||||||
const prevTopic = getTopicAtIndex(topic.index - 1);
|
|
||||||
const nextTopic = getTopicAtIndex(topic.index + 1);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="flex-1">
|
|
||||||
<PDFViewer file={topic.files[selectedVersion]} compact={config.narrowMode} />
|
|
||||||
<div className="absolute bottom-10 flex justify-between px-4 py-2 w-full z-999">
|
|
||||||
<div className="flex space-x-2">
|
|
||||||
<Link to="/" className="cursor-pointer p-2 rounded-full bg-blue-600 text-white">
|
|
||||||
<MenuBookIcon className="fill-gray-100" />
|
|
||||||
</Link>
|
|
||||||
<button
|
|
||||||
className={`cursor-pointer p-2 rounded-full text-white border ${config.displayTitle ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
|
||||||
onClick={() => changeConfig({ displayTitle: !config.displayTitle })}
|
|
||||||
>
|
|
||||||
<TitleIcon className="fill-gray-600" />
|
|
||||||
</button>
|
|
||||||
{window.innerWidth > 576 && (
|
|
||||||
<button
|
|
||||||
className={`cursor-pointer p-2 rounded-full text-white border ${config.narrowMode ? "bg-blue-100 border-blue-400" : "bg-gray-100 border-gray-400"}`}
|
|
||||||
onClick={() => changeConfig({ narrowMode: !config.narrowMode })}
|
|
||||||
>
|
|
||||||
<WidthIcon className="fill-gray-600" />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{topic.files.length > 1 && (
|
|
||||||
<div className="flex space-x-1">
|
|
||||||
{topic.files.map((file, vIndex) => (
|
|
||||||
<button
|
|
||||||
key={file}
|
|
||||||
className={`flex-1 cursor-pointer px-2 py-1 rounded-md text-xs whitespace-nowrap ${
|
|
||||||
selectedVersion === vIndex
|
|
||||||
? "bg-blue-100 text-blue-800 font-medium"
|
|
||||||
: "bg-gray-100 hover:bg-gray-200"
|
|
||||||
}`}
|
|
||||||
onClick={() => selectVersion(topic.id, vIndex)}
|
|
||||||
>
|
|
||||||
Версия {vIndex + 1}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full flex flex-col space-y-2">
|
|
||||||
<div className="flex bg-gray-100 border-t border-blue-200 text-center">
|
|
||||||
{topic.isFirst ? (
|
|
||||||
<div className="flex-1 border-r border-blue-200" />
|
|
||||||
) : (
|
|
||||||
<Link
|
|
||||||
to={`/${prevTopic.id}`}
|
|
||||||
className="border-r border-blue-200 w-1/2 flex-1 px-4 py-2 hover:bg-blue-200 cursor-pointer flex align-center justify-start"
|
|
||||||
>
|
|
||||||
<ArrowBackIcon />
|
|
||||||
<span className="ml-2 truncate w-full ">
|
|
||||||
{prevTopic.index + 1}: {prevTopic.title}
|
|
||||||
</span>
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
{topic.isLast ? (
|
|
||||||
<div className="flex-1" />
|
|
||||||
) : (
|
|
||||||
<Link
|
|
||||||
to={`/${nextTopic.id}`}
|
|
||||||
className="flex-1 px-4 py-2 hover:bg-blue-200 w-1/2 cursor-pointer flex align-center justify-end"
|
|
||||||
>
|
|
||||||
<span className="mr-2 w-full truncate">
|
|
||||||
{nextTopic.index + 1}: {nextTopic.title}
|
|
||||||
</span>
|
|
||||||
<ArrowForwardIcon />
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PDFViewer({ file, compact }) {
|
|
||||||
const [content, setContent] = useState(null);
|
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
|
||||||
const [error, setError] = useState(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const fetchFile = async () => {
|
|
||||||
try {
|
|
||||||
setIsLoading(true);
|
|
||||||
const response = await fetch(`/files_html/${file}`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to load file: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let fileContent = await response.text();
|
|
||||||
|
|
||||||
// If no head tag, add a basic HTML structure with fonts
|
|
||||||
fileContent = `
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap">
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: #333;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
padding-bottom: 40px;
|
|
||||||
}
|
|
||||||
pre, code {
|
|
||||||
font-family: 'SF Mono', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${fileContent}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
|
|
||||||
setContent(fileContent);
|
|
||||||
setError(null);
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Error loading file:", err);
|
|
||||||
setError(err.message);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchFile();
|
|
||||||
}, [file]);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return <div className="text-red-500 p-4 border border-red-300 rounded">Error: {error}</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLoading) {
|
|
||||||
return <DelayedLoader />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`w-full h-full overflow-hidden ${compact ? "max-w-xl mx-auto" : ""}`}>
|
|
||||||
<iframe
|
|
||||||
srcDoc={content}
|
|
||||||
title={`File: ${file}`}
|
|
||||||
className="w-full h-full border-0"
|
|
||||||
key={file}
|
|
||||||
allow="fullscreen"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const DelayedLoader = ({
|
|
||||||
delayMs = 2000,
|
|
||||||
className = "p-4 flex justify-center items-center h-40",
|
|
||||||
text = "Loading...",
|
|
||||||
}) => {
|
|
||||||
const [showLoader, setShowLoader] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Set a timeout to show the loader after the specified delay
|
|
||||||
const timer = setTimeout(() => {
|
|
||||||
setShowLoader(true);
|
|
||||||
}, delayMs);
|
|
||||||
|
|
||||||
// Clear the timeout on unmount
|
|
||||||
return () => clearTimeout(timer);
|
|
||||||
}, []); // Empty dependency array - only run on mount
|
|
||||||
|
|
||||||
// Only render if the delay has passed
|
|
||||||
if (showLoader) {
|
|
||||||
return (
|
|
||||||
<div className={className}>
|
|
||||||
<div className="animate-pulse">{text}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return null before delay threshold
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
@ -1,10 +1,15 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import structure from "./topics.json";
|
import structure from "./topics.json";
|
||||||
|
|
||||||
|
const localSubject = localStorage.getItem("subject") || 0;
|
||||||
|
|
||||||
export const useStore = create((set, get) => ({
|
export const useStore = create((set, get) => ({
|
||||||
subject: 0,
|
subject: localSubject,
|
||||||
selectSubject: (id) => set({ subject: id, topics: structure[id] }),
|
selectSubject: (id) => {
|
||||||
topics: structure[0],
|
set({ subject: id, topics: structure[id] });
|
||||||
|
localStorage.setItem("subject", id);
|
||||||
|
},
|
||||||
|
topics: structure[localSubject],
|
||||||
topicVersions: {},
|
topicVersions: {},
|
||||||
getTopicAtIndex: (index) => {
|
getTopicAtIndex: (index) => {
|
||||||
const topicId = get().topics.allIds[index];
|
const topicId = get().topics.allIds[index];
|
||||||
@ -22,10 +27,25 @@ export const useStore = create((set, get) => ({
|
|||||||
set({ selectedTopic: topic });
|
set({ selectedTopic: topic });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
config: {
|
config: getLocalConfig(),
|
||||||
|
changeConfig: (config) => {
|
||||||
|
const newConfig = { ...get().config, ...config };
|
||||||
|
set({ config: newConfig });
|
||||||
|
|
||||||
|
localStorage.setItem("config", JSON.stringify(newConfig));
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
function getLocalConfig() {
|
||||||
|
const defaultConfig = {
|
||||||
displayTitle: true,
|
displayTitle: true,
|
||||||
wrapTopicTitles: false,
|
wrapTopicTitles: false,
|
||||||
narrowMode: true,
|
narrowMode: true,
|
||||||
},
|
justifyText: false,
|
||||||
changeConfig: (config) => set({ config: { ...get().config, ...config } }),
|
contentZoomLevel: 100,
|
||||||
}));
|
};
|
||||||
|
const config_str = localStorage.getItem("config");
|
||||||
|
const config = config_str ? JSON.parse(config_str) : {};
|
||||||
|
|
||||||
|
return { ...defaultConfig, ...config };
|
||||||
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@
|
|||||||
"id": "F0_55",
|
"id": "F0_55",
|
||||||
"index": 54,
|
"index": 54,
|
||||||
"isFirst": false,
|
"isFirst": false,
|
||||||
"isLast": false,
|
"isLast": true,
|
||||||
"title": "Алергия. Алергични заболявания. Анафилактичен шок. Поведение на медицинската сестра при спешни алергични състояния.",
|
"title": "Алергия. Алергични заболявания. Анафилактичен шок. Поведение на медицинската сестра при спешни алергични състояния.",
|
||||||
"subject": 0,
|
"subject": 0,
|
||||||
"files": [
|
"files": [
|
||||||
@ -1102,7 +1102,7 @@
|
|||||||
"id": "F1_21",
|
"id": "F1_21",
|
||||||
"index": 20,
|
"index": 20,
|
||||||
"isFirst": false,
|
"isFirst": false,
|
||||||
"isLast": false,
|
"isLast": true,
|
||||||
"title": "Лекарствени средства, действащи върху храносмилателната система – апетитостимулиращи, апетитопотискащи (анорексигенни), противоповръщащи (антиеметични), противоязвени (антиулкусни).",
|
"title": "Лекарствени средства, действащи върху храносмилателната система – апетитостимулиращи, апетитопотискащи (анорексигенни), противоповръщащи (антиеметични), противоязвени (антиулкусни).",
|
||||||
"subject": 1,
|
"subject": 1,
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@ -1,714 +0,0 @@
|
|||||||
{
|
|
||||||
"byId": {
|
|
||||||
"a4d9fa36-8ed7-4d80-a108-eac209ca01a8": {
|
|
||||||
"id": "a4d9fa36-8ed7-4d80-a108-eac209ca01a8",
|
|
||||||
"title": "Предмет и задачи на вътрешната медицина. Раздели на вътрешните болести",
|
|
||||||
"files": [
|
|
||||||
"f001.html"
|
|
||||||
],
|
|
||||||
"index": 0,
|
|
||||||
"isFirst": true,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"f7fed0c0-15d9-439c-a3ef-24cec673dd44": {
|
|
||||||
"id": "f7fed0c0-15d9-439c-a3ef-24cec673dd44",
|
|
||||||
"title": "Тумори на белия дроб",
|
|
||||||
"files": [
|
|
||||||
"f002.html"
|
|
||||||
],
|
|
||||||
"index": 1,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"b20a76c0-59a1-4f0a-bb33-39c4bf437eac": {
|
|
||||||
"id": "b20a76c0-59a1-4f0a-bb33-39c4bf437eac",
|
|
||||||
"title": "Белодробен тромбоемболизъм",
|
|
||||||
"files": [
|
|
||||||
"f003.html",
|
|
||||||
"f096.html"
|
|
||||||
],
|
|
||||||
"index": 2,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"a2a3a830-9f1d-4dd0-ab52-c42ae66c17b3": {
|
|
||||||
"id": "a2a3a830-9f1d-4dd0-ab52-c42ae66c17b3",
|
|
||||||
"title": "Плеврити",
|
|
||||||
"files": [
|
|
||||||
"f004.html",
|
|
||||||
"f097.html"
|
|
||||||
],
|
|
||||||
"index": 3,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"38899f8f-2291-4923-ae59-928181c88bbd": {
|
|
||||||
"id": "38899f8f-2291-4923-ae59-928181c88bbd",
|
|
||||||
"title": "Белодробна туберколоза-етиология, патогенеза, и клинична картина. Първична и вторична ТБК. Лечение и профилактика на туберкулоза",
|
|
||||||
"files": [
|
|
||||||
"f005.html",
|
|
||||||
"f098.html"
|
|
||||||
],
|
|
||||||
"index": 4,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"b0460271-a4e2-4e82-a7ea-0f98689fcbb6": {
|
|
||||||
"id": "b0460271-a4e2-4e82-a7ea-0f98689fcbb6",
|
|
||||||
"title": "Дихателна недостатъчност",
|
|
||||||
"files": [
|
|
||||||
"f006.html"
|
|
||||||
],
|
|
||||||
"index": 5,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"9db34720-4756-4469-bbf0-1666d4b6c65f": {
|
|
||||||
"id": "9db34720-4756-4469-bbf0-1666d4b6c65f",
|
|
||||||
"title": "Основни симптоми и синдроми при заболявания на ССС Физикални и специални методи на изследване на ССС",
|
|
||||||
"files": [
|
|
||||||
"f007.html",
|
|
||||||
"f031.html"
|
|
||||||
],
|
|
||||||
"index": 6,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"c12799f8-63d2-4d76-88b9-e0fa68def5a4": {
|
|
||||||
"id": "c12799f8-63d2-4d76-88b9-e0fa68def5a4",
|
|
||||||
"title": "Болест и здраве. Етилогия и патогенеза на болестите. Периоди на болестта",
|
|
||||||
"files": [
|
|
||||||
"f008.html"
|
|
||||||
],
|
|
||||||
"index": 7,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"c200281a-d2cd-4ca6-b6d3-114db5753fc5": {
|
|
||||||
"id": "c200281a-d2cd-4ca6-b6d3-114db5753fc5",
|
|
||||||
"title": "Болести на надбъбречните жлези: Хиперкортицизъм. Хипокортицизъм",
|
|
||||||
"files": [
|
|
||||||
"f009.html",
|
|
||||||
"f047.html"
|
|
||||||
],
|
|
||||||
"index": 8,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"f191d184-a26f-41aa-b213-ead39c22f4c1": {
|
|
||||||
"id": "f191d184-a26f-41aa-b213-ead39c22f4c1",
|
|
||||||
"title": "Агония. Клинична смърт. Биологична смърт",
|
|
||||||
"files": [
|
|
||||||
"f010.html"
|
|
||||||
],
|
|
||||||
"index": 9,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"6b01e219-49d9-4ced-ae83-0e21a6cba53c": {
|
|
||||||
"id": "6b01e219-49d9-4ced-ae83-0e21a6cba53c",
|
|
||||||
"title": "Физикални методи на изследване на стомашно-чревния тракт",
|
|
||||||
"files": [
|
|
||||||
"f011.html"
|
|
||||||
],
|
|
||||||
"index": 10,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"bc201e49-52a3-42da-b47a-ed786576b377": {
|
|
||||||
"id": "bc201e49-52a3-42da-b47a-ed786576b377",
|
|
||||||
"title": "Основни симптоми и синдроми при заболявания на отделителната система. Функционално изследване на ОС",
|
|
||||||
"files": [
|
|
||||||
"f012.html"
|
|
||||||
],
|
|
||||||
"index": 11,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"1d71aeff-1637-493f-93ae-c7126367528c": {
|
|
||||||
"id": "1d71aeff-1637-493f-93ae-c7126367528c",
|
|
||||||
"title": "Основни класически методи на изследване във вътрешната медицина-анамнеза. Физикални методи на изследване на болните –оглед, палпация, перкусия, аускултация. Специални методи на изследване на пациентите",
|
|
||||||
"files": [
|
|
||||||
"f013.html"
|
|
||||||
],
|
|
||||||
"index": 12,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"7fcb4e5c-ef95-4fb0-a6a9-174318fb7aef": {
|
|
||||||
"id": "7fcb4e5c-ef95-4fb0-a6a9-174318fb7aef",
|
|
||||||
"title": "Деформираща артроза ОСТЕОАРТРОЗА",
|
|
||||||
"files": [
|
|
||||||
"f014.html"
|
|
||||||
],
|
|
||||||
"index": 13,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"5617f428-8057-42a4-8445-39085b5d5561": {
|
|
||||||
"id": "5617f428-8057-42a4-8445-39085b5d5561",
|
|
||||||
"title": "Сегашно състояние-обективен статус на болния. Клинична диагноза и прогноза. Проследяване на болния-декурзус",
|
|
||||||
"files": [
|
|
||||||
"f015.html"
|
|
||||||
],
|
|
||||||
"index": 14,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"501db50d-1cdf-425d-ac2e-e994b5abeba0": {
|
|
||||||
"id": "501db50d-1cdf-425d-ac2e-e994b5abeba0",
|
|
||||||
"title": "Изследване на ДС. Основни симптоми и синдроми на заболявания на ДС. Физиклани и спциални методи на изследване",
|
|
||||||
"files": [
|
|
||||||
"f016.html"
|
|
||||||
],
|
|
||||||
"index": 15,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"db96af60-ee77-4bdb-b4e3-edf93b274593": {
|
|
||||||
"id": "db96af60-ee77-4bdb-b4e3-edf93b274593",
|
|
||||||
"title": "Остър и хроничен бронхит. Белодробен емфизем. ХОББ",
|
|
||||||
"files": [
|
|
||||||
"f017.html",
|
|
||||||
"f057.html"
|
|
||||||
],
|
|
||||||
"index": 16,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"7fa4d0eb-0243-4cf7-8667-7cf130d92f2c": {
|
|
||||||
"id": "7fa4d0eb-0243-4cf7-8667-7cf130d92f2c",
|
|
||||||
"title": "Пневмонии: класификация, клиника, лечение",
|
|
||||||
"files": [
|
|
||||||
"f018.html",
|
|
||||||
"f075.html"
|
|
||||||
],
|
|
||||||
"index": 17,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"2cc4aa8c-978f-4d61-aa3c-9199a955682a": {
|
|
||||||
"id": "2cc4aa8c-978f-4d61-aa3c-9199a955682a",
|
|
||||||
"title": "Бронхиектазии. Белодробен абцес",
|
|
||||||
"files": [
|
|
||||||
"f019.html"
|
|
||||||
],
|
|
||||||
"index": 18,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"20b8b133-cb95-4855-a19b-50a0d2c64f21": {
|
|
||||||
"id": "20b8b133-cb95-4855-a19b-50a0d2c64f21",
|
|
||||||
"title": "Хипертонична болест- рискови фактори; патогенеза; клиника, лечение",
|
|
||||||
"files": [
|
|
||||||
"f020.html",
|
|
||||||
"f035.html"
|
|
||||||
],
|
|
||||||
"index": 19,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"ae779ecf-2f35-445e-91b1-a418ac7cf9cb": {
|
|
||||||
"id": "ae779ecf-2f35-445e-91b1-a418ac7cf9cb",
|
|
||||||
"title": "Изследване на стомашно-чревния тракт. Анемнеза. Основни симптоми и синдроми при заболявания на стомашно-чревния тракт",
|
|
||||||
"files": [
|
|
||||||
"f021.html",
|
|
||||||
"f054.html"
|
|
||||||
],
|
|
||||||
"index": 20,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"e4d7fb75-96f3-421d-9c1d-cd05bccc729b": {
|
|
||||||
"id": "e4d7fb75-96f3-421d-9c1d-cd05bccc729b",
|
|
||||||
"title": "Пиелонефрити",
|
|
||||||
"files": [
|
|
||||||
"f022.html",
|
|
||||||
"f074.html"
|
|
||||||
],
|
|
||||||
"index": 21,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"969617b2-ee8b-4d95-a24a-911adf4a7d9f": {
|
|
||||||
"id": "969617b2-ee8b-4d95-a24a-911adf4a7d9f",
|
|
||||||
"title": "Хемолитични анемии вследствие на вътре и извънеритроцитни фактори, вродени и придобити",
|
|
||||||
"files": [
|
|
||||||
"f023.html",
|
|
||||||
"f084.html"
|
|
||||||
],
|
|
||||||
"index": 22,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"61f037df-1000-402f-a0f5-ffcbde8bb5c7": {
|
|
||||||
"id": "61f037df-1000-402f-a0f5-ffcbde8bb5c7",
|
|
||||||
"title": "Хеморагични диатези – хемофилия, есенциална тромбоцитопения, капиляротоксикоза",
|
|
||||||
"files": [
|
|
||||||
"f024.html",
|
|
||||||
"f091.html"
|
|
||||||
],
|
|
||||||
"index": 23,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"c5053c28-67fc-45a3-8d0a-c8a90c27867d": {
|
|
||||||
"id": "c5053c28-67fc-45a3-8d0a-c8a90c27867d",
|
|
||||||
"title": "Бластна левкоза. Хронична миелолевкоза",
|
|
||||||
"files": [
|
|
||||||
"f025.html",
|
|
||||||
"f087.html"
|
|
||||||
],
|
|
||||||
"index": 24,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"a5fb0e0c-ad77-4a1f-ab08-2978179243e3": {
|
|
||||||
"id": "a5fb0e0c-ad77-4a1f-ab08-2978179243e3",
|
|
||||||
"title": "Нехочкинови и хочкинови лимфоми",
|
|
||||||
"files": [
|
|
||||||
"f026.html",
|
|
||||||
"f089.html"
|
|
||||||
],
|
|
||||||
"index": 25,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"c9bc30ff-a149-43db-b442-a7848b49d4bc": {
|
|
||||||
"id": "c9bc30ff-a149-43db-b442-a7848b49d4bc",
|
|
||||||
"title": "Остри екзогенни интоксикации. Общи принципи и правила в лечението на острите екзогенни отравяния. Поведение на медицинската сестра и грижи за болния с остро отравяне",
|
|
||||||
"files": [
|
|
||||||
"f027.html",
|
|
||||||
"f093.html"
|
|
||||||
],
|
|
||||||
"index": 26,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"b58d8623-cdcf-4428-85fb-7bfe819341b0": {
|
|
||||||
"id": "b58d8623-cdcf-4428-85fb-7bfe819341b0",
|
|
||||||
"title": "Алергия. Алергични заболявания. Анафилактичен шок. Поведение на медицинската сестра при спешни алергични състояния",
|
|
||||||
"files": [
|
|
||||||
"f028.html",
|
|
||||||
"f094.html"
|
|
||||||
],
|
|
||||||
"index": 27,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"6e12b33e-dead-4584-be58-cd11f3f6f787": {
|
|
||||||
"id": "6e12b33e-dead-4584-be58-cd11f3f6f787",
|
|
||||||
"title": "Основни класически методи на изследване във вътрешната медицина-анамнеза. Физикални методи за изледване на болните-оглед, палпация, перкусия, аускултация. Сегашно състояние-обективен статус на болния. Клинична диагноза и прогноза. Проследяване на болния-Декурзус",
|
|
||||||
"files": [
|
|
||||||
"f029.html"
|
|
||||||
],
|
|
||||||
"index": 28,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"b1264871-a4f9-4fe5-9ea2-b64cb586025b": {
|
|
||||||
"id": "b1264871-a4f9-4fe5-9ea2-b64cb586025b",
|
|
||||||
"title": "Дихателна недостатъчност- остра и хронична. Етиология, степени, клиника",
|
|
||||||
"files": [
|
|
||||||
"f030.html"
|
|
||||||
],
|
|
||||||
"index": 29,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"bae8e355-9716-42cc-88db-59e3bb85cc30": {
|
|
||||||
"id": "bae8e355-9716-42cc-88db-59e3bb85cc30",
|
|
||||||
"title": "Ревматизъм",
|
|
||||||
"files": [
|
|
||||||
"f032.html",
|
|
||||||
"f034.html"
|
|
||||||
],
|
|
||||||
"index": 30,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"2ef0265d-2b6a-4683-9ae7-72e2c22e23c6": {
|
|
||||||
"id": "2ef0265d-2b6a-4683-9ae7-72e2c22e23c6",
|
|
||||||
"title": "Ендокардити, перикардити",
|
|
||||||
"files": [
|
|
||||||
"f033.html",
|
|
||||||
"f039.html"
|
|
||||||
],
|
|
||||||
"index": 31,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"faa3cf05-8c89-4407-bfd2-00145aed9ecd": {
|
|
||||||
"id": "faa3cf05-8c89-4407-bfd2-00145aed9ecd",
|
|
||||||
"title": "Остра периферна сърдечно-съдова недостатъчност. Кардиологичен шок",
|
|
||||||
"files": [
|
|
||||||
"f036.html"
|
|
||||||
],
|
|
||||||
"index": 32,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"f04a41b6-e204-4964-8ccd-736d6cdd783a": {
|
|
||||||
"id": "f04a41b6-e204-4964-8ccd-736d6cdd783a",
|
|
||||||
"title": "Лечение на СН и поведение на м. с",
|
|
||||||
"files": [
|
|
||||||
"f037.html"
|
|
||||||
],
|
|
||||||
"index": 33,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"9c799e65-1b44-4665-8ec8-f3c21c1e9af0": {
|
|
||||||
"id": "9c799e65-1b44-4665-8ec8-f3c21c1e9af0",
|
|
||||||
"title": "Ритъмни нарушения на сърдечната дейност. Проводни нарушения на сърдечната дейност",
|
|
||||||
"files": [
|
|
||||||
"f038.html",
|
|
||||||
"f044.html"
|
|
||||||
],
|
|
||||||
"index": 34,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"82a3b90c-5f00-43aa-9331-2a2d98570189": {
|
|
||||||
"id": "82a3b90c-5f00-43aa-9331-2a2d98570189",
|
|
||||||
"title": "ИБС: етиология, рискови фактори, патофизиология. Стенокардия",
|
|
||||||
"files": [
|
|
||||||
"f040.html",
|
|
||||||
"f045.html"
|
|
||||||
],
|
|
||||||
"index": 35,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"30acab20-39b9-4c0e-a4fc-e70c09777f2c": {
|
|
||||||
"id": "30acab20-39b9-4c0e-a4fc-e70c09777f2c",
|
|
||||||
"title": "Изследване на ДС. Основни симптоми и синдроми при заболявания на ДС. Физикални и специаални методи на изследване на ДС",
|
|
||||||
"files": [
|
|
||||||
"f041.html"
|
|
||||||
],
|
|
||||||
"index": 36,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"16f88ceb-5718-4e64-badf-57125972ea03": {
|
|
||||||
"id": "16f88ceb-5718-4e64-badf-57125972ea03",
|
|
||||||
"title": "ИБС: етиология, рискови фактори, патофизиология. Инфаркт на миокарда",
|
|
||||||
"files": [
|
|
||||||
"f042.html",
|
|
||||||
"f046.html"
|
|
||||||
],
|
|
||||||
"index": 37,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"7f1b60f2-6eef-4974-aa3c-5e9fd9b965c7": {
|
|
||||||
"id": "7f1b60f2-6eef-4974-aa3c-5e9fd9b965c7",
|
|
||||||
"title": "Болести на хипофизата- Акромегалия; Безвкусен диабет",
|
|
||||||
"files": [
|
|
||||||
"f043.html",
|
|
||||||
"f048.html"
|
|
||||||
],
|
|
||||||
"index": 38,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"af8e5f62-f7ed-4b8d-9c82-adf5d050d401": {
|
|
||||||
"id": "af8e5f62-f7ed-4b8d-9c82-adf5d050d401",
|
|
||||||
"title": "Захарен диабет-етиология, патогенеза, класификация, клиника. Диабетна кетоацидоза и хипокликемична кома. Поведение на МС при диабетно болен в кома",
|
|
||||||
"files": [
|
|
||||||
"f049.html"
|
|
||||||
],
|
|
||||||
"index": 39,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"690b6497-c240-47d1-ba48-1a608f7e9d50": {
|
|
||||||
"id": "690b6497-c240-47d1-ba48-1a608f7e9d50",
|
|
||||||
"title": "Болести на щитовидната жлеза: Тиреотоксикоза. Микседем. Ендемична гуша",
|
|
||||||
"files": [
|
|
||||||
"f050.html"
|
|
||||||
],
|
|
||||||
"index": 40,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"9b6d0e9c-05cb-41ea-9d15-35f1b394817c": {
|
|
||||||
"id": "9b6d0e9c-05cb-41ea-9d15-35f1b394817c",
|
|
||||||
"title": "Захарен диабет – късни усложнения. Захарен диабет- диета и медикаментозно лечение",
|
|
||||||
"files": [
|
|
||||||
"f051.html",
|
|
||||||
"f056.html"
|
|
||||||
],
|
|
||||||
"index": 41,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"b9f5b23e-a110-4dc5-8b5c-e2b8bf2b3b59": {
|
|
||||||
"id": "b9f5b23e-a110-4dc5-8b5c-e2b8bf2b3b59",
|
|
||||||
"title": "Затлъстяване. Подагра",
|
|
||||||
"files": [
|
|
||||||
"f052.html",
|
|
||||||
"f053.html"
|
|
||||||
],
|
|
||||||
"index": 42,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"6a015a8a-725f-404e-a622-0c1ebba568e7": {
|
|
||||||
"id": "6a015a8a-725f-404e-a622-0c1ebba568e7",
|
|
||||||
"title": "Физикални и специални методи на изследване на стомашно-чревния тракт",
|
|
||||||
"files": [
|
|
||||||
"f055.html"
|
|
||||||
],
|
|
||||||
"index": 43,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"0fc6a512-3b04-4b79-bef7-c658d5bd01cb": {
|
|
||||||
"id": "0fc6a512-3b04-4b79-bef7-c658d5bd01cb",
|
|
||||||
"title": "Гастрити. ГЕРБ",
|
|
||||||
"files": [
|
|
||||||
"f058.html",
|
|
||||||
"f061.html"
|
|
||||||
],
|
|
||||||
"index": 44,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"f331d024-1846-44ae-860e-9dfc8522fafc": {
|
|
||||||
"id": "f331d024-1846-44ae-860e-9dfc8522fafc",
|
|
||||||
"title": "Язвена болест. Рак на стомаха",
|
|
||||||
"files": [
|
|
||||||
"f059.html",
|
|
||||||
"f063.html"
|
|
||||||
],
|
|
||||||
"index": 45,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"85f1a01e-3a5d-44da-9021-7460152cd5d1": {
|
|
||||||
"id": "85f1a01e-3a5d-44da-9021-7460152cd5d1",
|
|
||||||
"title": "Ентерити и колити. Рак на дебелото черво",
|
|
||||||
"files": [
|
|
||||||
"f060.html",
|
|
||||||
"f065.html"
|
|
||||||
],
|
|
||||||
"index": 46,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"c6524b3f-9cd6-4d2e-96ea-63120f2d8f7b": {
|
|
||||||
"id": "c6524b3f-9cd6-4d2e-96ea-63120f2d8f7b",
|
|
||||||
"title": "Основни симптоми и синдроми при заболяване на черния дроб и жлъчните пътища. Жълтеница, портална хипертония, асцит. Анамнеза, физикални и специални методи за изследване на черния дроб и жлъчните пътища",
|
|
||||||
"files": [
|
|
||||||
"f062.html"
|
|
||||||
],
|
|
||||||
"index": 47,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"fafe1f1a-71fc-4756-8aa7-38eeadb156a7": {
|
|
||||||
"id": "fafe1f1a-71fc-4756-8aa7-38eeadb156a7",
|
|
||||||
"title": "Хронични хепатити. Чернодробна цироза",
|
|
||||||
"files": [
|
|
||||||
"f064.html",
|
|
||||||
"f071.html"
|
|
||||||
],
|
|
||||||
"index": 48,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"be416a10-e96b-4a98-b413-47dce446c9ac": {
|
|
||||||
"id": "be416a10-e96b-4a98-b413-47dce446c9ac",
|
|
||||||
"title": "Холелитиаза. Холецистити",
|
|
||||||
"files": [
|
|
||||||
"f066.html",
|
|
||||||
"f073.html"
|
|
||||||
],
|
|
||||||
"index": 49,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"4788afb8-c112-42d3-9bae-40362556fa2b": {
|
|
||||||
"id": "4788afb8-c112-42d3-9bae-40362556fa2b",
|
|
||||||
"title": "Основни симптоми и синдроми при заболяване на черния дроб и жлъчните пътища. Анамнеза, физикални и специални методи за изледване на черния дроб и жлъчните пътища",
|
|
||||||
"files": [
|
|
||||||
"f067.html",
|
|
||||||
"f068.html"
|
|
||||||
],
|
|
||||||
"index": 50,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"8995a8df-963f-4459-bb8e-21912a9d0023": {
|
|
||||||
"id": "8995a8df-963f-4459-bb8e-21912a9d0023",
|
|
||||||
"title": "Остър и хроничен гломерулонефрит",
|
|
||||||
"files": [
|
|
||||||
"f069.html",
|
|
||||||
"f070.html"
|
|
||||||
],
|
|
||||||
"index": 51,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"9678afb6-4173-40f2-bcea-026a7b8307b9": {
|
|
||||||
"id": "9678afb6-4173-40f2-bcea-026a7b8307b9",
|
|
||||||
"title": "Нефролитиаза",
|
|
||||||
"files": [
|
|
||||||
"f072.html",
|
|
||||||
"f077.html"
|
|
||||||
],
|
|
||||||
"index": 52,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"c3c7ce4c-c9a0-449f-9ad2-5ce92ce203dd": {
|
|
||||||
"id": "c3c7ce4c-c9a0-449f-9ad2-5ce92ce203dd",
|
|
||||||
"title": "Остра бъбречна и хронична бъбречна недостатъчност",
|
|
||||||
"files": [
|
|
||||||
"f076.html"
|
|
||||||
],
|
|
||||||
"index": 53,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"281dc9d6-8971-42ff-a6b9-8901cc19e845": {
|
|
||||||
"id": "281dc9d6-8971-42ff-a6b9-8901cc19e845",
|
|
||||||
"title": "Балканска ендемична нефропатия. Бъбречна поликистозна болест. Бъбречна туберкулоза",
|
|
||||||
"files": [
|
|
||||||
"f078.html",
|
|
||||||
"f082.html"
|
|
||||||
],
|
|
||||||
"index": 54,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"d5183ba3-7de8-4676-ac25-81ec2f3915da": {
|
|
||||||
"id": "d5183ba3-7de8-4676-ac25-81ec2f3915da",
|
|
||||||
"title": "Ревмтоиден артрит",
|
|
||||||
"files": [
|
|
||||||
"f079.html",
|
|
||||||
"f085.html"
|
|
||||||
],
|
|
||||||
"index": 55,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"356b7311-aae7-4303-91d2-e0817bc462dd": {
|
|
||||||
"id": "356b7311-aae7-4303-91d2-e0817bc462dd",
|
|
||||||
"title": "Деформираща артроза",
|
|
||||||
"files": [
|
|
||||||
"f080.html",
|
|
||||||
"f081.html"
|
|
||||||
],
|
|
||||||
"index": 56,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"fb12f399-7a8d-47ba-8460-8b9291a16e53": {
|
|
||||||
"id": "fb12f399-7a8d-47ba-8460-8b9291a16e53",
|
|
||||||
"title": "Желязодефицитни анемии",
|
|
||||||
"files": [
|
|
||||||
"f083.html",
|
|
||||||
"f088.html"
|
|
||||||
],
|
|
||||||
"index": 57,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"5a493bc7-e45e-46f8-9fb8-722ea9636750": {
|
|
||||||
"id": "5a493bc7-e45e-46f8-9fb8-722ea9636750",
|
|
||||||
"title": "Витамин В 12 – дефицитни анемии",
|
|
||||||
"files": [
|
|
||||||
"f086.html",
|
|
||||||
"f090.html"
|
|
||||||
],
|
|
||||||
"index": 58,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"bc84aab9-dd28-4166-939e-b288cd84cf3d": {
|
|
||||||
"id": "bc84aab9-dd28-4166-939e-b288cd84cf3d",
|
|
||||||
"title": "Бронхоектазии. Белодробен абцес",
|
|
||||||
"files": [
|
|
||||||
"f092.html"
|
|
||||||
],
|
|
||||||
"index": 59,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": false
|
|
||||||
},
|
|
||||||
"6d88be6a-0f4f-43ec-82cb-71b57fdfa785": {
|
|
||||||
"id": "6d88be6a-0f4f-43ec-82cb-71b57fdfa785",
|
|
||||||
"title": "Tумори на белия дроб",
|
|
||||||
"files": [
|
|
||||||
"f095.html"
|
|
||||||
],
|
|
||||||
"index": 60,
|
|
||||||
"isFirst": false,
|
|
||||||
"isLast": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"allIds": [
|
|
||||||
"a4d9fa36-8ed7-4d80-a108-eac209ca01a8",
|
|
||||||
"f7fed0c0-15d9-439c-a3ef-24cec673dd44",
|
|
||||||
"b20a76c0-59a1-4f0a-bb33-39c4bf437eac",
|
|
||||||
"a2a3a830-9f1d-4dd0-ab52-c42ae66c17b3",
|
|
||||||
"38899f8f-2291-4923-ae59-928181c88bbd",
|
|
||||||
"b0460271-a4e2-4e82-a7ea-0f98689fcbb6",
|
|
||||||
"9db34720-4756-4469-bbf0-1666d4b6c65f",
|
|
||||||
"c12799f8-63d2-4d76-88b9-e0fa68def5a4",
|
|
||||||
"c200281a-d2cd-4ca6-b6d3-114db5753fc5",
|
|
||||||
"f191d184-a26f-41aa-b213-ead39c22f4c1",
|
|
||||||
"6b01e219-49d9-4ced-ae83-0e21a6cba53c",
|
|
||||||
"bc201e49-52a3-42da-b47a-ed786576b377",
|
|
||||||
"1d71aeff-1637-493f-93ae-c7126367528c",
|
|
||||||
"7fcb4e5c-ef95-4fb0-a6a9-174318fb7aef",
|
|
||||||
"5617f428-8057-42a4-8445-39085b5d5561",
|
|
||||||
"501db50d-1cdf-425d-ac2e-e994b5abeba0",
|
|
||||||
"db96af60-ee77-4bdb-b4e3-edf93b274593",
|
|
||||||
"7fa4d0eb-0243-4cf7-8667-7cf130d92f2c",
|
|
||||||
"2cc4aa8c-978f-4d61-aa3c-9199a955682a",
|
|
||||||
"20b8b133-cb95-4855-a19b-50a0d2c64f21",
|
|
||||||
"ae779ecf-2f35-445e-91b1-a418ac7cf9cb",
|
|
||||||
"e4d7fb75-96f3-421d-9c1d-cd05bccc729b",
|
|
||||||
"969617b2-ee8b-4d95-a24a-911adf4a7d9f",
|
|
||||||
"61f037df-1000-402f-a0f5-ffcbde8bb5c7",
|
|
||||||
"c5053c28-67fc-45a3-8d0a-c8a90c27867d",
|
|
||||||
"a5fb0e0c-ad77-4a1f-ab08-2978179243e3",
|
|
||||||
"c9bc30ff-a149-43db-b442-a7848b49d4bc",
|
|
||||||
"b58d8623-cdcf-4428-85fb-7bfe819341b0",
|
|
||||||
"6e12b33e-dead-4584-be58-cd11f3f6f787",
|
|
||||||
"b1264871-a4f9-4fe5-9ea2-b64cb586025b",
|
|
||||||
"bae8e355-9716-42cc-88db-59e3bb85cc30",
|
|
||||||
"2ef0265d-2b6a-4683-9ae7-72e2c22e23c6",
|
|
||||||
"faa3cf05-8c89-4407-bfd2-00145aed9ecd",
|
|
||||||
"f04a41b6-e204-4964-8ccd-736d6cdd783a",
|
|
||||||
"9c799e65-1b44-4665-8ec8-f3c21c1e9af0",
|
|
||||||
"82a3b90c-5f00-43aa-9331-2a2d98570189",
|
|
||||||
"30acab20-39b9-4c0e-a4fc-e70c09777f2c",
|
|
||||||
"16f88ceb-5718-4e64-badf-57125972ea03",
|
|
||||||
"7f1b60f2-6eef-4974-aa3c-5e9fd9b965c7",
|
|
||||||
"af8e5f62-f7ed-4b8d-9c82-adf5d050d401",
|
|
||||||
"690b6497-c240-47d1-ba48-1a608f7e9d50",
|
|
||||||
"9b6d0e9c-05cb-41ea-9d15-35f1b394817c",
|
|
||||||
"b9f5b23e-a110-4dc5-8b5c-e2b8bf2b3b59",
|
|
||||||
"6a015a8a-725f-404e-a622-0c1ebba568e7",
|
|
||||||
"0fc6a512-3b04-4b79-bef7-c658d5bd01cb",
|
|
||||||
"f331d024-1846-44ae-860e-9dfc8522fafc",
|
|
||||||
"85f1a01e-3a5d-44da-9021-7460152cd5d1",
|
|
||||||
"c6524b3f-9cd6-4d2e-96ea-63120f2d8f7b",
|
|
||||||
"fafe1f1a-71fc-4756-8aa7-38eeadb156a7",
|
|
||||||
"be416a10-e96b-4a98-b413-47dce446c9ac",
|
|
||||||
"4788afb8-c112-42d3-9bae-40362556fa2b",
|
|
||||||
"8995a8df-963f-4459-bb8e-21912a9d0023",
|
|
||||||
"9678afb6-4173-40f2-bcea-026a7b8307b9",
|
|
||||||
"c3c7ce4c-c9a0-449f-9ad2-5ce92ce203dd",
|
|
||||||
"281dc9d6-8971-42ff-a6b9-8901cc19e845",
|
|
||||||
"d5183ba3-7de8-4676-ac25-81ec2f3915da",
|
|
||||||
"356b7311-aae7-4303-91d2-e0817bc462dd",
|
|
||||||
"fb12f399-7a8d-47ba-8460-8b9291a16e53",
|
|
||||||
"5a493bc7-e45e-46f8-9fb8-722ea9636750",
|
|
||||||
"bc84aab9-dd28-4166-939e-b288cd84cf3d",
|
|
||||||
"6d88be6a-0f4f-43ec-82cb-71b57fdfa785"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user