diff --git a/README.md b/README.md index 23b00fb..f1435a1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # Personal-Space This site is a glimpse into my world + +Sorry for the messy code \ No newline at end of file diff --git a/about.php b/about.php new file mode 100644 index 0000000..6987834 --- /dev/null +++ b/about.php @@ -0,0 +1,80 @@ + + + + + + + + About Me + + + +
+
+ + + + +
+
+
+
+

+
+ + + +

+
+
+
+ +
+
+ +
+ + \ No newline at end of file diff --git a/blog/Parsedown.php b/blog/Parsedown.php new file mode 100644 index 0000000..2bb5eb9 --- /dev/null +++ b/blog/Parsedown.php @@ -0,0 +1,1996 @@ +textElements($text); + + # convert to markup + $markup = $this->elements($Elements); + + # trim line breaks + $markup = trim($markup, "\n"); + + return $markup; + } + + protected function textElements($text) + { + # make sure no definitions are set + $this->DefinitionData = array(); + + # standardize line breaks + $text = str_replace(array("\r\n", "\r"), "\n", $text); + + # remove surrounding line breaks + $text = trim($text, "\n"); + + # split text into lines + $lines = explode("\n", $text); + + # iterate through lines to identify blocks + return $this->linesElements($lines); + } + + # + # Setters + # + + function setBreaksEnabled($breaksEnabled) + { + $this->breaksEnabled = $breaksEnabled; + + return $this; + } + + protected $breaksEnabled; + + function setMarkupEscaped($markupEscaped) + { + $this->markupEscaped = $markupEscaped; + + return $this; + } + + protected $markupEscaped; + + function setUrlsLinked($urlsLinked) + { + $this->urlsLinked = $urlsLinked; + + return $this; + } + + protected $urlsLinked = true; + + function setSafeMode($safeMode) + { + $this->safeMode = (bool) $safeMode; + + return $this; + } + + protected $safeMode; + + function setStrictMode($strictMode) + { + $this->strictMode = (bool) $strictMode; + + return $this; + } + + protected $strictMode; + + protected $safeLinksWhitelist = array( + 'http://', + 'https://', + 'ftp://', + 'ftps://', + 'mailto:', + 'tel:', + 'data:image/png;base64,', + 'data:image/gif;base64,', + 'data:image/jpeg;base64,', + 'irc:', + 'ircs:', + 'git:', + 'ssh:', + 'news:', + 'steam:', + ); + + # + # Lines + # + + protected $BlockTypes = array( + '#' => array('Header'), + '*' => array('Rule', 'List'), + '+' => array('List'), + '-' => array('SetextHeader', 'Table', 'Rule', 'List'), + '0' => array('List'), + '1' => array('List'), + '2' => array('List'), + '3' => array('List'), + '4' => array('List'), + '5' => array('List'), + '6' => array('List'), + '7' => array('List'), + '8' => array('List'), + '9' => array('List'), + ':' => array('Table'), + '<' => array('Comment', 'Markup'), + '=' => array('SetextHeader'), + '>' => array('Quote'), + '[' => array('Reference'), + '_' => array('Rule'), + '`' => array('FencedCode'), + '|' => array('Table'), + '~' => array('FencedCode'), + ); + + # ~ + + protected $unmarkedBlockTypes = array( + 'Code', + ); + + # + # Blocks + # + + protected function lines(array $lines) + { + return $this->elements($this->linesElements($lines)); + } + + protected function linesElements(array $lines) + { + $Elements = array(); + $CurrentBlock = null; + + foreach ($lines as $line) + { + if (chop($line) === '') + { + if (isset($CurrentBlock)) + { + $CurrentBlock['interrupted'] = (isset($CurrentBlock['interrupted']) + ? $CurrentBlock['interrupted'] + 1 : 1 + ); + } + + continue; + } + + while (($beforeTab = strstr($line, "\t", true)) !== false) + { + $shortage = 4 - mb_strlen($beforeTab, 'utf-8') % 4; + + $line = $beforeTab + . str_repeat(' ', $shortage) + . substr($line, strlen($beforeTab) + 1) + ; + } + + $indent = strspn($line, ' '); + + $text = $indent > 0 ? substr($line, $indent) : $line; + + # ~ + + $Line = array('body' => $line, 'indent' => $indent, 'text' => $text); + + # ~ + + if (isset($CurrentBlock['continuable'])) + { + $methodName = 'block' . $CurrentBlock['type'] . 'Continue'; + $Block = $this->$methodName($Line, $CurrentBlock); + + if (isset($Block)) + { + $CurrentBlock = $Block; + + continue; + } + else + { + if ($this->isBlockCompletable($CurrentBlock['type'])) + { + $methodName = 'block' . $CurrentBlock['type'] . 'Complete'; + $CurrentBlock = $this->$methodName($CurrentBlock); + } + } + } + + # ~ + + $marker = $text[0]; + + # ~ + + $blockTypes = $this->unmarkedBlockTypes; + + if (isset($this->BlockTypes[$marker])) + { + foreach ($this->BlockTypes[$marker] as $blockType) + { + $blockTypes []= $blockType; + } + } + + # + # ~ + + foreach ($blockTypes as $blockType) + { + $Block = $this->{"block$blockType"}($Line, $CurrentBlock); + + if (isset($Block)) + { + $Block['type'] = $blockType; + + if ( ! isset($Block['identified'])) + { + if (isset($CurrentBlock)) + { + $Elements[] = $this->extractElement($CurrentBlock); + } + + $Block['identified'] = true; + } + + if ($this->isBlockContinuable($blockType)) + { + $Block['continuable'] = true; + } + + $CurrentBlock = $Block; + + continue 2; + } + } + + # ~ + + if (isset($CurrentBlock) and $CurrentBlock['type'] === 'Paragraph') + { + $Block = $this->paragraphContinue($Line, $CurrentBlock); + } + + if (isset($Block)) + { + $CurrentBlock = $Block; + } + else + { + if (isset($CurrentBlock)) + { + $Elements[] = $this->extractElement($CurrentBlock); + } + + $CurrentBlock = $this->paragraph($Line); + + $CurrentBlock['identified'] = true; + } + } + + # ~ + + if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type'])) + { + $methodName = 'block' . $CurrentBlock['type'] . 'Complete'; + $CurrentBlock = $this->$methodName($CurrentBlock); + } + + # ~ + + if (isset($CurrentBlock)) + { + $Elements[] = $this->extractElement($CurrentBlock); + } + + # ~ + + return $Elements; + } + + protected function extractElement(array $Component) + { + if ( ! isset($Component['element'])) + { + if (isset($Component['markup'])) + { + $Component['element'] = array('rawHtml' => $Component['markup']); + } + elseif (isset($Component['hidden'])) + { + $Component['element'] = array(); + } + } + + return $Component['element']; + } + + protected function isBlockContinuable($Type) + { + return method_exists($this, 'block' . $Type . 'Continue'); + } + + protected function isBlockCompletable($Type) + { + return method_exists($this, 'block' . $Type . 'Complete'); + } + + # + # Code + + protected function blockCode($Line, $Block = null) + { + if (isset($Block) and $Block['type'] === 'Paragraph' and ! isset($Block['interrupted'])) + { + return; + } + + if ($Line['indent'] >= 4) + { + $text = substr($Line['body'], 4); + + $Block = array( + 'element' => array( + 'name' => 'pre', + 'element' => array( + 'name' => 'code', + 'text' => $text, + ), + ), + ); + + return $Block; + } + } + + protected function blockCodeContinue($Line, $Block) + { + if ($Line['indent'] >= 4) + { + if (isset($Block['interrupted'])) + { + $Block['element']['element']['text'] .= str_repeat("\n", $Block['interrupted']); + + unset($Block['interrupted']); + } + + $Block['element']['element']['text'] .= "\n"; + + $text = substr($Line['body'], 4); + + $Block['element']['element']['text'] .= $text; + + return $Block; + } + } + + protected function blockCodeComplete($Block) + { + return $Block; + } + + # + # Comment + + protected function blockComment($Line) + { + if ($this->markupEscaped or $this->safeMode) + { + return; + } + + if (strpos($Line['text'], '') !== false) + { + $Block['closed'] = true; + } + + return $Block; + } + } + + protected function blockCommentContinue($Line, array $Block) + { + if (isset($Block['closed'])) + { + return; + } + + $Block['element']['rawHtml'] .= "\n" . $Line['body']; + + if (strpos($Line['text'], '-->') !== false) + { + $Block['closed'] = true; + } + + return $Block; + } + + # + # Fenced Code + + protected function blockFencedCode($Line) + { + $marker = $Line['text'][0]; + + $openerLength = strspn($Line['text'], $marker); + + if ($openerLength < 3) + { + return; + } + + $infostring = trim(substr($Line['text'], $openerLength), "\t "); + + if (strpos($infostring, '`') !== false) + { + return; + } + + $Element = array( + 'name' => 'code', + 'text' => '', + ); + + if ($infostring !== '') + { + /** + * https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes + * Every HTML element may have a class attribute specified. + * The attribute, if specified, must have a value that is a set + * of space-separated tokens representing the various classes + * that the element belongs to. + * [...] + * The space characters, for the purposes of this specification, + * are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), + * U+000A LINE FEED (LF), U+000C FORM FEED (FF), and + * U+000D CARRIAGE RETURN (CR). + */ + $language = substr($infostring, 0, strcspn($infostring, " \t\n\f\r")); + + $Element['attributes'] = array('class' => "language-$language"); + } + + $Block = array( + 'char' => $marker, + 'openerLength' => $openerLength, + 'element' => array( + 'name' => 'pre', + 'element' => $Element, + ), + ); + + return $Block; + } + + protected function blockFencedCodeContinue($Line, $Block) + { + if (isset($Block['complete'])) + { + return; + } + + if (isset($Block['interrupted'])) + { + $Block['element']['element']['text'] .= str_repeat("\n", $Block['interrupted']); + + unset($Block['interrupted']); + } + + if (($len = strspn($Line['text'], $Block['char'])) >= $Block['openerLength'] + and chop(substr($Line['text'], $len), ' ') === '' + ) { + $Block['element']['element']['text'] = substr($Block['element']['element']['text'], 1); + + $Block['complete'] = true; + + return $Block; + } + + $Block['element']['element']['text'] .= "\n" . $Line['body']; + + return $Block; + } + + protected function blockFencedCodeComplete($Block) + { + return $Block; + } + + # + # Header + + protected function blockHeader($Line) + { + $level = strspn($Line['text'], '#'); + + if ($level > 6) + { + return; + } + + $text = trim($Line['text'], '#'); + + if ($this->strictMode and isset($text[0]) and $text[0] !== ' ') + { + return; + } + + $text = trim($text, ' '); + + $Block = array( + 'element' => array( + 'name' => 'h' . $level, + 'handler' => array( + 'function' => 'lineElements', + 'argument' => $text, + 'destination' => 'elements', + ) + ), + ); + + return $Block; + } + + # + # List + + protected function blockList($Line, ?array $CurrentBlock = null) + { + list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]{1,9}+[.\)]'); + + if (preg_match('/^('.$pattern.'([ ]++|$))(.*+)/', $Line['text'], $matches)) + { + $contentIndent = strlen($matches[2]); + + if ($contentIndent >= 5) + { + $contentIndent -= 1; + $matches[1] = substr($matches[1], 0, -$contentIndent); + $matches[3] = str_repeat(' ', $contentIndent) . $matches[3]; + } + elseif ($contentIndent === 0) + { + $matches[1] .= ' '; + } + + $markerWithoutWhitespace = strstr($matches[1], ' ', true); + + $Block = array( + 'indent' => $Line['indent'], + 'pattern' => $pattern, + 'data' => array( + 'type' => $name, + 'marker' => $matches[1], + 'markerType' => ($name === 'ul' ? $markerWithoutWhitespace : substr($markerWithoutWhitespace, -1)), + ), + 'element' => array( + 'name' => $name, + 'elements' => array(), + ), + ); + $Block['data']['markerTypeRegex'] = preg_quote($Block['data']['markerType'], '/'); + + if ($name === 'ol') + { + $listStart = ltrim(strstr($matches[1], $Block['data']['markerType'], true), '0') ?: '0'; + + if ($listStart !== '1') + { + if ( + isset($CurrentBlock) + and $CurrentBlock['type'] === 'Paragraph' + and ! isset($CurrentBlock['interrupted']) + ) { + return; + } + + $Block['element']['attributes'] = array('start' => $listStart); + } + } + + $Block['li'] = array( + 'name' => 'li', + 'handler' => array( + 'function' => 'li', + 'argument' => !empty($matches[3]) ? array($matches[3]) : array(), + 'destination' => 'elements' + ) + ); + + $Block['element']['elements'] []= & $Block['li']; + + return $Block; + } + } + + protected function blockListContinue($Line, array $Block) + { + if (isset($Block['interrupted']) and empty($Block['li']['handler']['argument'])) + { + return null; + } + + $requiredIndent = ($Block['indent'] + strlen($Block['data']['marker'])); + + if ($Line['indent'] < $requiredIndent + and ( + ( + $Block['data']['type'] === 'ol' + and preg_match('/^[0-9]++'.$Block['data']['markerTypeRegex'].'(?:[ ]++(.*)|$)/', $Line['text'], $matches) + ) or ( + $Block['data']['type'] === 'ul' + and preg_match('/^'.$Block['data']['markerTypeRegex'].'(?:[ ]++(.*)|$)/', $Line['text'], $matches) + ) + ) + ) { + if (isset($Block['interrupted'])) + { + $Block['li']['handler']['argument'] []= ''; + + $Block['loose'] = true; + + unset($Block['interrupted']); + } + + unset($Block['li']); + + $text = isset($matches[1]) ? $matches[1] : ''; + + $Block['indent'] = $Line['indent']; + + $Block['li'] = array( + 'name' => 'li', + 'handler' => array( + 'function' => 'li', + 'argument' => array($text), + 'destination' => 'elements' + ) + ); + + $Block['element']['elements'] []= & $Block['li']; + + return $Block; + } + elseif ($Line['indent'] < $requiredIndent and $this->blockList($Line)) + { + return null; + } + + if ($Line['text'][0] === '[' and $this->blockReference($Line)) + { + return $Block; + } + + if ($Line['indent'] >= $requiredIndent) + { + if (isset($Block['interrupted'])) + { + $Block['li']['handler']['argument'] []= ''; + + $Block['loose'] = true; + + unset($Block['interrupted']); + } + + $text = substr($Line['body'], $requiredIndent); + + $Block['li']['handler']['argument'] []= $text; + + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $text = preg_replace('/^[ ]{0,'.$requiredIndent.'}+/', '', $Line['body']); + + $Block['li']['handler']['argument'] []= $text; + + return $Block; + } + } + + protected function blockListComplete(array $Block) + { + if (isset($Block['loose'])) + { + foreach ($Block['element']['elements'] as &$li) + { + if (end($li['handler']['argument']) !== '') + { + $li['handler']['argument'] []= ''; + } + } + } + + return $Block; + } + + # + # Quote + + protected function blockQuote($Line) + { + if (preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches)) + { + $Block = array( + 'element' => array( + 'name' => 'blockquote', + 'handler' => array( + 'function' => 'linesElements', + 'argument' => (array) $matches[1], + 'destination' => 'elements', + ) + ), + ); + + return $Block; + } + } + + protected function blockQuoteContinue($Line, array $Block) + { + if (isset($Block['interrupted'])) + { + return; + } + + if ($Line['text'][0] === '>' and preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches)) + { + $Block['element']['handler']['argument'] []= $matches[1]; + + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $Block['element']['handler']['argument'] []= $Line['text']; + + return $Block; + } + } + + # + # Rule + + protected function blockRule($Line) + { + $marker = $Line['text'][0]; + + if (substr_count($Line['text'], $marker) >= 3 and chop($Line['text'], " $marker") === '') + { + $Block = array( + 'element' => array( + 'name' => 'hr', + ), + ); + + return $Block; + } + } + + # + # Setext + + protected function blockSetextHeader($Line, ?array $Block = null) + { + if ( ! isset($Block) or $Block['type'] !== 'Paragraph' or isset($Block['interrupted'])) + { + return; + } + + if ($Line['indent'] < 4 and chop(chop($Line['text'], ' '), $Line['text'][0]) === '') + { + $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2'; + + return $Block; + } + } + + # + # Markup + + protected function blockMarkup($Line) + { + if ($this->markupEscaped or $this->safeMode) + { + return; + } + + if (preg_match('/^<[\/]?+(\w*)(?:[ ]*+'.$this->regexHtmlAttribute.')*+[ ]*+(\/)?>/', $Line['text'], $matches)) + { + $element = strtolower($matches[1]); + + if (in_array($element, $this->textLevelElements)) + { + return; + } + + $Block = array( + 'name' => $matches[1], + 'element' => array( + 'rawHtml' => $Line['text'], + 'autobreak' => true, + ), + ); + + return $Block; + } + } + + protected function blockMarkupContinue($Line, array $Block) + { + if (isset($Block['closed']) or isset($Block['interrupted'])) + { + return; + } + + $Block['element']['rawHtml'] .= "\n" . $Line['body']; + + return $Block; + } + + # + # Reference + + protected function blockReference($Line) + { + if (strpos($Line['text'], ']') !== false + and preg_match('/^\[(.+?)\]:[ ]*+?(?:[ ]+["\'(](.+)["\')])?[ ]*+$/', $Line['text'], $matches) + ) { + $id = strtolower($matches[1]); + + $Data = array( + 'url' => $matches[2], + 'title' => isset($matches[3]) ? $matches[3] : null, + ); + + $this->DefinitionData['Reference'][$id] = $Data; + + $Block = array( + 'element' => array(), + ); + + return $Block; + } + } + + # + # Table + + protected function blockTable($Line, ?array $Block = null) + { + if ( ! isset($Block) or $Block['type'] !== 'Paragraph' or isset($Block['interrupted'])) + { + return; + } + + if ( + strpos($Block['element']['handler']['argument'], '|') === false + and strpos($Line['text'], '|') === false + and strpos($Line['text'], ':') === false + or strpos($Block['element']['handler']['argument'], "\n") !== false + ) { + return; + } + + if (chop($Line['text'], ' -:|') !== '') + { + return; + } + + $alignments = array(); + + $divider = $Line['text']; + + $divider = trim($divider); + $divider = trim($divider, '|'); + + $dividerCells = explode('|', $divider); + + foreach ($dividerCells as $dividerCell) + { + $dividerCell = trim($dividerCell); + + if ($dividerCell === '') + { + return; + } + + $alignment = null; + + if ($dividerCell[0] === ':') + { + $alignment = 'left'; + } + + if (substr($dividerCell, - 1) === ':') + { + $alignment = $alignment === 'left' ? 'center' : 'right'; + } + + $alignments []= $alignment; + } + + # ~ + + $HeaderElements = array(); + + $header = $Block['element']['handler']['argument']; + + $header = trim($header); + $header = trim($header, '|'); + + $headerCells = explode('|', $header); + + if (count($headerCells) !== count($alignments)) + { + return; + } + + foreach ($headerCells as $index => $headerCell) + { + $headerCell = trim($headerCell); + + $HeaderElement = array( + 'name' => 'th', + 'handler' => array( + 'function' => 'lineElements', + 'argument' => $headerCell, + 'destination' => 'elements', + ) + ); + + if (isset($alignments[$index])) + { + $alignment = $alignments[$index]; + + $HeaderElement['attributes'] = array( + 'style' => "text-align: $alignment;", + ); + } + + $HeaderElements []= $HeaderElement; + } + + # ~ + + $Block = array( + 'alignments' => $alignments, + 'identified' => true, + 'element' => array( + 'name' => 'table', + 'elements' => array(), + ), + ); + + $Block['element']['elements'] []= array( + 'name' => 'thead', + ); + + $Block['element']['elements'] []= array( + 'name' => 'tbody', + 'elements' => array(), + ); + + $Block['element']['elements'][0]['elements'] []= array( + 'name' => 'tr', + 'elements' => $HeaderElements, + ); + + return $Block; + } + + protected function blockTableContinue($Line, array $Block) + { + if (isset($Block['interrupted'])) + { + return; + } + + if (count($Block['alignments']) === 1 or $Line['text'][0] === '|' or strpos($Line['text'], '|')) + { + $Elements = array(); + + $row = $Line['text']; + + $row = trim($row); + $row = trim($row, '|'); + + preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]++`|`)++/', $row, $matches); + + $cells = array_slice($matches[0], 0, count($Block['alignments'])); + + foreach ($cells as $index => $cell) + { + $cell = trim($cell); + + $Element = array( + 'name' => 'td', + 'handler' => array( + 'function' => 'lineElements', + 'argument' => $cell, + 'destination' => 'elements', + ) + ); + + if (isset($Block['alignments'][$index])) + { + $Element['attributes'] = array( + 'style' => 'text-align: ' . $Block['alignments'][$index] . ';', + ); + } + + $Elements []= $Element; + } + + $Element = array( + 'name' => 'tr', + 'elements' => $Elements, + ); + + $Block['element']['elements'][1]['elements'] []= $Element; + + return $Block; + } + } + + # + # ~ + # + + protected function paragraph($Line) + { + return array( + 'type' => 'Paragraph', + 'element' => array( + 'name' => 'p', + 'handler' => array( + 'function' => 'lineElements', + 'argument' => $Line['text'], + 'destination' => 'elements', + ), + ), + ); + } + + protected function paragraphContinue($Line, array $Block) + { + if (isset($Block['interrupted'])) + { + return; + } + + $Block['element']['handler']['argument'] .= "\n".$Line['text']; + + return $Block; + } + + # + # Inline Elements + # + + protected $InlineTypes = array( + '!' => array('Image'), + '&' => array('SpecialCharacter'), + '*' => array('Emphasis'), + ':' => array('Url'), + '<' => array('UrlTag', 'EmailTag', 'Markup'), + '[' => array('Link'), + '_' => array('Emphasis'), + '`' => array('Code'), + '~' => array('Strikethrough'), + '\\' => array('EscapeSequence'), + ); + + # ~ + + protected $inlineMarkerList = '!*_&[:<`~\\'; + + # + # ~ + # + + public function line($text, $nonNestables = array()) + { + return $this->elements($this->lineElements($text, $nonNestables)); + } + + protected function lineElements($text, $nonNestables = array()) + { + # standardize line breaks + $text = str_replace(array("\r\n", "\r"), "\n", $text); + + $Elements = array(); + + $nonNestables = (empty($nonNestables) + ? array() + : array_combine($nonNestables, $nonNestables) + ); + + # $excerpt is based on the first occurrence of a marker + + while ($excerpt = strpbrk($text, $this->inlineMarkerList)) + { + $marker = $excerpt[0]; + + $markerPosition = strlen($text) - strlen($excerpt); + + $Excerpt = array('text' => $excerpt, 'context' => $text); + + foreach ($this->InlineTypes[$marker] as $inlineType) + { + # check to see if the current inline type is nestable in the current context + + if (isset($nonNestables[$inlineType])) + { + continue; + } + + $Inline = $this->{"inline$inlineType"}($Excerpt); + + if ( ! isset($Inline)) + { + continue; + } + + # makes sure that the inline belongs to "our" marker + + if (isset($Inline['position']) and $Inline['position'] > $markerPosition) + { + continue; + } + + # sets a default inline position + + if ( ! isset($Inline['position'])) + { + $Inline['position'] = $markerPosition; + } + + # cause the new element to 'inherit' our non nestables + + + $Inline['element']['nonNestables'] = isset($Inline['element']['nonNestables']) + ? array_merge($Inline['element']['nonNestables'], $nonNestables) + : $nonNestables + ; + + # the text that comes before the inline + $unmarkedText = substr($text, 0, $Inline['position']); + + # compile the unmarked text + $InlineText = $this->inlineText($unmarkedText); + $Elements[] = $InlineText['element']; + + # compile the inline + $Elements[] = $this->extractElement($Inline); + + # remove the examined text + $text = substr($text, $Inline['position'] + $Inline['extent']); + + continue 2; + } + + # the marker does not belong to an inline + + $unmarkedText = substr($text, 0, $markerPosition + 1); + + $InlineText = $this->inlineText($unmarkedText); + $Elements[] = $InlineText['element']; + + $text = substr($text, $markerPosition + 1); + } + + $InlineText = $this->inlineText($text); + $Elements[] = $InlineText['element']; + + foreach ($Elements as &$Element) + { + if ( ! isset($Element['autobreak'])) + { + $Element['autobreak'] = false; + } + } + + return $Elements; + } + + # + # ~ + # + + protected function inlineText($text) + { + $Inline = array( + 'extent' => strlen($text), + 'element' => array(), + ); + + $Inline['element']['elements'] = self::pregReplaceElements( + $this->breaksEnabled ? '/[ ]*+\n/' : '/(?:[ ]*+\\\\|[ ]{2,}+)\n/', + array( + array('name' => 'br'), + array('text' => "\n"), + ), + $text + ); + + return $Inline; + } + + protected function inlineCode($Excerpt) + { + $marker = $Excerpt['text'][0]; + + if (preg_match('/^(['.$marker.']++)[ ]*+(.+?)[ ]*+(? strlen($matches[0]), + 'element' => array( + 'name' => 'code', + 'text' => $text, + ), + ); + } + } + + protected function inlineEmailTag($Excerpt) + { + $hostnameLabel = '[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?'; + + $commonMarkEmail = '[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]++@' + . $hostnameLabel . '(?:\.' . $hostnameLabel . ')*'; + + if (strpos($Excerpt['text'], '>') !== false + and preg_match("/^<((mailto:)?$commonMarkEmail)>/i", $Excerpt['text'], $matches) + ){ + $url = $matches[1]; + + if ( ! isset($matches[2])) + { + $url = "mailto:$url"; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $matches[1], + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + protected function inlineEmphasis($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + $marker = $Excerpt['text'][0]; + + if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'strong'; + } + elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'em'; + } + else + { + return; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => $emphasis, + 'handler' => array( + 'function' => 'lineElements', + 'argument' => $matches[1], + 'destination' => 'elements', + ) + ), + ); + } + + protected function inlineEscapeSequence($Excerpt) + { + if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters)) + { + return array( + 'element' => array('rawHtml' => $Excerpt['text'][1]), + 'extent' => 2, + ); + } + } + + protected function inlineImage($Excerpt) + { + if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[') + { + return; + } + + $Excerpt['text']= substr($Excerpt['text'], 1); + + $Link = $this->inlineLink($Excerpt); + + if ($Link === null) + { + return; + } + + $Inline = array( + 'extent' => $Link['extent'] + 1, + 'element' => array( + 'name' => 'img', + 'attributes' => array( + 'class' => 'post__img', + 'src' => $Link['element']['attributes']['href'], + 'alt' => $Link['element']['handler']['argument'], + ), + 'autobreak' => true, + ), + ); + + $Inline['element']['attributes'] += $Link['element']['attributes']; + + unset($Inline['element']['attributes']['href']); + + return $Inline; + } + + protected function inlineLink($Excerpt) + { + $Element = array( + 'name' => 'a', + 'handler' => array( + 'function' => 'lineElements', + 'argument' => null, + 'destination' => 'elements', + ), + 'nonNestables' => array('Url', 'Link'), + 'attributes' => array( + 'class' => 'post__links', + 'href' => null, + 'title' => null, + ), + ); + + $extent = 0; + + $remainder = $Excerpt['text']; + + if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) + { + $Element['handler']['argument'] = $matches[1]; + + $extent += strlen($matches[0]); + + $remainder = substr($remainder, $extent); + } + else + { + return; + } + + if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*+"|\'[^\']*+\'))?\s*+[)]/', $remainder, $matches)) + { + $Element['attributes']['href'] = $matches[1]; + + if (isset($matches[2])) + { + $Element['attributes']['title'] = substr($matches[2], 1, - 1); + } + + $extent += strlen($matches[0]); + } + else + { + if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) + { + $definition = strlen($matches[1]) ? $matches[1] : $Element['handler']['argument']; + $definition = strtolower($definition); + + $extent += strlen($matches[0]); + } + else + { + $definition = strtolower($Element['handler']['argument']); + } + + if ( ! isset($this->DefinitionData['Reference'][$definition])) + { + return; + } + + $Definition = $this->DefinitionData['Reference'][$definition]; + + $Element['attributes']['href'] = $Definition['url']; + $Element['attributes']['title'] = $Definition['title']; + } + + return array( + 'extent' => $extent, + 'element' => $Element, + ); + } + + protected function inlineMarkup($Excerpt) + { + if ($this->markupEscaped or $this->safeMode or strpos($Excerpt['text'], '>') === false) + { + return; + } + + if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*+[ ]*+>/s', $Excerpt['text'], $matches)) + { + return array( + 'element' => array('rawHtml' => $matches[0]), + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches)) + { + return array( + 'element' => array('rawHtml' => $matches[0]), + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w[\w-]*+(?:[ ]*+'.$this->regexHtmlAttribute.')*+[ ]*+\/?>/s', $Excerpt['text'], $matches)) + { + return array( + 'element' => array('rawHtml' => $matches[0]), + 'extent' => strlen($matches[0]), + ); + } + } + + protected function inlineSpecialCharacter($Excerpt) + { + if (substr($Excerpt['text'], 1, 1) !== ' ' and strpos($Excerpt['text'], ';') !== false + and preg_match('/^&(#?+[0-9a-zA-Z]++);/', $Excerpt['text'], $matches) + ) { + return array( + 'element' => array('rawHtml' => '&' . $matches[1] . ';'), + 'extent' => strlen($matches[0]), + ); + } + + return; + } + + protected function inlineStrikethrough($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) + { + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'del', + 'handler' => array( + 'function' => 'lineElements', + 'argument' => $matches[1], + 'destination' => 'elements', + ) + ), + ); + } + } + + protected function inlineUrl($Excerpt) + { + if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/') + { + return; + } + + if (strpos($Excerpt['context'], 'http') !== false + and preg_match('/\bhttps?+:[\/]{2}[^\s<]+\b\/*+/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE) + ) { + $url = $matches[0][0]; + + $Inline = array( + 'extent' => strlen($matches[0][0]), + 'position' => $matches[0][1], + 'element' => array( + 'name' => 'a', + 'text' => $url, + 'attributes' => array( + 'href' => $url, + ), + ), + ); + + return $Inline; + } + } + + protected function inlineUrlTag($Excerpt) + { + if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w++:\/{2}[^ >]++)>/i', $Excerpt['text'], $matches)) + { + $url = $matches[1]; + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $url, + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + # ~ + + protected function unmarkedText($text) + { + $Inline = $this->inlineText($text); + return $this->element($Inline['element']); + } + + # + # Handlers + # + + protected function handle(array $Element) + { + if (isset($Element['handler'])) + { + if (!isset($Element['nonNestables'])) + { + $Element['nonNestables'] = array(); + } + + if (is_string($Element['handler'])) + { + $function = $Element['handler']; + $argument = $Element['text']; + unset($Element['text']); + $destination = 'rawHtml'; + } + else + { + $function = $Element['handler']['function']; + $argument = $Element['handler']['argument']; + $destination = $Element['handler']['destination']; + } + + $Element[$destination] = $this->{$function}($argument, $Element['nonNestables']); + + if ($destination === 'handler') + { + $Element = $this->handle($Element); + } + + unset($Element['handler']); + } + + return $Element; + } + + protected function handleElementRecursive(array $Element) + { + return $this->elementApplyRecursive(array($this, 'handle'), $Element); + } + + protected function handleElementsRecursive(array $Elements) + { + return $this->elementsApplyRecursive(array($this, 'handle'), $Elements); + } + + protected function elementApplyRecursive($closure, array $Element) + { + $Element = call_user_func($closure, $Element); + + if (isset($Element['elements'])) + { + $Element['elements'] = $this->elementsApplyRecursive($closure, $Element['elements']); + } + elseif (isset($Element['element'])) + { + $Element['element'] = $this->elementApplyRecursive($closure, $Element['element']); + } + + return $Element; + } + + protected function elementApplyRecursiveDepthFirst($closure, array $Element) + { + if (isset($Element['elements'])) + { + $Element['elements'] = $this->elementsApplyRecursiveDepthFirst($closure, $Element['elements']); + } + elseif (isset($Element['element'])) + { + $Element['element'] = $this->elementsApplyRecursiveDepthFirst($closure, $Element['element']); + } + + $Element = call_user_func($closure, $Element); + + return $Element; + } + + protected function elementsApplyRecursive($closure, array $Elements) + { + foreach ($Elements as &$Element) + { + $Element = $this->elementApplyRecursive($closure, $Element); + } + + return $Elements; + } + + protected function elementsApplyRecursiveDepthFirst($closure, array $Elements) + { + foreach ($Elements as &$Element) + { + $Element = $this->elementApplyRecursiveDepthFirst($closure, $Element); + } + + return $Elements; + } + + protected function element(array $Element) + { + if ($this->safeMode) + { + $Element = $this->sanitiseElement($Element); + } + + # identity map if element has no handler + $Element = $this->handle($Element); + + $hasName = isset($Element['name']); + + $markup = ''; + + if ($hasName) + { + $markup .= '<' . $Element['name']; + + if (isset($Element['attributes'])) + { + foreach ($Element['attributes'] as $name => $value) + { + if ($value === null) + { + continue; + } + + $markup .= " $name=\"".self::escape($value).'"'; + } + } + } + + $permitRawHtml = false; + + if (isset($Element['text'])) + { + $text = $Element['text']; + } + // very strongly consider an alternative if you're writing an + // extension + elseif (isset($Element['rawHtml'])) + { + $text = $Element['rawHtml']; + + $allowRawHtmlInSafeMode = isset($Element['allowRawHtmlInSafeMode']) && $Element['allowRawHtmlInSafeMode']; + $permitRawHtml = !$this->safeMode || $allowRawHtmlInSafeMode; + } + + $hasContent = isset($text) || isset($Element['element']) || isset($Element['elements']); + + if ($hasContent) + { + $markup .= $hasName ? '>' : ''; + + if (isset($Element['elements'])) + { + $markup .= $this->elements($Element['elements']); + } + elseif (isset($Element['element'])) + { + $markup .= $this->element($Element['element']); + } + else + { + if (!$permitRawHtml) + { + $markup .= self::escape($text, true); + } + else + { + $markup .= $text; + } + } + + $markup .= $hasName ? '' : ''; + } + elseif ($hasName) + { + $markup .= ' />'; + } + + return $markup; + } + + protected function elements(array $Elements) + { + $markup = ''; + + $autoBreak = true; + + foreach ($Elements as $Element) + { + if (empty($Element)) + { + continue; + } + + $autoBreakNext = (isset($Element['autobreak']) + ? $Element['autobreak'] : isset($Element['name']) + ); + // (autobreak === false) covers both sides of an element + $autoBreak = !$autoBreak ? $autoBreak : $autoBreakNext; + + $markup .= ($autoBreak ? "\n" : '') . $this->element($Element); + $autoBreak = $autoBreakNext; + } + + $markup .= $autoBreak ? "\n" : ''; + + return $markup; + } + + # ~ + + protected function li($lines) + { + $Elements = $this->linesElements($lines); + + if ( ! in_array('', $lines) + and isset($Elements[0]) and isset($Elements[0]['name']) + and $Elements[0]['name'] === 'p' + ) { + unset($Elements[0]['name']); + } + + return $Elements; + } + + # + # AST Convenience + # + + /** + * Replace occurrences $regexp with $Elements in $text. Return an array of + * elements representing the replacement. + */ + protected static function pregReplaceElements($regexp, $Elements, $text) + { + $newElements = array(); + + while (preg_match($regexp, $text, $matches, PREG_OFFSET_CAPTURE)) + { + $offset = $matches[0][1]; + $before = substr($text, 0, $offset); + $after = substr($text, $offset + strlen($matches[0][0])); + + $newElements[] = array('text' => $before); + + foreach ($Elements as $Element) + { + $newElements[] = $Element; + } + + $text = $after; + } + + $newElements[] = array('text' => $text); + + return $newElements; + } + + # + # Deprecated Methods + # + + function parse($text) + { + $markup = $this->text($text); + + return $markup; + } + + protected function sanitiseElement(array $Element) + { + static $goodAttribute = '/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/'; + static $safeUrlNameToAtt = array( + 'a' => 'href', + 'img' => 'src', + ); + + if ( ! isset($Element['name'])) + { + unset($Element['attributes']); + return $Element; + } + + if (isset($safeUrlNameToAtt[$Element['name']])) + { + $Element = $this->filterUnsafeUrlInAttribute($Element, $safeUrlNameToAtt[$Element['name']]); + } + + if ( ! empty($Element['attributes'])) + { + foreach ($Element['attributes'] as $att => $val) + { + # filter out badly parsed attribute + if ( ! preg_match($goodAttribute, $att)) + { + unset($Element['attributes'][$att]); + } + # dump onevent attribute + elseif (self::striAtStart($att, 'on')) + { + unset($Element['attributes'][$att]); + } + } + } + + return $Element; + } + + protected function filterUnsafeUrlInAttribute(array $Element, $attribute) + { + foreach ($this->safeLinksWhitelist as $scheme) + { + if (self::striAtStart($Element['attributes'][$attribute], $scheme)) + { + return $Element; + } + } + + $Element['attributes'][$attribute] = str_replace(':', '%3A', $Element['attributes'][$attribute]); + + return $Element; + } + + # + # Static Methods + # + + protected static function escape($text, $allowQuotes = false) + { + return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8'); + } + + protected static function striAtStart($string, $needle) + { + $len = strlen($needle); + + if ($len > strlen($string)) + { + return false; + } + else + { + return strtolower(substr($string, 0, $len)) === strtolower($needle); + } + } + + static function instance($name = 'default') + { + if (isset(self::$instances[$name])) + { + return self::$instances[$name]; + } + + $instance = new static(); + + self::$instances[$name] = $instance; + + return $instance; + } + + private static $instances = array(); + + # + # Fields + # + + protected $DefinitionData; + + # + # Read-Only + + protected $specialCharacters = array( + '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|', '~' + ); + + protected $StrongRegex = array( + '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*+[*])+?)[*]{2}(?![*])/s', + '_' => '/^__((?:\\\\_|[^_]|_[^_]*+_)+?)__(?!_)/us', + ); + + protected $EmRegex = array( + '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', + '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', + ); + + protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*+(?:\s*+=\s*+(?:[^"\'=<>`\s]+|"[^"]*+"|\'[^\']*+\'))?+'; + + protected $voidElements = array( + 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', + ); + + protected $textLevelElements = array( + 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', + 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', + 'i', 'rp', 'del', 'code', 'strike', 'marquee', + 'q', 'rt', 'ins', 'font', 'strong', + 's', 'tt', 'kbd', 'mark', + 'u', 'xm', 'sub', 'nobr', + 'sup', 'ruby', + 'var', 'span', + 'wbr', 'time', + ); +} \ No newline at end of file diff --git a/blog/ctf.php b/blog/ctf.php new file mode 100644 index 0000000..d8f58b0 --- /dev/null +++ b/blog/ctf.php @@ -0,0 +1,79 @@ + + + + + + + + Blog + + + +
+
+ + + + +
+
+
+ text(fread($myblog, filesize("markdowns/ctf.md"))); + fclose($myblog); + ?> +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/blog/drive.php b/blog/drive.php new file mode 100644 index 0000000..1663899 --- /dev/null +++ b/blog/drive.php @@ -0,0 +1,68 @@ + + + + + + + + Driving Blog + + + +
+
+

