mirror of
https://github.com/ddworken/hishtory.git
synced 2024-11-22 08:14:02 +01:00
Before huge project change
This commit is contained in:
parent
252e9ab122
commit
d84022d9fe
8
Makefile
8
Makefile
@ -8,7 +8,7 @@ build:
|
||||
docker build -t gcr.io/dworken-k8s/hishtory-api -f server/Dockerfile .
|
||||
|
||||
deploy: build
|
||||
# docker push gcr.io/dworken-k8s/hishtory-static
|
||||
docker push gcr.io/dworken-k8s/hishtory-api
|
||||
# kubectl patch deployment hishtory-static -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"ts\":\"`date|sed -e 's/ /_/g'|sed -e 's/:/-/g'`\"}}}}}}"
|
||||
kubectl patch deployment hishtory-api -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"ts\":\"`date|sed -e 's/ /_/g'|sed -e 's/:/-/g'`\"}}}}}}"
|
||||
docker push gcr.io/dworken-k8s/hishtory-static
|
||||
# docker push gcr.io/dworken-k8s/hishtory-api
|
||||
kubectl patch deployment hishtory-static -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"ts\":\"`date|sed -e 's/ /_/g'|sed -e 's/:/-/g'`\"}}}}}}"
|
||||
# kubectl patch deployment hishtory-api -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"ts\":\"`date|sed -e 's/ /_/g'|sed -e 's/:/-/g'`\"}}}}}}"
|
||||
|
@ -28,6 +28,7 @@ func main() {
|
||||
shared.CheckFatalError(shared.Setup(os.Args))
|
||||
case "install":
|
||||
shared.CheckFatalError(shared.Install())
|
||||
// TODO: should be able to do hishtory install $secret
|
||||
case "enable":
|
||||
shared.CheckFatalError(shared.Enable())
|
||||
case "disable":
|
||||
|
25
design.md
Normal file
25
design.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Requirements
|
||||
|
||||
* Trustless
|
||||
* Handles computers going offline and online for extended periods of time
|
||||
* Cost effective
|
||||
|
||||
# Design Overview
|
||||
|
||||
* Client keeps local Set<HistoryEntry> in sqlite. HistoryEntry has usual metadata + an ID that is incrementing per machine
|
||||
* Client has USER_SECRET
|
||||
* Client gets installed with USER_SECRET
|
||||
* Client asks backend for N, number of registered computers for HMAC(USER_SECRET, "comp_count"). It tells the backend to increment this.
|
||||
* Periodically it checks the backend for a new N
|
||||
* Sends message to the queue named HMAC(USER_SECRET,i) for 0 --> N asking for history dump
|
||||
* Every time `hishtory query` is run, it checks HMAC(USER_SECRET,i) for 0 --> N for new history entries
|
||||
* Every time it records a hishtory entry (or batched shortly afterwards) it sends that entry to all queues
|
||||
* With some frequency (once a day?) it reads all queues for new history entries
|
||||
|
||||
# Offline Recovery Flow
|
||||
|
||||
* Once-per-day, it checks if it doesn't have any history entries from other computers within the past EXPIRY days. If it doesn't, it sends a dump request to all queues, then receives their responses
|
||||
|
||||
|
||||
|
||||
## SQS/PubSub/Redis/Postgres Queue
|
Binary file not shown.
Binary file not shown.
@ -1,259 +1,210 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>Hishtory: Better Shell History</title>
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-144207374-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-144207374-1');
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-144207374-1');
|
||||
</script>
|
||||
|
||||
<!-- Font Awesome Icons -->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Merriweather+Sans:400,700" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Merriweather:400,300,300italic,400italic,700,700italic'
|
||||
rel='stylesheet' type='text/css'>
|
||||
|
||||
<link href='https://fonts.googleapis.com/css?family=Merriweather:400,300,300italic,400italic,700,700italic' rel='stylesheet' type='text/css'>
|
||||
<!-- Plugin CSS -->
|
||||
<link href="vendor/magnific-popup/magnific-popup.css" rel="stylesheet">
|
||||
|
||||
<!-- Theme CSS - Includes Bootstrap -->
|
||||
<link href="css/creative.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Highlight JS -->
|
||||
<link rel="stylesheet"
|
||||
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.8/styles/default.min.css">
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.8/styles/default.min.css">
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.8/highlight.min.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light fixed-top py-3" id="mainNav">
|
||||
<div class="container">
|
||||
</head>
|
||||
<body id="page-top">
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light fixed-top py-3" id="mainNav">
|
||||
<div class="container">
|
||||
<a class="navbar-brand js-scroll-trigger" href="#page-top">Hishtory</a>
|
||||
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
|
||||
data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false"
|
||||
aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarResponsive">
|
||||
<ul class="navbar-nav ml-auto my-2 my-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link js-scroll-trigger" href="#about">About</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link js-scroll-trigger" href="#setup">Setup</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link js-scroll-trigger" href="#contact">FAQ</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto my-2 my-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link js-scroll-trigger" href="#about">About</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link js-scroll-trigger" href="#setup">Setup</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link js-scroll-trigger" href="#contact">FAQ</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Masthead -->
|
||||
<header class="masthead">
|
||||
<div class="container h-100">
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Masthead -->
|
||||
<header class="masthead">
|
||||
<div class="container h-100">
|
||||
<div class="row h-100 align-items-center justify-content-center text-center">
|
||||
<div class="col-lg-12 align-self-end">
|
||||
<h2 class="text-white font-weight-bold">Your shell history: synced, queryable, and in context</h1>
|
||||
<hr class="divider my-4">
|
||||
</div>
|
||||
<div class="col-lg-8 align-self-baseline">
|
||||
<script id="asciicast-xW0ddZdZm7Utv1iLATegM4Oe4" src="https://asciinema.org/a/xW0ddZdZm7Utv1iLATegM4Oe4.js" async data-autoplay="true" data-loop="true"></script>
|
||||
</div>
|
||||
<div class="col-lg-12 align-self-end">
|
||||
<h2 class="text-white font-weight-bold">Your shell history: synced, queryable, and in context </h1>
|
||||
<hr class="divider my-4">
|
||||
</div>
|
||||
<div class="col-lg-8 align-self-baseline">
|
||||
<script id="asciicast-xW0ddZdZm7Utv1iLATegM4Oe4" src="https://asciinema.org/a/xW0ddZdZm7Utv1iLATegM4Oe4.js" async data-autoplay="true" data-loop="true"></script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- About Section -->
|
||||
<section class="page-section bg-primary" id="about">
|
||||
<div class="container">
|
||||
</div>
|
||||
</header>
|
||||
<!-- About Section -->
|
||||
<section class="page-section bg-primary" id="about">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8 text-center">
|
||||
<h2 class="text-white mt-0">Bash scripting is powerful, keep track of how you use it</h2>
|
||||
<hr class="divider light my-4">
|
||||
<p class="text-white-50 mb-4">
|
||||
Bash keeps a list of every command you run locally, but this list of commands is devoid of context (where did I run that command? what was the output of the command? how long did it take to run?) and it is easily corrupted (open two terminals at once? Say goodbye to your bash history!).
|
||||
<br>
|
||||
<br>
|
||||
Hishtory keeps track of the command you ran, how long it took to run, whether it succeeded or failed, where you ran it, and on what machine. It syncs this information across all your machines, so you can always find that useful bash pipeline you wrote a month ago.
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-lg-8 text-center">
|
||||
<h2 class="text-white mt-0">Bash scripting is powerful, keep track of how you use it</h2>
|
||||
<hr class="divider light my-4">
|
||||
<p class="text-white-50 mb-4"> Bash keeps a list of every command you run locally, but this list of commands is devoid of context (where did I run that command? what was the output of the command? how long did it take to run?) and it is easily corrupted (open two terminals at once? Say goodbye to your bash history!). <br>
|
||||
<br> Hishtory keeps track of the command you ran, how long it took to run, whether it succeeded or failed, where you ran it, and on what machine. It syncs this information across all your machines, so you can always find that useful bash pipeline you wrote a month ago.
|
||||
</p>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Setup Section -->
|
||||
<section class="page-section" id="setup">
|
||||
<div class="container">
|
||||
</div>
|
||||
</section>
|
||||
<!-- Setup Section -->
|
||||
<section class="page-section" id="setup">
|
||||
<div class="container">
|
||||
<style>
|
||||
li.nav-item>:not([active]) {
|
||||
background-color: #f7f7f9
|
||||
}
|
||||
</style>
|
||||
<h2 class="text-center mt-0">Setup Process</h2>
|
||||
<hr class="divider my-4">
|
||||
<p class="text-black-50 mb-4">
|
||||
To install hishtory in offline mode: `curl -o hishtory https://hishtory.dev/hishtory-offline; chmod +x hishtory; ./hishtory install`
|
||||
<br>
|
||||
To install hishtory in online mode on your first machine: `curl -o hishtory https://hishtory.dev/hishtory-online; chmod +x hishtory; ./hishtory install`
|
||||
<br>
|
||||
To install hishtory in online mode on your other machines: `curl -o hishtory https://hishtory.dev/hishtory-online; chmod +x hishtory; ./hishtory install $YOUR_HISHTORY_SECRET`
|
||||
<div style="border: solid #f7f7f9; border-width: 2px;border-radius:10px;padding:2%">
|
||||
<ul class="nav nav-tabs nav-pills nav-justified" id="myTab" role="tablist" style="/*border: solid #f7f7f9; border-width: 2px;*/">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="install-online-tab" data-toggle="tab" href="#install-online" role="tab" style="margin: 10px">Install (Online Mode)</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="install-offline-tab" data-toggle="tab" href="#install-offline" role="tab" style="margin: 10px">Install (Offline Mode)</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="install-online" role="tabpanel" aria-labelledby="home-tab">
|
||||
<br>To install hishtory in online mode on your first machine:
|
||||
<br> <code>curl -o hishtory https://hishtory.dev/hishtory-online; chmod +x hishtory; ./hishtory install</code>
|
||||
<br> To install hishtory in online mode on your other machines:
|
||||
<br> <code>curl -o hishtory https://hishtory.dev/hishtory-online; chmod +x hishtory; ./hishtory install $YOUR_HISHTORY_SECRET</code>
|
||||
</div>
|
||||
<div class="tab-pane" id="install-offline" role="tabpanel" aria-labelledby="profile-tab"><br> To install hishtory in offline mode: <br> <code>curl -o hishtory https://hishtory.dev/hishtory-offline; chmod +x hishtory; ./hishtory install</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Contact Section -->
|
||||
<section class="page-section" id="contact">
|
||||
<div class="container">
|
||||
</div>
|
||||
</section>
|
||||
<!-- Contact Section -->
|
||||
<section class="page-section" id="contact">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8 text-center">
|
||||
<h2 class="mt-0">FAQ</h2>
|
||||
<!-- FAQ -->
|
||||
<hr class="divider my-4">
|
||||
<div class="accordion" id="accordionExample">
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingZero">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link" type="button" data-toggle="collapse"
|
||||
data-target="#collapseZero" aria-expanded="true" aria-controls="collapseZero">
|
||||
How does this work?
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div id="collapseZero" class="collapse show" aria-labelledby="headingZero"
|
||||
data-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
Hishtory hooks into your shell to record everything you could want to know about your shell history. It supports two modes:
|
||||
<ol>
|
||||
<li>Offline mode: It persists all this data in a local SQLite database</li>
|
||||
<li>Online mode: Only if you opt-in, it syncs this data between all your machines so your history is immediately queryable from every one of your machines</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingOne">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse"
|
||||
data-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
|
||||
Can I use this without syncing my bash history to the internet?
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div id="collapseOne" class="collapse" aria-labelledby="headingOne"
|
||||
data-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
Yes! The default is to use it in the offline mode where your shell history stays 100% local and never leaves your machine. Only if you opt-in will it be synced to your other machines with hishtory installed.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingTwo">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse"
|
||||
data-target="#collapseTwo" aria-expanded="false"
|
||||
aria-controls="collapseTwo">
|
||||
What about `.bash_history`?
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo"
|
||||
data-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
If it works for you, great! But I find I constantly get annoyed with `.bash_history` either because I lose context (which directory do I need to run that command from?) or because I full on lose the file (it tends to get corrupted if you open multiple terminals at the same time).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingThree">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse"
|
||||
data-target="#collapseThree" aria-expanded="false"
|
||||
aria-controls="collapseThree">
|
||||
Is this free?
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseThree" class="collapse" aria-labelledby="headingThree"
|
||||
data-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
Yes! This is just a hobby project for me that I use, and I hope other people get some use out of.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingFour">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse"
|
||||
data-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
|
||||
Who made this?
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseFour" class="collapse" aria-labelledby="headingFour"
|
||||
data-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
Made with ❤️ by <a
|
||||
href="https://daviddworken.com">David Dworken</a>.
|
||||
|
||||
I'm a Security Engineer working at Google. I built this to solve a problem for myself, and wanted to share it with others who may find it useful.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8 text-center">
|
||||
<h2 class="mt-0">FAQ</h2>
|
||||
<!-- FAQ -->
|
||||
<hr class="divider my-4">
|
||||
<div class="accordion" id="accordionExample">
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingZero">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseZero" aria-expanded="true" aria-controls="collapseZero"> How does this work? </button>
|
||||
</h2>
|
||||
</div>
|
||||
<hr class="divider my-4">
|
||||
<p class="text-muted mb-5">
|
||||
Feedback, thoughts, ideas, or other questions? Let us know
|
||||
</p>
|
||||
<div id="collapseZero" class="collapse show" aria-labelledby="headingZero" data-parent="#accordionExample">
|
||||
<div class="card-body"> Hishtory hooks into your shell to record everything you could want to know about your shell history. It supports two modes: <ol>
|
||||
<li>Offline mode: It persists all this data in a local SQLite database</li>
|
||||
<li>Online mode: Only if you opt-in, it syncs this data between all your machines so your history is immediately queryable from every one of your machines</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingOne">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne"> Can I use this without syncing my bash history to the internet? </button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
|
||||
<div class="card-body"> Yes! The default is to use it in the offline mode where your shell history stays 100% local and never leaves your machine. Only if you opt-in will it be synced to your other machines with hishtory installed. </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingTwo">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"> What about `.bash_history`? </button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
|
||||
<div class="card-body"> If it works for you, great! But I find I constantly get annoyed with `.bash_history` either because I lose context (which directory do I need to run that command from?) or because I full on lose the file (it tends to get corrupted if you open multiple terminals at the same time). </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingThree">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree"> Is this free? </button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordionExample">
|
||||
<div class="card-body"> Yes! This is just a hobby project for me that I use, and I hope other people get some use out of. </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingFour">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour"> Who made this? </button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapseFour" class="collapse" aria-labelledby="headingFour" data-parent="#accordionExample">
|
||||
<div class="card-body"> Made with ❤️ by <a href="https://daviddworken.com">David Dworken</a>. I'm a Security Engineer working at Google. I built this to solve a problem for myself, and wanted to share it with others who may find it useful. </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="divider my-4">
|
||||
<p class="text-muted mb-5"> Feedback, thoughts, ideas, or other questions? Let us know </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-4 text-center">
|
||||
<i class="fas fa-envelope fa-3x mb-3 text-muted"></i>
|
||||
<a class="d-block" href="mailto:david@daviddworken.com">david@daviddworken.com</a>
|
||||
</div>
|
||||
<div class="col-lg-4 text-center">
|
||||
<i class="fas fa-envelope fa-3x mb-3 text-muted"></i>
|
||||
<a class="d-block" href="mailto:david@daviddworken.com">david@daviddworken.com</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="bg-light py-5">
|
||||
<div class="container">
|
||||
</div>
|
||||
</section>
|
||||
<!-- Footer -->
|
||||
<footer class="bg-light py-5">
|
||||
<div class="container">
|
||||
<div class="small text-center text-muted">Copyright © 2022 - David Dworken</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Bootstrap core JavaScript -->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Plugin JavaScript -->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
<script src="vendor/magnific-popup/jquery.magnific-popup.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for this template -->
|
||||
<script src="js/creative.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- Bootstrap core JavaScript -->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<!-- Plugin JavaScript -->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
<script src="vendor/magnific-popup/jquery.magnific-popup.min.js"></script>
|
||||
<!-- Custom scripts for this template -->
|
||||
<script src="js/creative.min.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user