Hello World

+ +
+
+
+ text(fread($myblog, filesize("markdowns/blog.md"))); + fclose($myblog); + ?> +
+ +
+
+ + diff --git a/blog/markdowns/blog.md b/blog/markdowns/blog.md new file mode 100644 index 0000000..9c8555f --- /dev/null +++ b/blog/markdowns/blog.md @@ -0,0 +1,50 @@ + +============ + +> *markup.rocks* is a client-side app that lets you **edit**, **preview** and +> **convert** between documents written in various markup languages in your +> browser. + +---- + +## Open source! +Check out markup.rocks on [github] to view the source code, file issues and +contribute. + +markup.rocks wouldn't be possible without these open source projects: + +* [GHCJS] - Amazing Haskell to JavaScript compiler +* [Pandoc] - Extraordinary document converter which I shamelessly compiled to + JS and built an interface around +* [Reflex] and [Reflex-DOM] - Great set of libraries that hold this app + together with the Functional Reactive Programming constructs they provide. + +1. First item +2. Second item + - Nested item +3. Third item + +- Item 1 +- Item 2 + - Subitem 1 + - Subitem 2 +- Item 3 + + +### Building + +The easiest way to get a working GHCJS installation is to use the provided +nix-based build environment. + +```bash +$ git clone https://github.com/osener/markup.rocks.env +$ git clone https://github.com/osener/markup.rocks +$ markup.rocks.env/activate # this will take a while +$ make -C markup.rocks +``` + +[github]:https://github.com/osener/markup.rocks +[GHCJS]:https://github.com/ghcjs/ghcjs +[Pandoc]:http://pandoc.org/ +[Reflex]:https://github.com/ryantrinkle/reflex +[Reflex-DOM]:https://github.com/ryantrinkle/reflex-dom diff --git a/blog/markdowns/ctf.md b/blog/markdowns/ctf.md new file mode 100644 index 0000000..730f5c6 --- /dev/null +++ b/blog/markdowns/ctf.md @@ -0,0 +1,24 @@ +# I'm done with the CTF + +I recently took on an exciting challenge to complete a Capture The Flag (CTF) for WordPress, and I managed to find all three keys! + +## First Key + +![First key image](/Webster/media/blogs/ctf/8hKuBbzL.jpg) + +The first key, with the value **073403c8a58a1f80d943455fb30724b9**, was found at the address `http://[IP ADDRESS OF MR.ROBOT]/key-1-of-3.txt`. It felt amazing to find this key and get one step closer to completing the challenge. + +## Second Key + +![Second key image](/Webster/media/blogs/ctf/QKNmVAwi.jpg) + +Next, I found the second key, with the value **822c73956184f694993bede3eb39f959**, in the `home/robot` directory. It was a euphoric moment to find this key and realize that I was getting closer to the end goal. + +## Third Key + +![Third key image](/Webster/media/blogs/ctf/p8UpweNt.jpg) + +The third key, with the value **04787ddef27c3dee1ee161b21670b4e4**, was located in the root directory. It was a challenging hunt, but it felt amazing when I also found this key and successfully completed the challenge. + + +Overall, it was a great experience to do this CTF for WordPress, and I'm happy to have found all three keys. It tested my skills and helped me expand my knowledge. I'm already looking forward to the next challenge! \ No newline at end of file diff --git a/blogs.php b/blogs.php new file mode 100644 index 0000000..316a1f4 --- /dev/null +++ b/blogs.php @@ -0,0 +1,102 @@ + + + + + + + + Articles + + + +
+
+ + + + +
+
+
+
+

+
+

+ "; + foreach ($json_data['blogs']['items'] as $blogs) { + $html .= "
  • "; + $html .= "" . $blogs['text'][$lang] . ""; + $html .= "" . $blogs['subtext'][$lang] . ""; + $html .= ""; + $html .= "
  • "; + } + $html .= ""; + + echo $html; + ?> +
    +
    +
    +
    + +
    + + \ No newline at end of file diff --git a/halted/check.php b/halted/check.php new file mode 100644 index 0000000..a4abe2d --- /dev/null +++ b/halted/check.php @@ -0,0 +1,2 @@ + + + + + + + Portofolio + + + + +
    +
    + + + + +
    +
    +

    These are SD webrings:

    + '. $website['title']. '
    '; + } + }?> +
    + +
    + + + + + + diff --git a/index.php b/index.php new file mode 100644 index 0000000..9d4f886 --- /dev/null +++ b/index.php @@ -0,0 +1,144 @@ + + + + + + + + Portofolio + + + + +
    +
    + + + + +
    +
    +
    +
    + + alt=""> +
    + alt=""> +
    + alt=""> +
    +
    + '; + foreach ($json_data['socials']['links'] as $link) { + $html .= ''; + $html .= '' . htmlspecialchars($link['iconAlt']) . ''; + $html .= ''; + } + + $html .= ''; + $html .= '
    '; + + echo $html; + ?> + +
    +
    +
      +
    • + python icon + php icon + javascript icon + css icon +
    +
      +
    • +
      +
    • github icon
    • +
    • website icon
    • +
      +
    • +
    +
  • +
      +
    • +
      + +
      +
    +
      +
    • +
      +
    • + NL +
    • +
    • + EN +
    • +
    • + ID +
    • +
      +
    +
  • +
    +
    + +
    + + \ No newline at end of file diff --git a/json/blogs.json b/json/blogs.json new file mode 100644 index 0000000..6444ee4 --- /dev/null +++ b/json/blogs.json @@ -0,0 +1,36 @@ +{ + "blogs": { + "items": [ + { + "class": "blog__list", + "href": "blog/drive.php", + "text": { + "en": "Auto driving in brief", + "nl": "Auto rijden in het kort", + "id": "Mengemudi mobil secara singkat" + }, + "subtext": { + "en": "A short introduction about automating control systems.", + "nl": "Een korte inleiding over het automatiseren van controlesystemen.", + "id": "Pengantar singkat tentang sistem kontrol otomatis." + }, + "date": "2023-05-10" + }, + { + "class": "blog__list", + "href": "blog/ctf.php", + "text": { + "en": "I'm done with the CTF", + "nl": "Ik ben klaar met de CTF", + "id": "Saya menyelesaikan CTF" + }, + "subtext": { + "en": "Report of my recent challenge to complete a Capture The Flag (CTF) for WordPress.", + "nl": "Verslag van mijn recente uitdaging om een Capture The Flag (CTF) voor WordPress te voltooien.", + "id": "Laporan tentang tantangan saya baru-baru ini untuk menyelesaikan Capture The Flag (CTF) untuk WordPress." + }, + "date": "2023-05-15" + } + ] + } +} diff --git a/json/projects.json b/json/projects.json new file mode 100644 index 0000000..10fdbe3 --- /dev/null +++ b/json/projects.json @@ -0,0 +1,56 @@ +{ + "projects": [ + { + "title": { + "en": "National Videogame Museum Redesign Website.", + "nl": "National Videogame Museum Herontwerp Website.", + "id": "Desain Ulang Situs Web Museum Videogame Nasional." + }, + "links": [ + { + "type": "GitHub", + "url": "https://github.com/JerukPurut404/EindOpdrachtVGM", + "icon": "github.svg" + }, + { + "type": "Website", + "url": "https://35023.hosts1.ma-cloud.nl/EindOpdrachtVGM/Eugene's_folder/index.html", + "icon": "globe.svg" + } + ] + }, + { + "title": { + "en": "Discontinued 9292chan", + "nl": "Stopgezette 9292chan", + "id": "Dihentikan 9292chan" + }, + "links": [ + { + "type": "GitHub", + "url": "https://github.com/JerukPurut404/9292chan", + "icon": "github.svg" + } + ] + }, + { + "title": { + "en": "Based Dictionary", + "nl": "Based Woordenboek", + "id": "Kamus Based" + }, + "links": [ + { + "type": "GitHub", + "url": "https://github.com/JerukPurut404/BasedDictionary", + "icon": "github.svg" + }, + { + "type": "Website", + "url": "https://35023.hosts1.ma-cloud.nl/baseddict/", + "icon": "globe.svg" + } + ] + } + ] +} diff --git a/json/socials.json b/json/socials.json new file mode 100644 index 0000000..8238eb1 --- /dev/null +++ b/json/socials.json @@ -0,0 +1,28 @@ +{ + "socials": { + "type": "div", + "className": "content__menu", + "links": [ + { + "href": "mailto:privateduck@renn.es", + "iconSrc": "media/mail.svg", + "iconAlt": "mail icon" + }, + { + "href": "https://github.com/JerukPurut404", + "iconSrc": "media/github.svg", + "iconAlt": "github icon" + }, + { + "href": "https://anilist.co/user/JerukPurut/", + "iconSrc": "media/anilist.svg", + "iconAlt": "Anilist icon" + }, + { + "href": "https://www.linkedin.com/in/e-van-aubel", + "iconSrc": "media/linkedin.svg", + "iconAlt": "linkedin icon" + } + ] + } +} diff --git a/media/Keren.jpg b/media/Keren.jpg new file mode 100644 index 0000000..1626714 Binary files /dev/null and b/media/Keren.jpg differ diff --git a/media/achteruit.jpg b/media/achteruit.jpg new file mode 100644 index 0000000..1df2700 Binary files /dev/null and b/media/achteruit.jpg differ diff --git a/media/anilist.svg b/media/anilist.svg new file mode 100644 index 0000000..bb19116 --- /dev/null +++ b/media/anilist.svg @@ -0,0 +1 @@ +AniList \ No newline at end of file diff --git a/media/blogs/ctf/8hKuBbzL.jpg b/media/blogs/ctf/8hKuBbzL.jpg new file mode 100644 index 0000000..7d54d5a Binary files /dev/null and b/media/blogs/ctf/8hKuBbzL.jpg differ diff --git a/media/blogs/ctf/QKNmVAwi.jpg b/media/blogs/ctf/QKNmVAwi.jpg new file mode 100644 index 0000000..d2c55e4 Binary files /dev/null and b/media/blogs/ctf/QKNmVAwi.jpg differ diff --git a/media/blogs/ctf/p8UpweNt.jpg b/media/blogs/ctf/p8UpweNt.jpg new file mode 100644 index 0000000..b8b97df Binary files /dev/null and b/media/blogs/ctf/p8UpweNt.jpg differ diff --git a/media/css3.svg b/media/css3.svg new file mode 100644 index 0000000..5ca6bec --- /dev/null +++ b/media/css3.svg @@ -0,0 +1 @@ +CSS3 \ No newline at end of file diff --git a/media/file-parkeren.jpg b/media/file-parkeren.jpg new file mode 100644 index 0000000..5828896 Binary files /dev/null and b/media/file-parkeren.jpg differ diff --git a/media/github.svg b/media/github.svg new file mode 100644 index 0000000..a894c85 --- /dev/null +++ b/media/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/globe.svg b/media/globe.svg new file mode 100644 index 0000000..276b03d --- /dev/null +++ b/media/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/ik-ben-e-van-aubel.svg b/media/handwriting/ik-ben-e-van-aubel.svg new file mode 100644 index 0000000..85621a1 --- /dev/null +++ b/media/handwriting/ik-ben-e-van-aubel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/ik-ben-een-software-developer.svg b/media/handwriting/ik-ben-een-software-developer.svg new file mode 100644 index 0000000..4fab5fd --- /dev/null +++ b/media/handwriting/ik-ben-een-software-developer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/im-a-software-developer.svg b/media/handwriting/im-a-software-developer.svg new file mode 100644 index 0000000..12c2d75 --- /dev/null +++ b/media/handwriting/im-a-software-developer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/im-e-van-aubel.svg b/media/handwriting/im-e-van-aubel.svg new file mode 100644 index 0000000..ad7f13c --- /dev/null +++ b/media/handwriting/im-e-van-aubel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/nama-saya-e-van-aubel.svg b/media/handwriting/nama-saya-e-van-aubel.svg new file mode 100644 index 0000000..d1dcaac --- /dev/null +++ b/media/handwriting/nama-saya-e-van-aubel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/saya-seorang-software-developer.svg b/media/handwriting/saya-seorang-software-developer.svg new file mode 100644 index 0000000..f702d4a --- /dev/null +++ b/media/handwriting/saya-seorang-software-developer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/selamat-datang.svg b/media/handwriting/selamat-datang.svg new file mode 100644 index 0000000..d8fef5c --- /dev/null +++ b/media/handwriting/selamat-datang.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/welcome.svg b/media/handwriting/welcome.svg new file mode 100644 index 0000000..838bd7d --- /dev/null +++ b/media/handwriting/welcome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/handwriting/welkom.svg b/media/handwriting/welkom.svg new file mode 100644 index 0000000..8397205 --- /dev/null +++ b/media/handwriting/welkom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/javascript.svg b/media/javascript.svg new file mode 100644 index 0000000..91e5162 --- /dev/null +++ b/media/javascript.svg @@ -0,0 +1 @@ +JavaScript \ No newline at end of file diff --git a/media/linkedin.svg b/media/linkedin.svg new file mode 100644 index 0000000..ce8a03e --- /dev/null +++ b/media/linkedin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/mail.svg b/media/mail.svg new file mode 100644 index 0000000..f77e090 --- /dev/null +++ b/media/mail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/media/php.svg b/media/php.svg new file mode 100644 index 0000000..a08156a --- /dev/null +++ b/media/php.svg @@ -0,0 +1 @@ +PHP \ No newline at end of file diff --git a/media/python.svg b/media/python.svg new file mode 100644 index 0000000..30587d8 --- /dev/null +++ b/media/python.svg @@ -0,0 +1 @@ +Python \ No newline at end of file diff --git a/media/vooruit.jpg b/media/vooruit.jpg new file mode 100644 index 0000000..94d59ba Binary files /dev/null and b/media/vooruit.jpg differ diff --git a/old_html_pages/old_index.html b/old_html_pages/old_index.html new file mode 100644 index 0000000..b65f938 --- /dev/null +++ b/old_html_pages/old_index.html @@ -0,0 +1,100 @@ + + + + + + + Portofolio + + + + +
    +
    + + + + +
    +
    +
    +
    + + +
    + +
    + +
    +
    +
    +
    + mail icon + github icon + Anilist icon + linkedin icon + +
    +
    +
    +
    +
      +
    • Highlighted Skills
    • + python icon + php icon + javascript icon + css icon +
    +
      +
    • Highlighted Project
    • +
      +
    • github icon
    • +
    • website icon
    • +
      +
    • National Videogame Museum Redesign Website.
    • +
    +
  • +
      +
    • Highlighted Project 1
    • +
      +
    • github icon
    • +
    • website icon
    • +
      +
    • National Videogame Museum Redesign Website.
    • +
    +
      +
    • Highlighted Project 2
    • +
      +
    • github icon
    • +
    • website icon
    • +
      +
    • National Videogame Museum Redesign Website.
    • +
    +
  • + +
    +
    +
    + +
    +
    + + \ No newline at end of file diff --git a/old_html_pages/old_projects.html b/old_html_pages/old_projects.html new file mode 100644 index 0000000..7be8ad6 --- /dev/null +++ b/old_html_pages/old_projects.html @@ -0,0 +1,71 @@ + + + + + + Projects + + + +
    +
    + + + + +
    +
    +
    +
    +

    Projects

    +
    +

    These are my previous projects in my school and all of them are avaliable in Github

    +
      +
      +
    • github icon
    • +
    • website icon
    • +
      +
    • National Videogame Museum Redesign Website.
    • +
    +
      +
      +
    • github icon
    • +
      +
    • Discontinued 9292chan
    • +
    +
      +
      +
    • github icon
    • +
    • website icon
    • +
      +
    • Based Dictionary
    • +
    +
    +
    +
    + +
    + + \ No newline at end of file diff --git a/projects.php b/projects.php new file mode 100644 index 0000000..37959dd --- /dev/null +++ b/projects.php @@ -0,0 +1,88 @@ + + + + + + + <?php echo t('Projects'); ?> + + + +
    +
    + + + + +
    +
    +
    +
    +

    +
    +

    + "; + echo "
    "; + foreach ($project['links'] as $link) { + echo "
  • " . htmlspecialchars($link[
  • "; + } + echo "
    "; + echo "
  • " . htmlspecialchars($project['title'][$currentLang]) . "
  • "; + echo ""; + } + ?> +
    +
    +
    +
    + +
    +
    + + diff --git a/src/languages.php b/src/languages.php new file mode 100644 index 0000000..1ad6fb6 --- /dev/null +++ b/src/languages.php @@ -0,0 +1,82 @@ + 'Dutch', 'en' => 'English', 'id' => 'Indonesian']; + +$translations = [ + 'en' => [ + 'About' => 'About', + 'About me' => 'About me', + 'Projects' => 'Projects', + 'Blogs' => 'Blogs', + 'Highlighted Skills' => 'Highlighted Skills', + 'Highlighted Project' => 'Highlighted Project', + 'National Videogame Museum Redesign Website.' => 'National Videogame Museum Redesign Website.', + 'Made by E. van Aubel' => 'Made by E. van Aubel', + 'media/handwriting/welcome.svg' => 'media/handwriting/welcome.svg', + 'media/handwriting/im-e-van-aubel.svg' => 'media/handwriting/im-e-van-aubel.svg', + 'media/handwriting/im-a-software-developer.svg' => 'media/handwriting/im-a-software-developer.svg', + "These are my own articles/blog mostly about my own projects, rant's, thought's etc" => "These are my own articles/blog mostly about my own projects, rant's, thought's etc", + "These are my previous projects in my school and all of them are avaliable in Github" => "These are my previous projects in my school and all of them are avaliable in Github", + "View my CV here:" => "View my CV here", + "Go to my CV" => "Go to my CV", + "Select Language:" => "Select Language:", + "E. Van Aubel is a software development student who is scared of CSS and is living in Amsterdam, Netherlands. They are passionate about free and open-source software and privacy advocacy. Their skills include programming in Python and JavaScript, web development with CSS and HTML, and proficiency in the Laravel framework and Tailwind CSS. E. Van Aubel enjoys movies, anime, and music in their free time. They are equipped with an HP 15s-eq0xxx laptop featuring an AMD Ryzen 3 3200U processor. This young developer is well-positioned to contribute to innovative tech projects with their growing expertise in software development and commitment to open-source principles." => "E. Van Aubel is a software development student who is scared of CSS and is living in Amsterdam, Netherlands. They are passionate about free and open-source software and privacy advocacy. Their skills include programming in Python and JavaScript, web development with CSS and HTML, and proficiency in the Laravel framework and Tailwind CSS. E. Van Aubel enjoys movies, anime, and music in their free time. They are equipped with an HP 15s-eq0xxx laptop featuring an AMD Ryzen 3 3200U processor. This young developer is well-positioned to contribute to innovative tech projects with their growing expertise in software development and commitment to open-source principles." + + ], + 'nl' => [ + 'About' => 'Over', + 'About me' => 'Over mij', + 'Projects' => 'Projecten', + 'Blogs' => 'Blogs', + 'Highlighted Skills' => 'Uitgelichte Vaardigheden', + 'Highlighted Project' => 'Uitgelichte Projecten', + 'National Videogame Museum Redesign Website.' => 'Herontwerp website Nationaal Videogame Museum.', + 'Made by E. van Aubel' => 'Gemaakt door E. van Aubel', + 'media/handwriting/welcome.svg' => 'media/handwriting/welkom.svg', + 'media/handwriting/im-e-van-aubel.svg' => 'media/handwriting/ik-ben-e-van-aubel.svg', + 'media/handwriting/im-a-software-developer.svg' => 'media/handwriting/ik-ben-een-software-developer.svg', + "These are my own articles/blog mostly about my own projects, rant's, thought's etc" => "Dit zijn mijn eigen artikelen/blogs over mijn eigen projecten, rant's, gedachten enz.", + "These are my previous projects in my school and all of them are avaliable in Github" => "Dit zijn mijn vorige projecten op mijn school en ze zijn allemaal beschikbaar op Github", + "View my CV here:" => "Bekijk mijn CV hier:", + "Go to my CV" => "Ga nu naar mijn CV", + "Select Language:" => "Selecteer taal:", + "E. Van Aubel is a software development student who is scared of CSS and is living in Amsterdam, Netherlands. They are passionate about free and open-source software and privacy advocacy. Their skills include programming in Python and JavaScript, web development with CSS and HTML, and proficiency in the Laravel framework and Tailwind CSS. E. Van Aubel enjoys movies, anime, and music in their free time. They are equipped with an HP 15s-eq0xxx laptop featuring an AMD Ryzen 3 3200U processor. This young developer is well-positioned to contribute to innovative tech projects with their growing expertise in software development and commitment to open-source principles." => "E. Van Aubel is een student softwareontwikkeling die bang is voor CSS en woont in Amsterdam, Nederland. Ze zijn gepassioneerd door vrije en open-source software en privacy advocacy. Hun vaardigheden omvatten programmeren in Python en JavaScript, webontwikkeling met CSS en HTML, en vaardigheid in het Laravel framework en Tailwind CSS. E. Van Aubel houdt in hun vrije tijd van films, anime en muziek. Hij is uitgerust met een HP 15s-eq0xxx laptop met een AMD Ryzen 3 3200U processor. Deze jonge ontwikkelaar is goed gepositioneerd om bij te dragen aan innovatieve technische projecten met hun groeiende expertise in softwareontwikkeling en toewijding aan open-source principes." + ], + 'id' => [ + 'About' => 'Tentang', + 'About me' => 'Tentang saya', + 'Projects' => 'Proyek', + 'Blogs' => 'Blogs', + 'Highlighted Skills' => 'Sorotan Keterampilan', + 'Highlighted Project' => 'Sorotan Proyek', + 'National Videogame Museum Redesign Website.' => 'Desain Ulang Situs Web Museum Videogame Nasional.', + 'Made by E. van Aubel' => 'Dibuat oleh E. van Aubel', + 'media/handwriting/welcome.svg' => 'media/handwriting/selamat-datang.svg', + 'media/handwriting/im-e-van-aubel.svg' => 'media/handwriting/nama-saya-e-van-aubel.svg', + 'media/handwriting/im-a-software-developer.svg' => 'media/handwriting/saya-seorang-software-developer.svg', + "These are my own articles/blog mostly about my own projects, rant's, thought's etc" => "Ini adalah artikel/blog saya sendiri yang sebagian besar berisi tentang proyek-proyek saya sendiri, ocehan, pemikiran, dan lain-lain", + "These are my previous projects in my school and all of them are avaliable in Github" => "Ini adalah proyek-proyek saya sebelumnya di sekolah saya dan semuanya tersedia di Github", + "View my CV here:" => "Lihat CV saya di sini:", + "Go to my CV" => "Pergi ke CV saya", + "Select Language:" => "Pilih bahasa:", + "E. Van Aubel is a software development student who is scared of CSS and is living in Amsterdam, Netherlands. They are passionate about free and open-source software and privacy advocacy. Their skills include programming in Python and JavaScript, web development with CSS and HTML, and proficiency in the Laravel framework and Tailwind CSS. E. Van Aubel enjoys movies, anime, and music in their free time. They are equipped with an HP 15s-eq0xxx laptop featuring an AMD Ryzen 3 3200U processor. This young developer is well-positioned to contribute to innovative tech projects with their growing expertise in software development and commitment to open-source principles." => "E. Van Aubel adalah seorang mahasiswa software developer yang takut dengan CSS dan tinggal di Amsterdam, Belanda. Mereka sangat menyukai free and open-source software serta advokasi privasi. Keahlian mereka meliputi pemrograman dalam Python dan JavaScript, pengembangan web dengan CSS dan HTML, serta kemahiran dalam kerangka kerja Laravel dan Tailwind CSS. E. Van Aubel menikmati film, anime, dan musik di waktu luang mereka. Mereka dilengkapi dengan laptop HP 15s-eq0xxx yang dilengkapi dengan prosesor AMD Ryzen 3 3200U. Pengembang muda ini memiliki posisi yang tepat untuk berkontribusi pada proyek-proyek teknologi inovatif dengan keahlian mereka yang terus berkembang dalam pengembangan perangkat lunak dan komitmen terhadap prinsip-prinsip sumber terbuka." + ] +]; + diff --git a/style.css b/style.css new file mode 100644 index 0000000..811395f --- /dev/null +++ b/style.css @@ -0,0 +1,475 @@ +@keyframes typing { + from { width: 0 } + to { width: 100% } +} + +@keyframes blink-caret { + from, to { border-color: transparent } + 50% { border-color: white; } +} + + +*, *::before, *::after { + padding: 0; + margin: 0; + box-sizing: border-box; +} + +html { + font-size: 62.5%; + letter-spacing: 0.2rem; + scroll-behavior: smooth; +} + +body { + font-size: 2rem; + line-height: 1.5; + display: flex; + min-height: 100vh; + flex-direction: column; + background-color: #282a36; + color: #f8f8f2; +} + +a { + background-color: transparent; + text-decoration: none; + color: inherit; +} + +a:hover{ + text-decoration: underline white; +} + +button:hover{ + text-decoration: underline white; +} + + +hr { + margin: 4rem; +} + +.container { + display: flex; + flex-direction: column; + justify-content: center; + text-align: center; +} + +.header{ + margin-top: 2rem; + display: flex; + align-items: center; + padding: 0.5rem; + flex-direction: row; + justify-content: space-around; +} + +.header__inner{ + display: flex; + padding: 2rem; + max-width: 100%; +} + +.header__right{ + display: flex; + align-items: center; + justify-content: space-between; + margin: 0 auto; +} + +.logo__symbol{ + overflow: hidden; + border-right: .15em solid white; + white-space: nowrap; + margin: 0 auto; + animation: + typing 3.5s steps(40, end), + blink-caret .75s step-end infinite; +} + +.menu{ + border-right: 1px solid; + margin-right: 10px; + z-index: 9999; +} + +.menu__inner{ + gap: 2rem; + display: flex; + align-items: center; + justify-content: space-between; + list-style: none; +} + +.menu__inner li{ + display: flex; +} + +/* .content{ + display: flex; + flex-direction: column; + flex: 1 auto; + align-items: center; + justify-content: center; + margin: 0; +} */ + +.content__main{ + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + margin: 5rem; +} + +.content__div{ + margin: 2rem; + display: flex; + flex-direction: column; + gap: 2rem; + align-items: center; +} + +.content__main h1{ + font-size: 3rem; + font-weight: 500; + margin: 0.67em 0; +} + + +.icon__svg{ + filter: invert(85%) sepia(11%) saturate(825%) hue-rotate(195deg) brightness(101%) contrast(91%); + padding: 0 1rem; + margin: 0 1rem; + width: 50px; +} + +.icon__svg:hover{ + opacity: 50%; + outline-color:transparent; + outline-style: dotted; + box-shadow: 0 0 0 1px #7dc4e4; + transition: 0.7s; +} + +.profile__picture{ + display: flex; + align-items: center; + flex-direction: row; + width: 15%; + height: auto; + border-radius: 50%; +} + +.handwriting__svg{ + width: 25rem; +} + +.footer__content{ + display: flex; + justify-content: center; + gap: 2rem; + align-items: center; + padding-bottom: 2rem; +} + +.post{ + width: 100%; + max-width: 100rem; + padding: 2rem; + margin: 4rem auto; +} + +.post__info{ + margin-top: 3rem; + font-size: 0.8rem; + line-height: normal; + opacity: .6; +} + +.post__info p{ + font-size: 1.3rem; + margin: 0 .8em 0; +} + +.post__title{ + font-size: 2.5rem; + margin: 0 0 2rem; +} + +.post__content{ + display: flex; + flex-direction: column; + font-weight: 300; + overflow-wrap: break-word; + line-height: 1.5; +} + +.post__content p{ + margin-bottom: 1rem; + margin-top: 0; +} + +.post__subtext{ + display: flex; + flex-direction: row; + justify-content: center; +} + +.blog__content{ + display: flex; + margin-top: 3rem; +} + +.blog__content{ + display: flex; +} + +.post__icons{ + display: flex; + justify-content: center; +} + +.post__lists{ + padding: 1rem; + border: 1px solid #f8f8f2; + margin-bottom: 2rem; + margin-top: 2rem; + border-radius: 2rem; +} + +.post__list{ + display: flex; + align-items: center; + justify-content: center; + margin: 1rem; +} + +.blog__list{ + padding: 1rem; + border: 1px solid #8bd5ca; + list-style-type: none; +} + +.post__subtext { + color: #a5adcb; + flex-wrap: wrap; + font-size: 0.9em; + margin-top: 0.5em; +} + +.post__date { + color: #6e738d; + font-size: 0.8em; + margin-left: 1em; +} + +.box__list{ + display: flex; + align-items: center; + justify-content: center; + margin: 1rem; + flex-direction: row; +} + +.box__lists{ + padding: 1rem; + border: 1px solid #f8f8f2; + margin-bottom: 2rem; + margin-top: 2rem; + border-radius: 2rem; +} + + +.box-wrapper{ + display: flex; + gap: 3rem; + justify-content: space-between; +} + +.cv__button{ + display: flex; + justify-content: center; + border-radius: 2.5rem; + text-decoration: none; + padding: 1px 6px; + border: 1px outset buttonborder; + border-radius: 3px; + color: buttontext; + background-color: buttonface; + text-decoration: none; +} + +.language__button { + padding: 10px 15px; + margin: 5px; + background-color: #007bff; /* Bootstrap primary color */ + color: white; + text-decoration: none; + border-radius: 5px; +} + +.language__button:hover { + background-color: #0056b3; /* Darker shade on hover */ +} + +.post__article{ + display: flex; + flex-direction: column; +} + +.blog__article{ + display: flex; + flex-direction: column; + text-align: left; +} + +.blog__article blockquote{ + padding-left: 1rem; + border-left: .3rem solid #ed8796; + border-radius: 1rem; +} + +.blog__article ul{ + padding: 1rem; +} + +.post__img { + display: block; + margin-left: auto; + border-radius: .5rem; + margin-right: auto; + object-fit: cover; + max-width: 50%; + height: auto; +} + +.post__description { + flex: 2; +} + +.post__text{ + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.post__subtext{ + text-align: left; + line-height: 3rem; +} + +.post__links{ + font-weight: 600; + text-decoration: underline; + text-decoration-color: #a5adcb; + text-decoration-thickness: .2rem; +} + +.post__links:hover{ + text-decoration-color: #f8f8f2; +} + + +@media only screen and (max-width: 770px) { + body { + font-size: 1.6rem; + } + + .container{ + padding: 5rem; + } + + .header{ + flex-direction: column; + } + + .header__inner { + padding: 0; + } + + .header__right { + flex-direction: column; + align-items: center; + margin-bottom: 1rem; + } + + .profile__picture{ + width: 55%; + } + + .menu { + display: flex; + align-items: center; + border: none; + margin: 0; + padding-top: 2rem; + } + + .menu__inner{ + flex-direction: column; + } + + .post { + padding: 0rem; + } + + .content__menu{ + gap: 2rem; + } + + .post__text { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + .blog__content { + display: flex; + flex-direction: column; + align-items: center; + } + + .post__img > img { + object-fit: contain; + max-width: 50%; + height: auto; + } + + .post__description { + margin-top: 2rem; + text-align: center; + } + + .box-wrapper{ + display: block; + } + +} + +@media only screen and (max-width: 1024px) { + .header__inner { + padding: 1rem; + } + + .header__right { + margin-top: 1rem; + } + + .content__main { + padding: 3rem; + margin: 2rem; + } +} + +@media only screen and (max-width: 1440px) { + .content__main { + padding: 2rem; + margin: 3rem; + } + +} \ No newline at end of file