Compare commits

...

37 Commits

Author SHA1 Message Date
f7503916ce UTC date to LocalTIME 2020-07-07 13:13:17 +02:00
e709b7a33f ajout dossier fonts 2020-05-28 08:45:22 +02:00
723d4b38cd ajout mode My special Blocks list 2020-03-27 08:25:27 +01:00
de74a94433 footer en bg-grey about.php 2020-01-12 20:12:52 +01:00
5fffd55693 hidde logo on smartpghone in about.php 2020-01-09 14:41:42 +01:00
2bb9f3e81e nouveaux logos tr 2020-01-09 10:24:06 +01:00
8dd6659bf8 preload logo pictures 2020-01-09 09:06:31 +01:00
ec01340aa7 ajout des chroniques dans about.php 2020-01-06 14:43:25 +01:00
fc231ee294 Put simpleParallax and modify logo.php to merge 2020-01-04 18:18:39 +01:00
ca6e77ebb0 modification logo dans about.php 2019-12-28 09:22:56 +01:00
0fa7b7f2a6 Empêcher un bloc d'etre là 2 fois 2019-12-21 21:24:20 +01:00
1e30565b83 Remove unsued copy ! 2019-12-21 20:04:02 +01:00
0684c9c627 Detect scroll to footer 2019-12-21 20:02:46 +01:00
8621260f26 Refonte Explorateur 2019-12-21 19:54:39 +01:00
315a82c2fb ajout de height dans les infos 2019-09-26 07:27:59 +02:00
75449b4c46 modif bookmarks 2019-09-16 07:18:14 +02:00
3b2841b9ff about.php : bookmarks to bookmarks 2019-09-16 07:10:19 +02:00
d38b68b39b ajouter par le haut 2019-08-31 15:18:00 +02:00
fc5b04c159 correction sur le hack à true dans isblocknew 2019-08-31 14:42:05 +02:00
907e56d9cb Ajout du dernier block par le haut 2019-08-31 14:25:50 +02:00
4301ad5cb5 Superposer l'image et les infos. Avec une checkbox 2019-07-28 08:52:38 +02:00
c0239d260e index est juste une liste des blocks 2019-07-23 07:21:54 +02:00
2a651ede89 ajout du projet des nombres univers 2019-05-11 09:47:22 +02:00
82c9316d43 Début des chroniques 2019-03-30 09:34:28 +01:00
ad0ec21c6d quantité = confiance 2019-03-26 19:30:42 +01:00
e55f435001 système de console et timer de block 2019-03-16 19:07:33 +01:00
e1084a2358 système page sous-page pour les cas d'usages 2019-03-10 18:08:14 +01:00
be13b27598 finir une phrase 2019-03-09 12:08:13 +01:00
7a66157bd9 Rajout d'un article 20190308 2019-03-08 19:56:23 +01:00
a4f572f962 list of special blocks is now dynamic via ajax 2019-03-03 17:59:01 +01:00
61930c1277 change a comment in block_image.php 2019-02-17 10:40:30 +01:00
89215df21b renommage dossiers articles 2019-02-10 11:24:40 +01:00
48cc573c1c limiter aux articles commençant par "20" 2019-02-10 11:18:35 +01:00
537c61e8a3 telephone is lost 2019-02-09 06:14:33 +01:00
f28d91237b ajout de liste_blocks 2019-02-09 06:08:01 +01:00
24bbee0109 lastbloc.js is now a module 2018-12-01 10:47:03 +01:00
1d90cd185a temporaire 20181201 2018-12-01 09:51:41 +01:00
113 changed files with 5601 additions and 597 deletions

243
about.php Normal file
View File

@@ -0,0 +1,243 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>TOPISTO</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Bangers" rel="stylesheet" type="text/css">
<link href="css/topisto.css" rel="stylesheet" type="text/css">
<link href="css/fonts.css" rel="stylesheet" type="text/css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="js/console.js" defer></script>
<script src="js/lastblock.js" defer></script>
<script src="js/blockexplorer.js" defer></script>
<script src="js/simpleParallax.js"></script>
<script>
$(document).ready(function(){
setInterval(changeGargoyle,10000);
getMyAdressInfos();
setParallax();
$('#myNavbar').on('show.bs.collapse', function () {
$('#logo_topisto').css({'height' : '30px','width' : '30px'});
$('#titre_topisto').css({'font-size' : '30px'});
});
$('#myNavbar').on('hidden.bs.collapse', function () {
$('#logo_topisto').css({'height' : '72px','width' : '72px'});
$('#titre_topisto').css({'font-size' : '60px'});
});
// Add smooth scrolling to all links in navbar + footer link
$("footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
$(window).scroll(function() {
$(".slideanim").each(function(){
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
$(this).addClass("slide");
}
});
});
});
/*
*
* Pré-charger les images
*
*/
var preloadImages = function (imgs, callback) {
var img;
var remaining = 26;
for (var i = 0; i < 26; i++) {
img = new Image;
img.onload = function () {
--remaining;
if (remaining <= 0) {
callback();
}
if (i == 0)
$("#gargoyle").attr("src", this.src)
};
d = new Date();
img.src = "images/logo.php?rank="+i+"&ts="+d.getTime();
imgs.push(img);
}
};
/*
* Faire varier l'image de la gargouille
*
*/
var gargoyles = [];
function changeGargoyle()
{
if (gargoyles.length == 0)
{
preloadImages(gargoyles, function(){
topistoConsole.log("All Gargoyles are loaded");
});
} else {
r = Math.floor(Math.random() * gargoyles.length);
$("#gargoyle").attr("src", gargoyles[r].src);
}
}
/*
* Récupéer les taux de change actuels
* https://blockchain.info/ticker?cors=true
*
* Récupéer la balance de mon adresse
* https://blockchain.info/q/addressbalance/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh?cors=true
*
* Calculer et afficher la balance en EUR et USD
*
*/
function getMyAdressInfos()
{
var balance_url = 'https://blockchain.info/q/addressbalance/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh?cors=true';
$.get( balance_url, function( data ) {
var balance = data/100000000;
var btc_change = 'balance : ' + balance + ' &#8383';
$.getJSON( 'https://blockchain.info/ticker?cors=true', function( data ) {
btc_change += ' / '+ Math.round(data.USD['15m']*balance) + ' $';
btc_change += ' / '+ Math.round(data.EUR['15m']*balance) + ' €';
$('#BTC_CHANGE').html(btc_change);
});
});
}
function setParallax()
{
var image = document.getElementsByClassName('simple-parallax');
new simpleParallax(image,{
scale: 1.5,
overflow: true,
orientation: 'down'
});
}
</script>
</head>
<body id="myPage" data-spy="scroll" data-target=".navbar" data-offset="60">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="index.php">
<img id="logo_topisto" src="images/topisto_vert.png" style="border-radius:6px;display:inline-block;height:72px;;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)">
<span id="titre_topisto" style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 60px;text-shadow: 2px 2px #ffffff">TOPISTO</span>
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li><a href="#about">About</a></li>
<li><a href="index.php">Explorer</a></li>
<li><a href="blog.php">Blog</a></li>
</ul>
</div>
</div>
</nav>
<div id="explorer" class="container-fluid" style="padding-bottom:10px">
<div class="row">
<div class="col-sm-12 text-left">
<br>BTC adress : <a href="https://www.blockchain.com/btc/address/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh">15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh</a>
<br><div id="BTC_CHANGE">&nbsp; &#8383 - &nbsp; $ - &nbsp; €</div>
</div>
</div>
</div>
<div id="about" class="container-fluid bg-grey" style="padding-top:5px;padding-bottom:5px">
<div class="row" style="margin-top:0px">
<div class="col-sm-8" style="margin-top:0px">
<h4 style="margin-top:0px">This site is a hobby.<br>It's also a testing place where i can do <a href="blog.php">things</a> that are impossible at work.</h4>
<p class="text-justify">I like <b>surfing</b> and sailing on the ocean. But during longs winter nights, computing is fun. I'm interested into <b>cryptocurrencies</b>, computationnal art, datavisualisation. I know that <b>42</b> is the answer to <b>the Life, Universe and Everything Else</b>. As <b>Eto Demerzel</b> said to me, the <b>Seldon's Plan</b> will save the Galaxy. My favorites books are the <b>House of leaves</b>, the <b>Necronomicron</b> and the <b>DarkHold</b>. I also know that <b>great power comes with great responsibility</b>. I'm still in <b>the search of Captain Zero</b>, because <b>the Truth is out there</b>.</p>
<p class="text-justify">.I'm also really astonished by <b>Universal Numbers</b>, aka Disjunctives Sequences. Thinking that a single number can contain every others, that's a great <b>mystery</b>. So I'm trying to write the <a href="page.php?id=00190327">Chronicles</a> of these numbers (in french)</p>
</div>
<div class="col-sm-4 hidden-xs">
<!--
<div style="background-image:url(images/topisto_vert_tr.png);background-repeat: no-repeat;background-position:center top;background-size: 100% auto;">
<img id="gargoyle" src="images/logo.php" alt="avatar dragon gargoyle" width="100%; height: auto" style="opacity:0.4"></img>
</div>
-->
<img id="gargoyle" class="simple-parallax" src="images/logo.php" alt="avatar dragon gargoyle" width="100%; height: auto" style="margin-top:-100px"></img>
</div>
</div>
</div>
<div id="contact" class="container-fluid">
<div class="row slideanim">
<div class="col-sm-4">
Bookmarks : <br>
<a href="/bookmarks" target="_blank">my Shaarli</a><br>
<a href="https://inconvergent.net/" target="_blank">Inconvergent</a><br>
<a href="http://www.datasketch.es/" target="_blank">Data Sketches</a><br>
<a href="https://bit101.github.io/lab/dailies/170310.html" target="_blank">bit101-github</a><br>
<a href="http://www.imdb.com/title/tt1508021/" target="_blank">being captain zero</a><br>
</div>
<div class="col-sm-4">
<p>Contact me :</p>
<p><span class="glyphicon glyphicon-map-marker"></span> Shambala</p>
<p><span class="glyphicon glyphicon-globe"></span> Employer : Mutiny</p>
<p><span class="glyphicon glyphicon-phone"></span> +33 4 8 15 16 23 42</p>
<p>
<span class="glyphicon glyphicon-envelope"></span>
<!--Place the code below where you want the link to be displayed-->
<span id="obf"><script>document.getElementById("obf").innerHTML="<n uers=\"znvygb:nyoreg.frnaquvyf@gbcvfgb.arg?fhowrpg=pbagnpg\" gnetrg=\"_oynax\">nyoreg.frnaquvyf@gbcvfgb.arg</n>".replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});</script>
<noscript><span style="unicode-bidi:bidi-override;direction:rtl;">ten.otsipot@slihdnaes.trebla</span></noscript></span>
</p>
</div>
<div class="col-sm-4">
BTC adresss : <br>
<a href="https://www.blockchain.com/btc/address/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh">15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh</a>
</div>
</div>
</div>
<footer class="container-fluid bg-grey text-center">
<a href="#myPage" title="To Top">
<span class="glyphicon glyphicon-chevron-up"></span>
</a>
</footer>
</body>
</html>

View File

@@ -0,0 +1,65 @@
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-4">
<br><img id="logo_ARTICLE" src="articles/ARTICLE/images/Roman-Opalka-01.jpg" width="100%; height: auto"></img>
<br><i><small>Roman Opalka , Détail , 1965 / 1 </small></i>
</div>
<div class="col-sm-8">
<h2>Les chroniques des Nombres Univers.</h2>
<p class="text-justify">
Certains l'ont découvert par hasard, d'autres y ont consacré des années de recherche : il existe des "<b>nombres univers</b>".<br><br>
Ces nombres font partie de l'ensemble des irrationnels, leur représentation comprend une infinité de décimales.
La suite de leurs décimales ne comporte aucune périodicité.
Cela conduit à une propriété un peu étonnante : ils peuvent contenir la représentation de n'importe quel nombre, y compris eux-même.<br><br>
Nous en connaissons tous au moins un, il s'agit du nombre <b>π</b> : 3,141 592 653 589 793 238 462 643 383 279 502 884 197 169 399 375 105 820 974 944 592 307 816 406 286 208 998 628 034 825 342 117 067 ...
<br><br>
Ils furent massivement utilisés par les grandes firmes informatiques à partir du milieu du 21eme siècle.
<br><br>
</p>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<p class="text-justify">
Dès le début de l'informatique, les ordinateurs ont été utilisés pour codifier l'information.
Leurs grandes facultées calculatoires étaient bien sûr exploitées dans les domaines scientifiques et financiers.
Mais on a rapidement sû tirer profit de ces machines pour organiser, stocker et rechercher des connaissances.
Dans ces systèmes, textes et images sont convertis en suites de chiffres.
Chaque lettre d'un texte est remplacée par sa position dans l'alphabet.
Les images sont vues comme des matrices de points, dont la couleur est codée suivant l'intensité de sa valeur RGB (Red, Green, Blue)
<br><br>
Lorsque la capacité de traitement des ordinateurs augmenta, il fallut stocker toujours plus d'information pour alimenter les calculs qui, ainsi, devenaient de plus en plus pertinents.
Pour couronner le tout, ce stockage était mal géré, de nombreuses copies d'un même fichier existaient, parfois intentionnellement (dans le but d'un assurer la conservation), parfois par manque de rigueur.
La capacité de stockage devint un problème, au point de contribuer à mettre la planète en péril.
Consommer toujours plus d'énergie, pour alimenter des datacenters de plus en plus nombreux.
Extraire des minerais rares pour fabriquer des composants électroniques en quantité astronomiques. Cela n'était clairement pas viable sur le long terme.
<br><br>
C'est alors que l'on trouva un nouvel intêret aux nombres univers.
Il n'était plus besoin de stocker l'intégralité de la suite de chiffres qui représentait une information.
Cette suite existait forcément à l'intérieur d'un nombre univers.
Seule la longueur de l'information et sa position dans le nombre devenaient nécessaires.
Ces deux valeurs étaient bien sûr stockées, mais cela représentait une économie phénoménale de ressources.
On rechercha des nombres univers dont les propriétés mathématiques permettaient de fabriquer des puces électroniques spécifiquement
<br><br>
Comme toujours les pionniers furent incompris et passèrent pour des excentriques.
Certains furent même soupçonnés d'escroquerie tant les performances annoncées paraissaient extraordinaires.
Mais bientôt les perspectives de bénéfices attirèrent des entrepreneurs, avec des projets réfléchis et des ambitions démesurées.
<br><br>
Les plus malins avaient remarqué qu'il leur était possible de monter un modèle économique où leurs clients étaient complètement captifs.
Car la seule information que le client détenait se limitait à deux nombres : une longueur et une position.
A elles seules, ces données ne permettaient pas grand chose.
Il fallait connaître le nombre univers auquel elles se référaient, et il fallait aussi détenir des composants spécifiques capables de calculer très rapidement un grand nombre de décimales du nombre univers choisi.
<br><br>
Bientôt, sous la pression de lobbies industriels, les gouvernements cédèrent les uns après les autres.
Ils votèrent une loi permettant de breveter un nombre univers.
Se donner les moyens de découvrir un nouveau nombre univers garantissait l'exclusivité de son usage.
Les mathématiciens avaient devant eux de belles carrières dans des entreprises devenues d'énormes conglomérats mondiaux.
<br><br>
Enfin vint le temps des intelligences artificielles.
La boucle était bouclée, les ordinateurs cherchaient eux-mêmes les conditions de l'optimisation de leurs performances.
La singularité fût-elle atteinte ? Les hommes ne le sûrent jamais.
</p>
</div>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

View File

@@ -0,0 +1,55 @@
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-4">
<br><img id="logo_ARTICLE" src="articles/ARTICLE/images/Roman-Opalka-02.jpg" style="width:100%;max-width:580px;"></img>
</div>
<div class="col-sm-8">
<h3>La constante <b>e</b> : le cas Jan Sloot.</h3>
<p class="text-justify">
<i><small>Inspiré par un post sur <a href="https://usbeketrica.com/article/jan-sloot-ingenieur-mort-informatique" target="_blank">Uzbek & Rica</a></small></i><br><br>
Certains l'ont découvert par hasard, d'autres y ont consacré des années de recherche : il existe des "<b>nombres univers</b>". <br><br>
Le nombre d'Euler (noté <b>e</b> ) est l'un d'entre eux : 2,718 281 828 459 045 235 360 287 471 352 662 497 757 247 093 699 959 574 966 967 627 724 076 630 353 547 594 571 382 178 525 166 427 427 466 391 932 003 059 ...<br><br>
</p>
<p>
Jan Sloot surveillait ses braises.
Un large sourire éclairait son visage.
Bien sûr la perspective d'avaler ces délicieuses merguez contribuait à son état d'esprit.
Accompagnées d'une salade et d'une bière blonde bien fraîche, sur la table du jardin en compagnie de la famille, c'était parfait.
Mais c'était surtout parce que demain, toutes ces longues années de travail allaient enfin payer.
<br><br>
L'idée était pourtant assez simple, et il s'étonnait encore que personne avant lui n'y ait pensé.
</p>
</div>
<div class="row">
<div class="col-sm-12">
<p>Voici deux manières de calculer une valeur approchée de la constante <b>e</b> :</p>
<ul>
<li>la formule de Bernoulli : \(e = \lim_{n\to\infty} \left( 1 + \frac{1}{n} \right)^n\)</li>
<li>la série infinie suivante : \(e = \sum_{n = 0}^\infty \frac{1}{n!} = \frac{1}{0!} + \frac{1}{1!} + \frac{1}{2!} + \frac{1}{3!} + \frac{1}{4!} + \cdots\)</li>
</ul>
<p>L'implémentation informatique directe de ces équations pose des problèmes. Soit cela ne converge pas assez vite vers e, soit les calculs sont trop lents.</p>
<p>Pour être pragmatique, il faut poser: \(u_n=\displaystyle\sum_{k=0}^{k=n}\dfrac{1}{k!}\) et \(v_n=u_n+\dfrac{1}{n\cdot n!}\) </p>
<p>Ce qui donne, par exemple, le programme Python suivant :</p>
<pre><code class="python">
# -*- coding: utf-8 -*-
def e(ndec=1000):
n = fn = 1
while fn < ndec:
fn *= n; n += 1
x = u = 10**ndec
for k in range(n,0,-1):
u = x + u//k
return u
print "// Pour 1000 décimales :"
print e()
print "// Pour 100000 décimales :"
print e(100000);
</code></pre>
NB : L'identité d'Euler est considérée par beaucoup comme la plus belle formule des mathématiques.
Elle met en jeu deux nombre univers.<br>
Elle s'écrit : \(e^{i\pi} + 1 = 0\)
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,18 @@
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-4">
<br><img id="logo_ARTICLE" src="articles/ARTICLE/images/pi_by_xan2_3.jpeg" style="width:100%;max-width:580px;"></img>
</div>
<div class="col-sm-8">
<h3><b>π</b>fs</h3>
<p class="text-justify">
Certains l'ont découvert par hasard, d'autres y ont consacré des années de recherche : il existe des "<b>nombres univers</b>".
<br><br>
Nous en connaissons tous au moins un, il s'agit du nombre <b>π</b> : 3,141 592 653 589 793 238 462 643 383 279 502 884 197 169 399 375 105 820 974 944 592 307 816 406 286 208 998 628 034 825 342 117 067 ...
</p>
<br/><br/>
Epilogue :
Les sources de pifs sont <a href="https://github.com/philipl/pifs"></a>en ligne sur GITHUB</a>
</div>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-4">
<br><img id="logo_ARTICLE" src="images/block_image.php?methode=spline" width="100%; height: auto"></img>
<br><img id="logo_ARTICLE" src="images/block_image.php?methode=spline_2" width="100%; height: auto"></img>
<br><p>ARTICLE</p>
</div>
<div class="col-sm-8">

View File

@@ -32,5 +32,5 @@ function init_2018025(leblock)
}
$(document).ready(function(){
last_block_hooks.push(init_2018025);
blockchainListener.addBlockHook(init_2018025);
});

View File

@@ -1,7 +1,7 @@
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-4">
<br><img id="logo_ARTICLE" src="images/block_image.php?methode=treemapV2" width="100%; height: auto"></img>
<br><img id="logo_ARTICLE" src="images/block_image.php?methode=treemap2" width="100%; height: auto"></img>
<br><p>ARTICLE</p>
</div>
<div class="col-sm-8">

View File

@@ -0,0 +1,162 @@
<style>
blockquote {
font-size: 14px !important;
font-style: italic !important;
}
h5 {
font-size: 17px !important;
text-decoration: underline !important;
padding-top: 15px;
}
</style>
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-12">
<br><p>ARTICLE</p>
<h2>Des cas d'usages des technos crypto pour l'&Eacute;tat</h2>
<h4>Cas dusage n°1 : une gestion des identités.</h4>
<p class="text-justify">
Nous commencerons par attirer lattention sur un avantage peu mis en avant de lusage dadresses BTC comme identités.<br/>
<ul>
<li><a href="#technologie">La technologie</a></li>
<li><a href="#usage">L'usage</a></li>
</ul>
</p>
<a id="technologie"></a>
<h5>La technologie</h5>
<p class="text-justify">
Dans un réseau cryptographique, chacun est identifié par un couple de clé publique / clé privée.<br/>
<br/>
La clé privée doit rester secrète et la clé publique à vocation à être communiquée aux interlocuteurs du réseau.<br/>
<br/>
Il est évidemment impossible de déduire la clé privée à partir de la clé publique.<br/>
Les clés sont en fait des très grands nombres mathématiques, peu faciles à manipuler.<br/>
Ladresse est une représentation (un peu) plus simple de la clé publique.<br/>
<br/>
Le schéma est donc le suivant : <b>clé privée</b> => <b>clé publique</b> <=> <b>adresse</b><br/>
<br/>
Il suffit de connaître ladresse dune personne pour accéder à la balance comptable de son compte.<br/>
On est alors également en capacité denvoyer des fonds sur cette adresse.<br/>
Il suffit de connaître la clé privée dune adresse pour être capable de dépenser les fonds quelle possède.<br/>
<br/>
Le registre des transactions (la blockchain) est publique.<br/>
Chaque transaction est un échange de fonds entre (au moins) deux adresses publiques.<br/>
La traçabilité est donc totale.<br/>
<br/>
Les portes monnaies cryptographiques sont en fait des trousseaux de clés.<br/>
En simplifiant à lextrême, un porte monnaie na besoin de retenir quune seule information : la clé privée.<br/>
Cette information étant ultra sensible, elle doit faire lobjet dune sécurisation absolue.<br/>
Il faut en assurer la confidentialité ainsi que la sauvegarde, ce qui peut se révéler contradictoire.<br/>
<br/>
Mais rien nempêche un même porte monnaie de contenir plusieurs couples de clés.<br/>
Lutilisateur possède alors plusieurs identités sur le réseau puisquil utilise plusieurs adresses publiques.<br/>
Techniquement, il est très facile de créer un couple de clés.<br/>
Chacun peut donc en théorie posséder des milliers dadresses, sa fortune est alors composée de la somme des balances de chacune des adresses.<br/>
Mais nous avons vu que la sécurité dune identité repose sur la connaissance de sa clé privée.<br/>
Lorsquon se met à utiliser des milliers dadresses, tout lenjeu réside donc dans la gestion des milliers de clés privées.<br/>
Cela peut rapidement devenir laborieux …<br/>
<br/>
Heureusement, les trousseaux de clés modernes utilisent un système dhéritage entre les adresses.<br/>
Grâce aux suggestions des BIP 32, 43 et 44, on peut dériver une adresse dune autre adresse.<br/>
Une relation mathématique lie ladresse mère à son adresse fille.<br/>
Mais il est impossible de remonter de ladresse fille vers son adresse mère.<br/>
Du point de vue du réseau, ces deux adresses sont complètement indépendantes.<br/>
Seul le trousseau peut faire la relation entre les deux adresses.<br/>
Et il est impossible pour le réseau de savoir que deux adresses sont sœurs.<br/>
En fait, il est possible de déduire un grand nombre de filles à partir dune mère, de lordre de deux milliards.<br/>
Mieux encore, chaque fille peut elle-même être la mère dautres adresses, et ce sur une profondeur illimitée.<br/>
Ainsi donc, un trousseau na à sécuriser quune seule information : la clé privée de ladresse racine.<br/>
Toutes les autres clés peuvent en être déduites …<br/>
</p>
<a id="usage"></a>
<h5>L'usage</h5>
<p class="text-justify">
On peut donc concevoir quun &Eacute;tat puisse distribuer des adresses certifiées par ses soins à ses citoyens.<br/>
Chacun dispose donc dune adresse publique, certifiée par l&Eacute;tat.<br/>
Mais à partir de celle-ci, chacun est libre de décliner cette adresse en autant de filles quil le souhaite.<br/>
Même dans les relations avec les services de l&Eacute;tat, il peut choisir de décliner une nouvelle identité à chaque fois :<br/>
Une identité pour la CAF, une autre pour la Sécu, les impôts, etc.<br/>
De même dans ses relations privées ou commerciales :<br/>
Une identité vis-à-vis de la banque, une autre vis-à-vis dun réseau social, du boulanger, etc.<br/>
<br/>
Je pense quà ce stade, le lecteur aura compris lidée générale de ce cas dusage.<br/>
Le principe de respect de la vie privée devient compatible avec la nécessaire traçabilité des transactions.<br/>
<br/>
On pourrait par exemple imaginer une blockchain parallèle à celle hébergeant les transactions, utilisant les mêmes adresses que le réseau mais dont le token aurait pour seul objet de signifier la validité dune adresse. Une adresse y ayant un solde positif, même dun Satoshi, serait dune adresse valide.<br/>
<br/>
L&Eacute;tat certifie une identité en envoyant un jeton sur ladresse de cette personne. Chacun peut ensuite émettre et révoquer ses propres adresses filles. Chacun peut vérifier la validité dune adresse, la blockchain en question étant publique. Eventuellement, l&Eacute;tat révoque lidentité certifiée de lindividu au moment de son décès (selon des modalités à définir). <br/>
<br/>
Pour garantir la confidentialité, cette blockchain pourrait être du type Monero ou ZCash dont la technologie permet de masquer lorigine des fonds présents sur une adresse. Ainsi on ne pourrait pas non plus déduire la filiation des adresses en traçant les échanges de tokens<br/>
<br/>
Enfin, le type des transactions y serait particulier dans le sens où pour envoyer un token à une adresse, il faudrait<br/>
- Soit en être le propriétaire, c'est à dire détenir sa clé privée<br/>
- Soit partager un secret avec elle, pour sceller la transaction, ce qui implique un échange "offline"<br/>
<br/>
Cela laisse des options quant à la certification des adresses par l'&Eacute;tat.<br/>
- Soit les adresses certifiées sont des filles de celles de l'&Eacute;tat, dans ce cas ce dernier a un contrôle total de toutes les adresses.<br/>
Cela lui permet de révoquer une identité et toutes ses filles, au moment du décès de la personne par exemple.<br/>
- Soit le script de transaction fait une exception qui permet aux adresses de l'&Eacute;tat de verser des tokens sur une adresse dont il n'est pas propriétaire.<br/>
On notera que ces deux types de solution peuvent cohabiter dans uen même blockchain.<br/>
<br/>
Il y a donc sans doute matière à satisfaire les plus libertaires d'entre-vous, qui auront également noté que dans ce système, rien n'empêche d'échanger des fonds sur la blockchain principale sur des adresses non certifiées par la deuxième blockchain.
Chacun reste libre ...<br/>
<br/>
Autre avantage de ce système, si l'&Eacute;tat donne une quantité fixe de tokens, plus l'utilisateur crée d'identités plus il "affaiblit" son identité principale puisque la balance de son wallet diminue.
On peut donc avoir plus ou moins confiance dans une identité en fonction de la quantité de tokens dont elle dispose.
<br/><br/>
Je marrête là pour ce premier cas dusage.<br/>
La discussion est ouverte, les bases de l'identité sont posées, on peut passer à la suite.<br/>
Rendez-vous pour le second cas d'usage ...<br/>
</p>
</div>
</div>
<a id="lafin"></a>

View File

@@ -0,0 +1,31 @@
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-4">
<br><img id="logo_ARTICLE" src="images/block_image.php" width="100%; height: auto"></img>
<br><p>ARTICLE</p>
</div>
<div class="col-sm-8">
<h2>Cas d'usages des technos crypto pour l'&Eacute;tat</h2>
<p class="text-justify">
Récemment, <a href="http://www2.assemblee-nationale.fr/deputes/fiche/OMC_PA721568">le député Pierre PERSON</a> nous invitait à "bousculer" ladministration sur ces sujets en proposant à la personne publique des modèles qui permettent daméliorer le fonctionnement de nos services publics et le fonctionnement de notre société en général.
Je me lance donc dans une modeste contribution, en proposant quelques cas dusages.
Spontannément, j'ai 4 cas d'usage qui me viennent en tête.
<ul>
<li>
<a href="page.php?id=20190308/01">Une gestion des identités, conciliant traçabilité et confidentialité</a>.<br/>
</li>
<li>
Une crypto monnaie d'Etat.<br/>
</li>
<li>
Des transactions multisignatures pour fluidifier lorganisation ordonnateur/payeur.<br/>
</li>
<li>
Des smartcontracts pour les marchés publics.<br/>
</li>
</ul>
</p>
<br/><br/>
</div>
</div>
</div>

147
blog.php
View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="fr">
<html lang="en">
<head>
<title>TOPISTO</title>
<meta charset="utf-8">
@@ -17,6 +17,63 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="js/console.js" defer></script>
<script src="js/lastblock.js" defer></script>
<!--
-- From https://highlightjs.org
-->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/atom-one-dark.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
$(document).ready(function(){
$('#myNavbar').on('show.bs.collapse', function () {
$('#logo_topisto').css({'height' : '30px','width' : '30px'});
$('#titre_topisto').css({'font-size' : '30px'});
});
$('#myNavbar').on('hidden.bs.collapse', function () {
$('#logo_topisto').css({'height' : '72px','width' : '72px'});
$('#titre_topisto').css({'font-size' : '60px'});
});
// Add smooth scrolling to all links in navbar + footer link
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
$(window).scroll(function() {
$(".slideanim").each(function(){
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
blockchainExplorer.ajouterPreviousBlock();
$(this).addClass("slide");
}
});
});
});
</script>
</head>
<body id="myPage" data-spy="scroll" data-target=".navbar" data-offset="60">
@@ -28,32 +85,31 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="..">
<a class="navbar-brand" href="index.php">
<img id="logo_topisto" src="images/topisto_vert.png" style="border-radius:6px;display:inline-block;height:72px;;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)">
<span style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 70px;">TOPISTO</span>
<span id="titre_topisto" style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 60px;text-shadow: 2px 2px #ffffff">TOPISTO</span>
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="about.php">About</a></li>
<li><a href="index.php">Explorer</a></li>
<li><a href="#blog">Blog</a></li>
</ul>
</div>
</div>
</nav>
<div id="about" class="container-fluid">
<div id="blog" class="container-fluid bg-white" style="padding-top:50px;align:right">
<div class="row">
<div class="col-sm-12">
<br><br>
</div>
<div class="col-sm-12 text-right">&nbsp;</div>
</div>
</div>
<?php
$odd_even = 0;
$liste = '';
foreach (glob("articles/*/header.html") as $filename) {
foreach (glob("articles/20*/header.html") as $filename) {
$article = basename(dirname($filename));
$odd_even = 1 - $odd_even;
$header = file_get_contents($filename);
@@ -62,7 +118,7 @@ foreach (glob("articles/*/header.html") as $filename) {
$header = str_replace('ARTICLE',$article,$header);
if (!file_exists('articles/'.$article.'/content.html'))
if (!file_exists('articles/'.$article.'/content.html'))
{
$header = str_replace('####BUTTON####','',$header);
} else {
@@ -81,79 +137,10 @@ foreach (glob("articles/*/header.html") as $filename) {
echo $liste;
?>
<div id="contact" class="container-fluid bg-grey">
<h4 class="text-center">CONTACT</h4>
<div class="row slideanim">
<div class="col-sm-5">
<p>Contact me</p>
<p><span class="glyphicon glyphicon-map-marker"></span> Shambala</p>
<p><span class="glyphicon glyphicon-globe"></span> Employer : Mutiny</p>
<p><span class="glyphicon glyphicon-phone"></span> +00 666 666 666</p>
<p>
<span class="glyphicon glyphicon-envelope"></span>
<!--Place the code below where you want the link to be displayed-->
<span id="obf"><script>document.getElementById("obf").innerHTML="<n uers=\"znvygb:nyoreg.frnaquvyf@gbcvfgb.arg?fhowrpg=pbagnpg\" gnetrg=\"_oynax\">nyoreg.frnaquvyf@gbcvfgb.arg</n>".replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});</script>
<noscript><span style="unicode-bidi:bidi-override;direction:rtl;">ten.otsipot@slihdnaes.trebla</span></noscript></span>
</p>
</div>
<div class="col-sm-5">
bookmarks : <br>
<a href="http://inconvergent.net/" target="_blank">Inconvergent</a><br>
<a href="http://www.datasketch.es/" target="_blank">Data Sketches</a><br>
<a href="https://bit101.github.io/lab/dailies/170310.html" target="_blank">bit101-github</a><br>
<a href="http://www.beingcaptainzero.com/" target="_blank">being captain zero</a><br>
</div>
<div class="col-sm-2">
PGP : <br>
<a href="page.php?id=00000000"><img src="articles/00000000/public_key_qrcode.png" width="100%; height: auto"></img></a>
</div>
</div>
</div>
<footer class="container-fluid bg-grey text-center">
<a href="#myPage" title="To Top">
<span class="glyphicon glyphicon-chevron-up"></span>
</a>
<p>Bootstrap Theme Made By <a href="https://www.w3schools.com" title="Visit w3schools">www.w3schools.com</a></p>
</footer>
<script>
$(document).ready(function(){
// Add smooth scrolling to all links in navbar + footer link
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
$(window).scroll(function() {
$(".slideanim").each(function(){
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
$(this).addClass("slide");
}
// if (winTop < 400) $('#logo_topisto').css('visibility', 'hidden');
// else $('#logo_topisto').css('visibility', 'visible');
});
});
})
</script>
</body>
</html>

View File

@@ -36,7 +36,7 @@
padding: 60px 50px;
}
.bg-grey {
background-color: #f6f6f6;
background-color: #e6e6e6;
}
.bg-grey-odd {
background-color: #fff;

View File

@@ -24,7 +24,7 @@ $block_hash = blockchain::getLastCacheBlockHash();
// ---
// --- Le cas échéant, on cherche block passé en argument
// ---
if (isset($_REQUEST['block_hash'])) $block_hash = $_REQUEST['block_hash'];
if (isset($_REQUEST['block_hash'])) $block_hash = $_REQUEST['block_hash'];
$the_block = blockchain::getBlockWithHash($block_hash);
if ($the_block === FALSE) die();
@@ -45,7 +45,7 @@ if (isset($_REQUEST['block_hash']))
header('Content-Type: application/json');
}
$message = '{"hash":"'.$the_block->hash.'", "block_index":"'.$the_block->block_index.'", "time":"'.date('Y/m/d H:i:s', $the_block->time).'", "height":"'.$the_block->height.'", "topisto_outputs":"'.$the_block->topisto_outputs.'", "prev":"'.$the_block->prev_block.'", "topisto_inputs":"'.$the_block->topisto_inputs.'", "topisto_fees":"'.$the_block->topisto_fees.'", "topisto_reward":"'.$the_block->topisto_reward.'", "nonce":"'.$the_block->nonce.'", "n_tx":"'.$the_block->n_tx.'"}';
$message = '{"hash":"'.$the_block->hash.'", "block_index":"'.$the_block->block_index.'", "time":"'.$the_block->time.'", "height":"'.$the_block->height.'", "topisto_outputs":"'.$the_block->topisto_outputs.'", "prev":"'.$the_block->prev_block.'", "topisto_inputs":"'.$the_block->topisto_inputs.'", "topisto_fees":"'.$the_block->topisto_fees.'", "topisto_reward":"'.$the_block->topisto_reward.'", "nonce":"'.$the_block->nonce.'", "n_tx":"'.$the_block->n_tx.'"}';
if ($_REQUEST['FULL'] == 'OK') $message = json_encode($the_block);

View File

@@ -0,0 +1,25 @@
<?php
// ---
// --- La config globale
// ---
chdir('/opt/TOPISTO/apps');
require_once '/opt/TOPISTO/apps/global/inc/config.php';
// ---
// --- External dependances
// ---
require TOPISTO_PATH.'/ressources/vendor/autoload.php';
// ---
// --- Internal dependances
// ---
require_once APP_PATH.'/blockchain/inc/block.php';
header('Content-Type: application/json');
echo blockchain::getSpecialBlocksJSON();
die();
?>

288
data/last.json Normal file
View File

@@ -0,0 +1,288 @@
{
"Height" : "610613",
"Hash" : "00000000000000000002e115eeead81ee6977eb7697c267748cb5bf8b4dd761b",
"Version" : "541065216",
"Timestamp" : "1577789001",
"Nonce" : "1978572825",
"Previous" : "0000000000000000000e27bcd20a2c05064636b6abd52975d59062a803d86fb9",
"Merkle" : "09f4975c0c558d0bdc82244d0811ce648773799ea2d5a7211ad69aa7ed156440",
"TX" : [
{"Hash":"430e1560a55ea77c4334389f7e5c57eb76675edbafe46bce72be5238f8768685", "Timelock":"0","Amount":"1252070815"},
{"Hash":"ab88d5013a926d1a0b04384ef63cdeb59e8e015f76698ed64a72f87054854284", "Timelock":"0","Amount":"1408948128"},
{"Hash":"7f7ff846fd1a08bd8ed698711cf69b5d5f84f64a14348284f79f2537c89c7f03", "Timelock":"0","Amount":"52585327"},
{"Hash":"87b24db8855066ffb61156ea5e0ff874a489bc26a079c8de4207a02319f268b7", "Timelock":"610611","Amount":"4370410956"},
{"Hash":"091c632678d4353356d2aa19a0a5022b48e43dc5839b976dfa4db3a27df7cfae", "Timelock":"610612","Amount":"137301334"},
{"Hash":"2ed396ad457cddb176c07099022ba27e2fa8b8714b629f4cd642f2714c3b4007", "Timelock":"0","Amount":"829288"},
{"Hash":"33c2694dd3acedb0b333817dadac4e52fd2254a50a70337bb84bfe473718154b", "Timelock":"610612","Amount":"2573250"},
{"Hash":"d8f67c3a56409ec0574809b5d68ae8418605396815794a31110c2b3472e0ef8e", "Timelock":"610612","Amount":"25997116"},
{"Hash":"4551b5df7a1bea50a625260b1f528d6fa3b8748d6768909791aff3a75dd110c0", "Timelock":"0","Amount":"2307242207"},
{"Hash":"00b65c3b22bf12d9e1609e002c6909cad91a3d76f4855652848670981a9ccd13", "Timelock":"0","Amount":"172453"},
{"Hash":"368128cc945384050a9af4f595334de573b18261ca36d90b6f48e8b51aa04142", "Timelock":"0","Amount":"415333"},
{"Hash":"438e52615dcc7bf45ebdd8487cd1e817ac53ab646e1748ffcdfcabd52ab85352", "Timelock":"0","Amount":"199508"},
{"Hash":"90c7bd4a106935cadf8726c1ece872d69a5223001ab46d8dd67453f71d0a527c", "Timelock":"0","Amount":"442388"},
{"Hash":"f4e947923b060117db520238f8d695b5733d843626a33d8adfbb25768b0ebaa8", "Timelock":"0","Amount":"172517"},
{"Hash":"ff1083f1013239427e1325836bd57e6e5ed6dd56c2a59d868e2e6a1086f065cb", "Timelock":"0","Amount":"172560"},
{"Hash":"464e5f5b4ed996b4fec45a2e78e3b0e7f1419be4e581ff87b2bf42582c81adf7", "Timelock":"0","Amount":"442334"},
{"Hash":"ff8b744bcc7433fc2b729cac2e51f88c86b33ec58aaf2a7800e965b32f40563e", "Timelock":"0","Amount":"442388"},
{"Hash":"d52ab83f47d71c22af57fa10fdbe3d7716d94c8b68c0a07734815b41901d395a", "Timelock":"0","Amount":"172507"},
{"Hash":"d7e172f6826ec1099400c7af6ae76cf9e8221f60bea298552df5a61d2d80be62", "Timelock":"0","Amount":"226453"},
{"Hash":"b8506d4e89af438bd8e3d733a6b81bc7e8f1e19032f90a6202c432d2e2b7fd72", "Timelock":"0","Amount":"172561"},
{"Hash":"59a3ce63eb6ce9ab6421a09f1aea495cc68fdcb0a2772449a5f6e60686dd3a7b", "Timelock":"0","Amount":"172454"},
{"Hash":"d77460002718fef51efea5529061c8ba76285660ce2b8b0070ff9aee2961678c", "Timelock":"0","Amount":"226453"},
{"Hash":"e44847a9fb68ceebe63ee8ea6e12b78a22de10c518f84f029b901b7d9a5ee68d", "Timelock":"0","Amount":"442334"},
{"Hash":"0a7061f1806a4fafb3f8f8c1ab5508268b598f15b775b4c9f1029da6e63b7aa1", "Timelock":"0","Amount":"442334"},
{"Hash":"5059939f8c9e7e2090c9615c87aac3247658ccfabd83eddff7def430e89473ad", "Timelock":"0","Amount":"415441"},
{"Hash":"1892d746c63082d84660d302c2976f52af6489376a3a4bfeac1296d91a47d8ae", "Timelock":"0","Amount":"415388"},
{"Hash":"eb6263a9cc47b37d9e78dfdcd9a81ee7a0a93423ab9809e94dd50402da8ad3b0", "Timelock":"0","Amount":"442388"},
{"Hash":"3a608b91415e0d5e5e958c9aa3adc9308ac6becfd817d49c868e682e9923fabb", "Timelock":"0","Amount":"226507"},
{"Hash":"175e437471fa7a87607b0f69b60124c852b7c3bec604533bfd3e537e67d58cd7", "Timelock":"0","Amount":"415387"},
{"Hash":"764ac68edd0bb5583923b382736a36ac080fc513f157b1eddca1cc6c5d0ab4de", "Timelock":"0","Amount":"226399"},
{"Hash":"aa0773b9f6f156a3739204b59f1399cbab7f8d15d256de3678efccc7ee79a3e8", "Timelock":"0","Amount":"442388"},
{"Hash":"5b34a8c685f8d1ffa92062c5b9a907289e96a26d6ec05144eb79e6f0c5c89cf1", "Timelock":"0","Amount":"172452"},
{"Hash":"0a3a1e763e1b39ce1f412bdf1d1ef5931237a49945012b234082bb2c1f1901f9", "Timelock":"0","Amount":"442334"},
{"Hash":"8929dd3205413caa862c85cca472f0d6354277923ac53a607028389942513afd", "Timelock":"0","Amount":"172614"},
{"Hash":"c4b10b1aa965dd239b52d6fbdc8454a371f064ce1b188f8ff2984e56cf231416", "Timelock":"0","Amount":"172561"},
{"Hash":"834514b9c659c3d337e218c6c4f5e2dadfc29c09424f64aeab34fcf75300681d", "Timelock":"0","Amount":"172400"},
{"Hash":"84809433f9b27b32d44dd928cd790d94de91ad42b1f2dc17304ee56cc8d67d23", "Timelock":"0","Amount":"226453"},
{"Hash":"1cdbc639f27b1d95781bbf708623a54dd3694b33253942741eb6266ca2a32b3f", "Timelock":"0","Amount":"172507"},
{"Hash":"cae61d427b4f3b53665768ed5bd188e91c34c1ff81cc73bd54486c2965062f53", "Timelock":"0","Amount":"415388"},
{"Hash":"4a7e289c57fe0221e39d3a9a7c13bf1004a4d594d7dcd3102b8e7ffea167915a", "Timelock":"0","Amount":"442334"},
{"Hash":"ef1e7dca343e90c8e03285463579d8fbcd886fe7552681ba574206af0b84c772", "Timelock":"0","Amount":"172614"},
{"Hash":"1fdbf1cee2838bb1fa3d2f3dc7aa9cf312a4e5de1ecb390244c2c6eef05cada7", "Timelock":"0","Amount":"172561"},
{"Hash":"5fcda12bd9da552d9cf6921689eb6d2bfd0f5736725b55cecc13c8145c7662ac", "Timelock":"0","Amount":"172398"},
{"Hash":"35ed4fc56ddda175a2a22b07e66bf85ce9128d33214a930cf8a313c66e6f85f8", "Timelock":"0","Amount":"172506"},
{"Hash":"ac504cb9488ec9cfa4df07398a18fc07a1a419d5bd5102bc0ef45c429b27f1e1", "Timelock":"0","Amount":"37910603"},
{"Hash":"e6814a02507e07d18970151512ade5dbc083fe87921475d96d60669d6df03ac9", "Timelock":"0","Amount":"1181500"},
{"Hash":"3b390023200a6a1b205a0f706c04bcd2f52f11a0622e5992dfbd59ac0fcc6ab9", "Timelock":"610611","Amount":"109555200"},
{"Hash":"3bdd3340e02fe7e6163bffcc923e76660a20362187a3e7423f3ef70553cf16fd", "Timelock":"610611","Amount":"1434152"},
{"Hash":"974efc78ddf5fa212ab015d5cab8ef985139522857820d6d2539a2a2e347af26", "Timelock":"610611","Amount":"1420756"},
{"Hash":"a9c0e05edd7be77210e80bf1c55513a0f5a7306ad3a555193af278d68084e09b", "Timelock":"610526","Amount":"1407360"},
{"Hash":"786fb70f2cccb69848abfbc7dbb88f5b8381cfb751a569063e56fc040a36b15c", "Timelock":"610611","Amount":"1394014"},
{"Hash":"950f03c106f5b48de77147505d5aecbc1af2653c849056860fe4d9a7418022fd", "Timelock":"610611","Amount":"1380618"},
{"Hash":"4f0d9dc0858458b15bbef552d6109577821db359cb97056c2c4914c45b4d1940", "Timelock":"0","Amount":"9343098"},
{"Hash":"c23db3a178b0e81fc83c462705518ededf56de524309b1a66279ee12879ba176", "Timelock":"0","Amount":"118208932"},
{"Hash":"199c060f771b52e47dd17af1d9273ac1a1aedec30c9dfc93b4d61db12b341728", "Timelock":"0","Amount":"9341082"},
{"Hash":"77baaa6822444fa968b6b21195b2f26d9543622e508d1afef9f2ce044aed7032", "Timelock":"0","Amount":"9340829"},
{"Hash":"bd3ce87659d9bf61730138b5f79c6bc056b0832896a6d984cf1eae7284058418", "Timelock":"0","Amount":"9328349"},
{"Hash":"fc512cc59bb13ce369542b03cfaf877fc3becc98f1949dcab9037eabd8870564", "Timelock":"0","Amount":"1778747"},
{"Hash":"51181d9de70705d063506caf35f539e0b570816f98c8aa77e3b1530c8d9e29c0", "Timelock":"0","Amount":"1778624"},
{"Hash":"a569f21c36c5a2c9dfe1465e1ad44dbfbe76fa8fb028af0c263e1eab95c807c2", "Timelock":"0","Amount":"9327992"},
{"Hash":"a5bbdc76d94faa4e56eab49c3c8faf1d56c3c972695072a53c9534195b2602d3", "Timelock":"0","Amount":"1780330"},
{"Hash":"93f3b439a44f7fb4c90c410aea40d1a6968bbbb4807d4add7beb2b5d3e715f14", "Timelock":"0","Amount":"1779710"},
{"Hash":"ebb20b84a721f902c7f0349774d4ee8d7f58ad067fae718407a885797097fd77", "Timelock":"0","Amount":"20884786"},
{"Hash":"75eb8805b3014a13bd0e73062a636d1d006d6f13e79fb72645dd4b170684f686", "Timelock":"0","Amount":"2588900"},
{"Hash":"10e74529beaf33ce82148373f9f05561c4c178fdd9cc0ec75197de9e4ac90905", "Timelock":"0","Amount":"4899475"},
{"Hash":"77a14c6afee21c6db185075b173196b71f9cc88137c0c6030a3a45d411def53b", "Timelock":"610611","Amount":"2294190"},
{"Hash":"bca263663f36b5dcc800f0ff103ac884d331d704df27ada5c9970a748a5411eb", "Timelock":"610611","Amount":"2821732"},
{"Hash":"b17688fb601092a4f1826c4589c88b84441f0bffc27120cf0499cb992bc309a0", "Timelock":"0","Amount":"7513163"},
{"Hash":"a1129c0f13794c33f7bbd43acb6510b48d9f6958d4d8369275945db84fb2cf65", "Timelock":"0","Amount":"25945760"},
{"Hash":"7caf265d8c38089d58fae9a07210ea3fa9daa3b906c00845d0fd7fe8aa5cd5d7", "Timelock":"0","Amount":"802895"},
{"Hash":"53639f44f3675c3dd5da703aa3cd12dd931fc4685949cbd55c4654c734a67eda", "Timelock":"610525","Amount":"1930027"},
{"Hash":"9f0a66a02460215f5c9e8f1f9e0bd213f6422bf1e03c50921ab150387707cca6", "Timelock":"610611","Amount":"8879050"},
{"Hash":"c7758975a419c2cd3055cea02118c8f3a86e4a4597c6957d04e7640ebc86b7a0", "Timelock":"0","Amount":"47696224"},
{"Hash":"801e013770a9b8ee232a4c48eb2734ac61276fa27afcf5ecefab4defb231da35", "Timelock":"0","Amount":"3610116"},
{"Hash":"a447c26916b130d4293bdad593716d2a8b28a95309a025354adb0e9dd56e3752", "Timelock":"0","Amount":"1695019"},
{"Hash":"77e3e0b3c955f9327de85ff8852988b4ee8d7995945a908e8adbdd31f7e14d37", "Timelock":"0","Amount":"245120348"},
{"Hash":"978cb28e1e3d1285a59a89560736d14dd7e219cea4985b051d6cdcb7648cfde5", "Timelock":"0","Amount":"109305802"},
{"Hash":"d3aba0f4509139fe1af47112c15814b25123f7dbf436dc1186975e31369c0d0c", "Timelock":"0","Amount":"8672328"},
{"Hash":"f3345d8766bacdece0db04ff3bcbb89ae6916ca752d57d045dee3c324368dd6f", "Timelock":"0","Amount":"697116"},
{"Hash":"90aa1b582b779cbb12ea725ef0931ac497c058f57c95ed46b49d150ca5fa797a", "Timelock":"0","Amount":"46938046"},
{"Hash":"bd266c769b9826dcaf582bfa55e34022dae4c970e0435e29a22a024c2ed48997", "Timelock":"0","Amount":"315857548"},
{"Hash":"c934f2ebb0b6e6e124d5e2bf607c42d6fc815c34482db67be87b9b91afebd6a5", "Timelock":"610611","Amount":"138204874"},
{"Hash":"1b3d99e6afc8ff9fb5f378ee1028b9d6da5c0ac1ab6e05c9629c30da9f022cad", "Timelock":"0","Amount":"17290649927"},
{"Hash":"8a4e6513932c083eb8f29bc82a5c59fca0b3df3c4b01073032a8cece337c8cf8", "Timelock":"0","Amount":"2134590"},
{"Hash":"3b717dde9b891e7d8803b972e42b93fe016e5367be19371ad414e38e9711e687", "Timelock":"610612","Amount":"1189729"},
{"Hash":"0187ef5c6ac4c395deb08dfd178240d5e2440f3694810c665a5dc9715af98917", "Timelock":"0","Amount":"11476313"},
{"Hash":"23b83c1242f24f931226b6a6b753edcc016bf3f3318a1e5d9b9ed7662825801e", "Timelock":"0","Amount":"10772334"},
{"Hash":"35ac2974a3b008e14cf662fcc7ff4fdea0f44b46a317306afbacc81abd3af268", "Timelock":"0","Amount":"11614502"},
{"Hash":"99d5c98fff55040bfb3f631d069f92db86d43a1fe5a5b58305b90fc156008a21", "Timelock":"0","Amount":"4083241"},
{"Hash":"0d4939cec1d06e5d6821db20354085646f3462705b9b6fc5e2479dbfc63e7ad0", "Timelock":"0","Amount":"11573411"},
{"Hash":"4d7d94c6f9340935f9fac63380d71944e274683d8271a7886c5de78dab0db102", "Timelock":"0","Amount":"2370883"},
{"Hash":"49e0bee994a241b6a5cd8c6921d7eeec2198e50035e9bfe92290d1ca55db8b66", "Timelock":"0","Amount":"36245331"},
{"Hash":"05fbe4e855613c1a62f91f58b2ff3f39526030d46b7f00a8a4e486eb0a1c68a1", "Timelock":"0","Amount":"36245311"},
{"Hash":"f341add38baf66a365302997cdcfd4ef78154302ff90f4c01eb7659454211812", "Timelock":"0","Amount":"1830231"},
{"Hash":"08b9c10598ba595aabf808d17965e13f24dc664ad671cccb886372ca510e9b93", "Timelock":"0","Amount":"690565"},
{"Hash":"297cf01c89f9499348d245f81b5d6f48156ae71d22ccd09e0e1a9978df606da4", "Timelock":"0","Amount":"10004692"},
{"Hash":"d26dbe9426bc55d1f428d7f71a332511a4927c61a5387e1cf5bba920c9c46c15", "Timelock":"0","Amount":"62232459"},
{"Hash":"3f9aff8c341bdd6afdd3906c3eaae891e23a31910050defe9c5f18bb17ae07d5", "Timelock":"0","Amount":"59916685"},
{"Hash":"9541401b5af8348b1e9ee58692f0f15af82d9435a66ab31842c220ec88398bee", "Timelock":"0","Amount":"59488224"},
{"Hash":"6fae3b219cba8c62fda41471ad0a92e7f15bc8a65095a9521622b577fd48f37f", "Timelock":"0","Amount":"56648936"},
{"Hash":"6c9a8302eb69c447362cc2a50ffaa01f3bbc48139a974e87951bc345e90b0858", "Timelock":"0","Amount":"48492217"},
{"Hash":"c32a46c407a008b73b0ecca3b0a1d3ab905b15499cca314951894e7296e89494", "Timelock":"0","Amount":"47430066"},
{"Hash":"7ea69120fb99685089da3c9cc35b9575749afc5f67efd47223414036cafb827c", "Timelock":"0","Amount":"28914493"},
{"Hash":"a722bc55d7537f1c8bd8c6f11d58e03e8e26808080486c6ca44e4b8573b7fe6c", "Timelock":"0","Amount":"12204009"},
{"Hash":"4ee5de1cc3eba8252dd6e7bc74c6da2e08b9803ffe21e0539f4da3b1aa9c5521", "Timelock":"0","Amount":"596830"},
{"Hash":"9dadb5b119f67fff4e6d72614cb889c0f81f57f1cbdd18f11b723af2af458802", "Timelock":"0","Amount":"1092617"},
{"Hash":"baa4f5e91b453f85c1838fe3ab9fa6f7e65bc075e62cb48e4beb2308307f00e4", "Timelock":"0","Amount":"613854672"},
{"Hash":"83b1a68a0ede876c9747e103df25e8d334ce08147b10ef2eff3aa094f1855e63", "Timelock":"0","Amount":"76576"},
{"Hash":"f7f7d6800091828a57b255e8b7ace07319f831005829f901de39fe95304a4849", "Timelock":"0","Amount":"516018"},
{"Hash":"7908c475e26c3a148d15282afa31bef739b25183bb7ce5437aa0e84f3dcdcbff", "Timelock":"0","Amount":"976581"},
{"Hash":"44f7a0fc1e2b4f78184e58a943fc72735e8edc65d469ad2a558154c3a894de3a", "Timelock":"0","Amount":"46174460"},
{"Hash":"8774a74f7998a01a5bf0f1c80fc7690ee08addb2146550b2f06e583793aaa8f3", "Timelock":"0","Amount":"3908771"},
{"Hash":"ee3fc85e94640147e2b74bd8b263936e02e7844e3e3865c18d3d4e876d6d5115", "Timelock":"0","Amount":"54029203"},
{"Hash":"110a64b5152ff73956dc46c9cbaf994742b782cba74150af4995237615e63a5e", "Timelock":"0","Amount":"1864060"},
{"Hash":"8ff0fa0f2c0f141549e72723a2fab1fa0093b5b80f5fb12945ff73bef180b192", "Timelock":"0","Amount":"1093080"},
{"Hash":"aa05d3f9239c50094413c4270af895652e0c3acdee41f5441ba2fe24304b40e7", "Timelock":"0","Amount":"17960007"},
{"Hash":"d9956a24133fb231e178aaa20d6762fc70fd201aac6717634abe1572a46839fc", "Timelock":"0","Amount":"4140524"},
{"Hash":"9a630c4c8c5dff30dcea319068d4a9c0c1401860f4cfa6931910b69a275badbd", "Timelock":"0","Amount":"1252648"},
{"Hash":"ff8eeda68b788b83aa6591b3690f87ffa17f85e1f61490cade92e0bc142b0b2b", "Timelock":"0","Amount":"552000"},
{"Hash":"6d3d40c04f66a8200b2b9b508f0e72b80315f6c4ae233d64a0d62aa3fdbceb37", "Timelock":"0","Amount":"7546810"},
{"Hash":"22ac47f4e5eb62f77454df2e8c7ed2d2a234a5016738ca75e1653be43efcd0f1", "Timelock":"0","Amount":"16808660"},
{"Hash":"ef48bdce7be5da3c3d359b2b3f1b8d036143625549f9b9e36e96381966375b2b", "Timelock":"0","Amount":"273426"},
{"Hash":"f8bdc6db5dcfc62a374304d356470658839d595159a752bda2875a2a5947cdf5", "Timelock":"0","Amount":"15014603"},
{"Hash":"f39b3fbbb7814041e8d9308481ff66c28e0f155e035d454391d01e606421c11b", "Timelock":"0","Amount":"32377579"},
{"Hash":"591db08ca2d396de4e0d930b8b81e67d77165f33386f64b540cbbeb5d8c04dac", "Timelock":"0","Amount":"5537223"},
{"Hash":"6fbc22e1852563db0f25e1cc740834c683947ac7ef03c73ccb457d32d56b99ec", "Timelock":"0","Amount":"4099008"},
{"Hash":"24d61de3080367401e7cd3debaa1b05ae54bf205fe40313bfeb8be3751be07be", "Timelock":"0","Amount":"17144935"},
{"Hash":"b88e78277759f488a616855021776d2513dadc7600cb6215c3b78e1abe0cebc8", "Timelock":"0","Amount":"1786188"},
{"Hash":"fcf5cea27e6d0a2593843416f1ad4045c78e4d189d66648948783107971065cf", "Timelock":"0","Amount":"545170"},
{"Hash":"f7108c7615e587163df51b99a408dc3a07a6b25855fd348333400d6c04614231", "Timelock":"0","Amount":"70574654"},
{"Hash":"7a79a71655a0aaa232ab8c9adad799d1a3b0c968a6c8cde528642b1a5e7733d7", "Timelock":"0","Amount":"602315"},
{"Hash":"0f99f2acff77da93de76faff6976dcc4c77c043d3c362d7a1a60cf702546b5dc", "Timelock":"0","Amount":"84998663"},
{"Hash":"57cbd37b4af4c95e56c8ecd2d630092bcd69c8ff21cc42ff02ac432b857c9900", "Timelock":"0","Amount":"1466751"},
{"Hash":"964a6ed783cf7308f3ff6772c2d5ff63a3bd4bb39ffdcc4081873943705e546b", "Timelock":"0","Amount":"6509"},
{"Hash":"efb97e437c294603de145eae3ad958a6ff4126f3aed33e7b55dcba081bdb2e1a", "Timelock":"0","Amount":"93282264"},
{"Hash":"703977a73c8c10d97b599406fd2271e051f1c0cffda752d2a5f594e6685d8261", "Timelock":"610612","Amount":"79687580"},
{"Hash":"51c57ea0d3790def7d66b774a26a0ba98bb6072317ebc90eeab3a80df7b49d20", "Timelock":"0","Amount":"777507037"},
{"Hash":"1126a772cc0529d5fc95db96f7dfa5f5180dcd7477ee6a4ba0a384de6ac17a3b", "Timelock":"610613","Amount":"57169215"},
{"Hash":"5234985816f4c27dccecaed5464774741a17cc488edadcd0e14c6199318167cf", "Timelock":"610611","Amount":"692000"},
{"Hash":"e04c15750207381cc5b8d47bdadc3e0945c3d4ce626099389f454d1d0d99ae7a", "Timelock":"0","Amount":"129130"},
{"Hash":"58ebb62cc184edfc2a242b83d22dd03f6cc5e0982977adeb68f242cfbd076cfb", "Timelock":"0","Amount":"95948947"},
{"Hash":"f3d84b166bbc0f93fbda033eb8b56d5c34efe557451fb48138baa217e7a4273c", "Timelock":"0","Amount":"55938194"},
{"Hash":"47143be5f2ac1be85e424ddd5388d04aa4a77a9ddd4743e887e53d9e10a35214", "Timelock":"0","Amount":"15865380"},
{"Hash":"bb85cca828d6503e470c4d425a1bb75db4af3d3be97234ec8806f3030fe5885f", "Timelock":"610612","Amount":"84370181"},
{"Hash":"810ed0d85d37e4893a399a672e3f91d94f09aa6d84065ab806845eba95dbce2c", "Timelock":"0","Amount":"3386237"},
{"Hash":"9165184e73b8a54ba1e5c16dc5f37e919cf83c59529e6623163cc5088a1e0962", "Timelock":"0","Amount":"1066271"},
{"Hash":"44d5ce2d5640c202bba300fc9d4e78dcd42b0a6a6af34dda3662792c34a3e85b", "Timelock":"0","Amount":"14817954"},
{"Hash":"e35f504d9240169cb1042ca1cb035d3e67754dec6294f0ed7dad2386bfccf0f2", "Timelock":"0","Amount":"5595232"},
{"Hash":"1fc03a9c90ec8eff9c443f79be05461b1d76d018ad817793e87ad54e955f88f3", "Timelock":"0","Amount":"16904522"},
{"Hash":"0d337f6e9ef369b7b0d63654528ebeb9bef149bd9e46178a05b1943c4acfc7ba", "Timelock":"0","Amount":"56054252"},
{"Hash":"4a8799db89c87cdc01030690c8334f07134a745f1bf39de94bc7553b19d0dbff", "Timelock":"0","Amount":"9992155"},
{"Hash":"1f95bca1b96a52dc0369576abfed782aa245940a82ee3bdfeb9ef8782cd7e93a", "Timelock":"0","Amount":"4662624"},
{"Hash":"6ba744f9e596470675decede86bb17aae566a50916d9d552d604a7b8c204d089", "Timelock":"0","Amount":"3146974"},
{"Hash":"d78534e7dcf544126beae5f2403aa8367303b99a6df12dce659e4259bab3b298", "Timelock":"0","Amount":"200306"},
{"Hash":"c1a15a8c6d05d43eaba0e0fd0a75ce2e51df50c04739dd4ddbc39044ade1191d", "Timelock":"0","Amount":"1596303"},
{"Hash":"5208ea98e3c4265943c428917e7c5290ce31320f742d28f9506302dded938638", "Timelock":"0","Amount":"11686374"},
{"Hash":"095e3e956f640ddced8966aa65fade1f3c3b0cb47064464739866be018f6e0b7", "Timelock":"0","Amount":"1729712"},
{"Hash":"474d4140d8e63574ab11bebb82bdec1a27a4fb3e69c777c11ebb46818ad58ad3", "Timelock":"0","Amount":"100890"},
{"Hash":"11c2a22918fa0c52eb3b58c9de0f204baa515bffa76e8ab0bacfb1bcb284e809", "Timelock":"0","Amount":"1307062"},
{"Hash":"574d371439d9a89b600cc330f3476cb7144520167ff8a554bdcd82893461ff0e", "Timelock":"0","Amount":"1223399"},
{"Hash":"96ede43efd211a1c305ee28e22757a3c33cb9ace76bf4a5940b984efdb8c1734", "Timelock":"0","Amount":"33369356"},
{"Hash":"3702029ec7041263a1b2fbe0c803489347c6ca82526361f7ab57ddeff3c61352", "Timelock":"0","Amount":"888722"},
{"Hash":"1c0c4b8d9c48e1787ebb293493d0bc9cec27b6ac14b79b638ee1ec71ff3b5bbb", "Timelock":"0","Amount":"3239060"},
{"Hash":"a5635968d11902b1927142349654adb8ee37d3c66fb65f8ec0446775e62ea839", "Timelock":"0","Amount":"39293"},
{"Hash":"f75e699a3aed32d8754f64fcb8b95ccbe38170a740cbf304e1b16f263b2e532c", "Timelock":"0","Amount":"880501"},
{"Hash":"fc24d67b967e9c3d571e0061b5b22fe63d6c31995b5bfe748580e178064adcac", "Timelock":"0","Amount":"1999501"},
{"Hash":"dfb900019a868e5907b7b646f8675f153bcd314548648431d40260929f8366b1", "Timelock":"0","Amount":"3623549"},
{"Hash":"63f781ca03831a1428719ecc1128cc429796c49f654500ceb9564d49b1a8a0d6", "Timelock":"0","Amount":"4356568"},
{"Hash":"60832cda55888b65da7d0051c74b9a0167207d1e35ca2fa5d756a88d35631c88", "Timelock":"0","Amount":"1191810"},
{"Hash":"20a47f6a23155384dfd724b8ff9fe8721cd2c7f4e63e953c3db6a8d74a776fc9", "Timelock":"0","Amount":"213303"},
{"Hash":"5db600482d5f8b597eeb6df99e6abbfa10851ffc43c9fd0e9e7ebdf1093b7449", "Timelock":"0","Amount":"276881"},
{"Hash":"f14b767fb4d3813d165c0c085d829a57c91144f378ae4bfc353f1251654c071e", "Timelock":"0","Amount":"73236"},
{"Hash":"3203bd34798fd2653f6dafa8dc96906b162b9610a5f3a978dca4cf6462d4877b", "Timelock":"0","Amount":"21647"},
{"Hash":"f9881901ae72f2a2d45900860873e17c42afad5ae939fd9a9508c905c7fd36a0", "Timelock":"0","Amount":"837681"},
{"Hash":"88de4f89b929de2d3693db2a2f2a4f7fb8b09e786cdb84cee28251a54be9eab8", "Timelock":"0","Amount":"945945"},
{"Hash":"23d7451a6fb818b8c5f4a76d2ecbc82fa487876afeea6136887d138897b579ea", "Timelock":"0","Amount":"3055782"},
{"Hash":"5a1e88345111227c80a65b3eecfd4ddf04e81ddf66cb23dc48e684d7b25ac219", "Timelock":"0","Amount":"348590"},
{"Hash":"972069aeddfbf42a90044389619f17fb5eba93492f1e5092e2b45f0e63b1a64a", "Timelock":"0","Amount":"100948"},
{"Hash":"0abe46e255e647f035b8a20ab55a632564a66c8d39eafabca60e59fff8aa4458", "Timelock":"0","Amount":"38190"},
{"Hash":"a89fc18abf2bbc87aa547deb3ea30296497b2106ea9dd179b4fb0c6c8706f159", "Timelock":"0","Amount":"101439"},
{"Hash":"310942f43f904106ac267e404e62f6eb01b4711d7bcd1f1736d990270a308c8a", "Timelock":"0","Amount":"458696"},
{"Hash":"0dc5e678214d604604b2926a5da391668fdd7011d8516c8a2eee3ecb0d87b095", "Timelock":"610612","Amount":"320000000"},
{"Hash":"6f70d9069b382513a148eb79ed54b1ccd4ec158df6c2cb18314304e369f15a52", "Timelock":"0","Amount":"79035653"},
{"Hash":"71dc72310d9a9b994ce19f4c03cdb7f6528b34aca0075cb5d74c6c68915d3a9d", "Timelock":"0","Amount":"2504027"},
{"Hash":"893a4babc462051b8a0155cbdd545908b418ea6e110e5a13ef3a4fad767bda00", "Timelock":"610611","Amount":"1478499"},
{"Hash":"fcc431847d59c950b45722c3f7f0c15561322003c0e3ed56a8aed21267a4cf26", "Timelock":"610611","Amount":"148935329"},
{"Hash":"097d85b4821c32f742eaa41126a40f152424b789e2d4ea103ff8048884dfc871", "Timelock":"610611","Amount":"410979578"},
{"Hash":"3de0395922a468f4582b47fcb86e09de5c300aa7deb564505881718a9f81f990", "Timelock":"610612","Amount":"86910899"},
{"Hash":"7f496800d68732533b10884a448079bb36d5246fcd3944c3213f8fb185d25a5b", "Timelock":"610612","Amount":"1677195"},
{"Hash":"8aa85614c39716ab9ef6c775a8561108c790d953a8f8d6ff41d81098b5caa11b", "Timelock":"0","Amount":"1600823"},
{"Hash":"5b6d8c3ecc320f7d451b329ac5ec92efa755a8fc780f6fdc4a48f19f31b04e1d", "Timelock":"0","Amount":"4898293"},
{"Hash":"6dfc9912e0b488bb9b5e8a289f77fd8a099460b84843a63c32de0d705c4f397e", "Timelock":"0","Amount":"8275011"},
{"Hash":"2eb66f5e336880ec848463403f6e1c527bc7247c397d1ece7e733d1617235798", "Timelock":"0","Amount":"7451649"},
{"Hash":"cd80ebcfd55c08381531a302d157998cca5dc15407d994c2d9e827aaf627bbc2", "Timelock":"0","Amount":"11469618"},
{"Hash":"70fec2714233e91aeb8e1ab2d57f4d32fdbe57b07c056f676d63d1bbdca301f5", "Timelock":"0","Amount":"1799319"},
{"Hash":"20be7a8b20f087ff9ee30c89eba214e74af9bd56e85afc2f415f761886269516", "Timelock":"0","Amount":"157721723"},
{"Hash":"90c027ccf08205b7fe9fcff4510df4b95627d1153ae0056c3c8d80252bfd8205", "Timelock":"0","Amount":"4609322"},
{"Hash":"768b6e5b63b54b3bc37fe2ea495fcf2ae2303fe4dacc6540359561dac7383623", "Timelock":"0","Amount":"21145038"},
{"Hash":"4211d1386b23fabcacd67982b26aae124a88f006494270a5cc86b5601666ceb9", "Timelock":"0","Amount":"124400229"},
{"Hash":"788a270693f8c3c932cdaeda1865ce7872db9899b6bd9a606124ca80146173c4", "Timelock":"0","Amount":"15199613"},
{"Hash":"f5a7146cdb7e75d7897cd70b98fa817fa3c36e1a1c6b42c8dcc9f72198e255d6", "Timelock":"610558","Amount":"1000550"},
{"Hash":"947447dab3ba1b50c801eb37106442e1253595f55b02c14fddf34bde6012c3b3", "Timelock":"0","Amount":"323024"},
{"Hash":"26ac445b31f2bc464dd5eb751ad1a62fec85a9bdb4f0ec47134f7fc75d8cfcc0", "Timelock":"0","Amount":"519323"},
{"Hash":"1243171091b7fed1e1c9f769ebd6226a59023125a7ead697eaa5c6c9f8832427", "Timelock":"0","Amount":"292805217"},
{"Hash":"d36f2df5b4e420e44d0073f53475756ef4d8e404f7e9a1ea3eb3f9ca25f47aad", "Timelock":"0","Amount":"48965812"},
{"Hash":"6431044325da98cd4e321a760d7da40c09d1969316196dcc54381499e5da6c14", "Timelock":"0","Amount":"44999427"},
{"Hash":"9adc8663c50853a0ce7a99723b4e98b06cf4d980ef5738bd4a7155ba2b38d5da", "Timelock":"0","Amount":"1900387"},
{"Hash":"772fd9982e39f71ce3d83f3437364debc6488b1f02b44720b820ad8d48ecaf3b", "Timelock":"0","Amount":"9582288"},
{"Hash":"c40bdca7de3a7df966009833b18673032d3cb875a30a03dd99c91529d13fc6e4", "Timelock":"0","Amount":"4607956"},
{"Hash":"dd8c711a143c68ca88d066cb8c4d78a9312a63a1c95885a90740707e90d6082a", "Timelock":"0","Amount":"35924076"},
{"Hash":"272c78e70846869bf6f2769a9dbfaee799c3a0cd1ec22770a021a43b827ce020", "Timelock":"0","Amount":"1493859"},
{"Hash":"b69bf1d588f2376a695bd8eb0f9ec1a3a06279dd3e1829f3ff6baf6aea6a92f1", "Timelock":"0","Amount":"3615810"},
{"Hash":"f928b036a8d562fd87fd3f3744f95c2a6901d14ba59cb5758cdae45c72771662", "Timelock":"610612","Amount":"4004129"},
{"Hash":"ce7ca845b58a1e894aae420ba70b82f5df865a5024d2d12f59300d5ee8f4640a", "Timelock":"610611","Amount":"2208372"},
{"Hash":"63ebbee7465d03f80a85786519aa88db1d63225d8799d7ab13741185a5dd81bc", "Timelock":"0","Amount":"30607316"},
{"Hash":"e3dd757753ff6cfb3e3a1db8cc2d50295e6eb2641668070e92f5efa8d714b5d0", "Timelock":"0","Amount":"824007"},
{"Hash":"80043c175f15c5c9e9dff94833d4f91aca3655092dd97ae417c93e929537e3b4", "Timelock":"0","Amount":"914375877"},
{"Hash":"a0cc08938f3eef38fb09c4d7055218287bec1ec78e4638f53035f6ca6fed26e2", "Timelock":"0","Amount":"206568328"},
{"Hash":"d8812f2ef12be371800ec26df4a89ffc5d2d2741eb8417c0344c0afebc830d1d", "Timelock":"610611","Amount":"8172299"},
{"Hash":"9c9f4360ab3fe07bcd6c8de670d247c89d9f4b4445dffdd47516bf1bb5691caa", "Timelock":"0","Amount":"34998220"},
{"Hash":"d2abc9f9d4b00b121a05d6c391f0fc8ff66d35ed4dc3a32a21eb935f27e5cfe9", "Timelock":"0","Amount":"6571256"},
{"Hash":"5c616154caa404a59acbc4b2583c626a44af0b39045034d4acdc2df0b56046a4", "Timelock":"610609","Amount":"2426712"},
{"Hash":"c8fded8ee21e0022f21aa87d3a4b35b39406245f6d782883fb8426c93d50f3ab", "Timelock":"0","Amount":"891105"},
{"Hash":"63294c0d34ea9bf1ef4152442582f2fed1348c3fd5d29564877741057e199319", "Timelock":"0","Amount":"640260"},
{"Hash":"5150b3c63b594907ec39de381d9d701298f3f1a331018454c3443e0d53c88c5b", "Timelock":"0","Amount":"545760"},
{"Hash":"ca837ed1bea2f1ee672c746cc9568a493c5b6ea2a93aee7540263f7d01c93e6c", "Timelock":"0","Amount":"237690"},
{"Hash":"f77266d54f00730a84ec701bd14d238fa23a606bf29ee1811b1ceeba5598c4c3", "Timelock":"0","Amount":"846060"},
{"Hash":"46d329aff53be4c395db6fdb6645e108f3b338af70aa7f728714cb389badffd4", "Timelock":"0","Amount":"552060"},
{"Hash":"74b5293ce16ab56c6d37a74ea526b33245ba7b96b388442930b5bd16bcf78734", "Timelock":"0","Amount":"197047"},
{"Hash":"eb4a7762da37b44f346ace0ad0832ea84713f5a7f2845ff7119a260639e1825f", "Timelock":"0","Amount":"186635"},
{"Hash":"8177d1d50789b35a79acc0869bb1ce08bca9b6fed317032242c6b130c7d3fec0", "Timelock":"0","Amount":"197287"},
{"Hash":"f7dfd885bcce8458a74de83d4da4ee7c6cb64b3dba94a47507b422815d4844d6", "Timelock":"0","Amount":"197059"},
{"Hash":"0ea4b003160596991bb76746ce3664545710b10dcd853e3afec51d5b69aacd03", "Timelock":"610612","Amount":"5039070"},
{"Hash":"3f20c30db68a4a52b3fcb4da398f77528724a06ccc2aa54314b07ddbe44bace1", "Timelock":"610612","Amount":"18434512"},
{"Hash":"d82cf4f229c4c8e74f7dc128192c058545eefc01e6528d7eff220681df62be56", "Timelock":"610611","Amount":"23567482"},
{"Hash":"0b5208dd76c0c1549c407dc83b53acaaed700a88049009dc583600f63c944458", "Timelock":"610611","Amount":"1555453"},
{"Hash":"684c01e803731bc88ec0e2419ed19c3890298f7c0b5d495483ece46949f3075f", "Timelock":"610611","Amount":"4602272"},
{"Hash":"8c3442f6157f8c605bea12590ce27e565d2ca05eee2f343893e56b1805a2f195", "Timelock":"610611","Amount":"3254296"},
{"Hash":"cd649ba4f7d5f73a68de9225d6fd8cfbdea825f3976c9a7cb2170886a86352fd", "Timelock":"610612","Amount":"6102583"},
{"Hash":"a3099bf1386a6a768dfdf6964b5b410c18b7db88f21e14446b4a0751548fb230", "Timelock":"610525","Amount":"1232642"},
{"Hash":"da6cf1a622c8465ac940a66e45b4a058aa7bd7c7b6528c7199ee47eb3a5e9186", "Timelock":"610612","Amount":"1662053"},
{"Hash":"054b2fe617c7f3472589711d43a62e964fe954c9bda1199ea90f6eccf07505d5", "Timelock":"610612","Amount":"8196614"},
{"Hash":"fe93ce64f01e56de307402f70ddd320eaefbf4829a5ed0466d908e6842878532", "Timelock":"610611","Amount":"212838070"},
{"Hash":"0dc2c34306fbf5ab99b601163024e63063ed13dc2532371dad0ccbf09013de41", "Timelock":"610612","Amount":"986431394"},
{"Hash":"f61fbd11bd65d03b956c887f2d46ff7cf836c006aad18b7250ad94612f82f30b", "Timelock":"0","Amount":"145385"},
{"Hash":"3dd516cb408189b5576e0a28426778416967328bbd15884c11729e0ed1d5126c", "Timelock":"0","Amount":"194250"},
{"Hash":"b0ccf26e5325aabe1574fc4ec856780a1d3610f02ef85170e36b590682bc426c", "Timelock":"0","Amount":"180677"},
{"Hash":"2367d6bd910dc3fe35eca461919a618774a801127ccf13df695924b2b5e57b70", "Timelock":"0","Amount":"183047"},
{"Hash":"b2909891ee0e4fd942839d760be1c5ad490167c6ea9e747ad0c32f75c6a92e90", "Timelock":"0","Amount":"5404771"},
{"Hash":"a5d0ee16a2a4eba67580d7d15db87bce77163695725845ade652d039f7a7dedf", "Timelock":"610612","Amount":"2431061"},
{"Hash":"d312679befb9d51aa59ae05ad79c6ceff5d73ef732c3ebf5b279e850e3a8a803", "Timelock":"0","Amount":"57124"},
{"Hash":"178d4e0dde468f2f7555397ab103afa9b1a9a794c8712c3c93de8b6c6850360b", "Timelock":"610612","Amount":"1236819"},
{"Hash":"21f823e3e9dfcdb6d7a09f7b0a4a3f1460a7529d94ebd9c62888331aa5c11f15", "Timelock":"0","Amount":"1038899"},
{"Hash":"c1a14678b5e766cdfd10fd82f180f53f1c818bb93b61694c49d3e48bf83ec61c", "Timelock":"610612","Amount":"2085777"},
{"Hash":"44e42e283ddb28adc7d1be3c87a1f1f00cc485d0dce7f13cc2a26592cad7fa3d", "Timelock":"0","Amount":"308249"},
{"Hash":"e497755421aaa563baec3172f4994f5e7d81194bcd73e6435ff1d2e78db45d3e", "Timelock":"610611","Amount":"1430901"},
{"Hash":"c58b725bded8622819c8a630c37d632fb528c0f0faecabcf399efe520c842560", "Timelock":"610612","Amount":"2001785"},
{"Hash":"b4f90cc8ea3c61d5d2c6149e34f4c9ae4845a92890a54b6f3c203fd854f64971", "Timelock":"610612","Amount":"1731654"},
{"Hash":"26b44e3c6733cb7367c63d38f68b5321932bd2989186f7038de4b0888a12e175", "Timelock":"610611","Amount":"26296859"},
{"Hash":"2c30bca6de71e4302090dc121b47e20fc5c9eec2cfacdc69c197e9ced8c10f8e", "Timelock":"0","Amount":"636951"},
{"Hash":"c09ce4f0165b7995d6a1b216657210f5deb376226cab7a58bada7bba362edc93", "Timelock":"610611","Amount":"1998128"},
{"Hash":"32ddf000f48be887acb84f32781d8bf2f24f7ea5e4a13f9f4718f70b6c1fe1a1", "Timelock":"610612","Amount":"1790662"},
{"Hash":"0603251530586c9f731704d09710bcdcd862d58097bd9ec0103713f3439e01b1", "Timelock":"610612","Amount":"2024605"},
{"Hash":"ac2baa16cca1cf50168d712c633962c0abcf08ffe08a065752c0250caedb55c1", "Timelock":"610611","Amount":"1486989"},
{"Hash":"2e4b6bb7c08d696131c790310291dec6b747e3e996bfe3d6e563fb5c51866dc5", "Timelock":"610612","Amount":"2203418"},
{"Hash":"40f5f4a90b626346fcff1f1ba490ab53f996cd6bdcdb9a91c00c84c56307c5cc", "Timelock":"0","Amount":"75698"},
{"Hash":"51289eb491361a921e545addda6aa83eda612b3e9a44db9cd09a2cdeddef5dd4", "Timelock":"610611","Amount":"1057522"},
{"Hash":"91f0965412d263e511a08ec3971c5cd6e1f9c3a8f1c03bca3ac752532fd1d2d5", "Timelock":"0","Amount":"431533"},
{"Hash":"ef0b3e7a40283a62720933537d3c7cd35989236f1d5e4eb6e207338e63b93ad7", "Timelock":"610611","Amount":"1624761"},
{"Hash":"6ddb8af0f8ea045159c90bef1ebc4c87a7ed6600b4117dd811e5e9e5e57094d8", "Timelock":"0","Amount":"449055"},
{"Hash":"9f7db89d3e700fd50972c79ef5149f1d18e2ab03f62b1cdb22204dc9682d54e4", "Timelock":"610612","Amount":"1121060"},
{"Hash":"d49a885914128a01a0642b7bd4424fd6aa65c44e1666768a1d1f5d81068928e5", "Timelock":"610611","Amount":"1242539"},
{"Hash":"fb70e5f8fedc9ba3e3bc418c3cbb777b42cff9585b43513bfb32368d3f3997e6", "Timelock":"0","Amount":"295101"},
{"Hash":"35259952a5ddba69338ddb79df345e7bfd5af96c8a9409b9415a3eefe1c3bff2", "Timelock":"610611","Amount":"1579203"},
{"Hash":"a46c28fe069c151d92a9017d98069395aaf29d2130d57ce5b0f6775acb1641ff", "Timelock":"0","Amount":"1196333"}
],
"Amount" : "35563119179"
}

View File

@@ -53,13 +53,19 @@
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
ajouterPreviousBlock();
blockchainExplorer.ajouterPreviousBlock();
$(this).addClass("slide");
}
});
});
});
function changeMethode(la_methode)
{
cur_height = [];
cur_methode=la_methode;
return blockchainExplorer.init();
}
</script>
</head>
@@ -78,12 +84,42 @@
<span style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 60px;text-shadow: 2px 2px #ffffff">TOPISTO</span>
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li><a href="#explorer">Full Explorer</a></li>
</ul>
</div>
</div>
</nav>
<div id="explorer" class="container-fluid bg-grey" style="padding-top:10px">
<div id="explorer" class="container-fluid bg-grey" style="padding-bottom:10px">
<div class="row">
<div class="col-sm-12">&nbsp;</div>
<div class="col-sm-12 text-right">
Scroll down to see the previous blocks<br>
<!--
Méthode de dessin <select onchange="changeMethode(this.value);">
<option value="hasard">hasard</option>
<option value="circle">circle</option>
<option value="circle_spline">circle_spline</option>
<option value="linegradient">linegradient</option>
<option value="mondrian">mondrian</option>
<option value="splinelineblackalpha">splinelineblackalpha</option>
<option value="treemap2">treemap2</option>
<option value="circle_line">circle_line</option>
<option value="circles_spline">circles_spline</option>
<option value="linehashed">linehashed/option>
<option value="peigne">peigne</option>
<option value="splinelinegradient">splinelinegradient</option>
<option value="veraMolnar">veraMolnar</option>
<option value="circles">circles</option>
<option value="line">line</option>
<option value="linehashedtx">linehashedtx</option>
<option value="peignealpha">peignealpha</option>
<option value="splinelineblack">splinelineblack</option>
<option value="splinelinegradientalpha">splinelinegradientalpha</option>
</select>
-->
</div>
</div>
</div>
@@ -91,11 +127,11 @@
<div id="contact" class="container-fluid bg-grey">
<h4 class="text-center">
<a href="#myPage" title="To Top">
<a href="#contact" title="To Top">
<span class="glyphicon glyphicon-chevron-down"></span>
</a>
SCROLL TO LOAD PREVIOUS BLOCK
<a href="#myPage" title="To Top">
PREVIOUS BLOCK
<a href="#contact" title="To Top">
<span class="glyphicon glyphicon-chevron-down"></span>
</a>
</h4>
@@ -104,7 +140,7 @@
<p>Contact me</p>
<p><span class="glyphicon glyphicon-map-marker"></span> Shambala</p>
<p><span class="glyphicon glyphicon-globe"></span> Employer : Mutiny</p>
<p><span class="glyphicon glyphicon-phone"></span> +00 666 666 666</p>
<p><span class="glyphicon glyphicon-phone"></span> +33 4 8 15 16 23 42</p>
<p>
<span class="glyphicon glyphicon-envelope"></span>
<!--Place the code below where you want the link to be displayed-->

BIN
fonts/klingon.ttf Normal file

Binary file not shown.

BIN
fonts/klingon_font.zip Normal file

Binary file not shown.

BIN
fonts/tengwar.ttf Normal file

Binary file not shown.

Binary file not shown.

230
history.php Normal file
View File

@@ -0,0 +1,230 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>TOPISTO</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Bangers" rel="stylesheet" type="text/css">
<link href="css/topisto.css" rel="stylesheet" type="text/css">
<link href="css/fonts.css" rel="stylesheet" type="text/css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="js/lastblock.js" defer></script>
<script src="js/blockexplorer.js" defer></script>
<script>
// Init array
var cur_history_blocks = -1;
var history_blocks = [
'WHALE201810',
'BLOCK21E800',
'HURRICANE_1',
'SEGWIT',
'SEGWIT_LOCK',
'BCC',
'BIP_91_LOCK',
'HALVING_2',
'WHALE201311',
'HALVING_1',
'PIZZA',
'TOPISTO',
'LEET',
'LUCIFER',
'THE_ANSWER',
'GENESIS'
];
var height_blocks = {
'GENESIS' : 0,
'THE_ANSWER' : 42,
'LUCIFER' : 666,
'LEET' : 1337,
'TOPISTO' : 5637,
'PIZZA' : 57035,
'HALVING_1' : 210000,
'HALVING_2' : 420000,
'BIP_91_LOCK' : 477120,
'BCC' : 478559,
'SEGWIT_LOCK' : 479808,
'WHALE201311' : 270953,
'BLOCK21E800' : 528249,
'WHALE201810' : 545911,
'HURRICANE_1' : 506734,
'SEGWIT' : 481823
};
function ajouterPreviousHistoryBlock()
{
// Bloquer la navigation pendant le calcul
if (!flag_nav) return false;
flag_nav = false;
// Ajouter un div
cur_history_blocks += 1;
curblocname=history_blocks[cur_history_blocks];
console.log(curblocname);
console.log(height_blocks[curblocname]);
addDivForBlock(height_blocks[curblocname]);
// Mettre les infos du
block_hash = '?block_hash='+liste_blocks[history_blocks[cur_history_blocks]];
$.getJSON('data/getBlockInfo.php'+block_hash, function( data ) {
addInfoForBlock(data);
});
}
$(document).ready(function(){
// tooltips activation
$('[data-toggle="tooltip"]').tooltip();
// Add smooth scrolling to all links in navbar + footer link
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
$(window).scroll(function() {
$(".slideanim").each(function(){
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
ajouterPreviousHistoryBlock();
$(this).addClass("slide");
}
});
});
});
function changeMethode(la_methode)
{
cur_height = [];
cur_methode=la_methode;
return initBlockExplorer(null);
}
</script>
</head>
<body id="myPage" data-spy="scroll" data-target=".navbar" data-offset="60">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="..">
<img id="logo_topisto" src="images/topisto_vert.png" style="border-radius:6px;display:inline-block;visibility:block;height:72px;;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)">
<span style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 60px;text-shadow: 2px 2px #ffffff">TOPISTO</span>
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li><a href="#explorer">Full Explorer</a></li>
</ul>
</div>
</div>
</nav>
<div id="explorer" class="container-fluid bg-grey" style="padding-bottom:10px">
<div class="row">
<div class="col-sm-12 text-right">
Scroll down to see the previous blocks<br>
Méthode de dessin <select onchange="changeMethode(this.value);">
<option value="hasard">hasard</option>
<option value="circle">circle</option>
<option value="circle_spline">circle_spline</option>
<option value="linegradient">linegradient</option>
<option value="mondrian">mondrian</option>
<option value="splinelineblackalpha">splinelineblackalpha</option>
<option value="treemap2">treemap2</option>
<option value="circle_line">circle_line</option>
<option value="circles_spline">circles_spline</option>
<option value="linehashed">linehashed/option>
<option value="peigne">peigne</option>
<option value="splinelinegradient">splinelinegradient</option>
<option value="veraMolnar">veraMolnar</option>
<option value="circles">circles</option>
<option value="line">line</option>
<option value="linehashedtx">linehashedtx</option>
<option value="peignealpha">peignealpha</option>
<option value="splinelineblack">splinelineblack</option>
<option value="splinelinegradientalpha">splinelinegradientalpha</option>
</select>
</div>
</div>
</div>
<div id="blockchain"></div>
<div id="contact" class="container-fluid bg-grey">
<h4 class="text-center">
<a href="#contact" title="To Top">
<span class="glyphicon glyphicon-chevron-down"></span>
</a>
PREVIOUS BLOCK
<a href="#contact" title="To Top">
<span class="glyphicon glyphicon-chevron-down"></span>
</a>
</h4>
<div class="row slideanim">
<div class="col-sm-5">
<p>Contact me</p>
<p><span class="glyphicon glyphicon-map-marker"></span> Shambala</p>
<p><span class="glyphicon glyphicon-globe"></span> Employer : Mutiny</p>
<p><span class="glyphicon glyphicon-phone"></span> +33 4 8 15 16 23 42</p>
<p>
<span class="glyphicon glyphicon-envelope"></span>
<!--Place the code below where you want the link to be displayed-->
<span id="obf"><script>document.getElementById("obf").innerHTML="<n uers=\"znvygb:nyoreg.frnaquvyf@gbcvfgb.arg?fhowrpg=pbagnpg\" gnetrg=\"_oynax\">nyoreg.frnaquvyf@gbcvfgb.arg</n>".replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});</script>
<noscript><span style="unicode-bidi:bidi-override;direction:rtl;">ten.otsipot@slihdnaes.trebla</span></noscript></span>
</p>
</div>
<div class="col-sm-5">
bookmarks : <br>
<a href="http://inconvergent.net/" target="_blank">Inconvergent</a><br>
<a href="http://www.datasketch.es/" target="_blank">Data Sketches</a><br>
<a href="https://bit101.github.io/lab/dailies/170310.html" target="_blank">bit101-github</a><br>
<a href="http://www.imdb.com/title/tt1508021/" target="_blank">being captain zero</a><br>
</div>
<div class="col-sm-2">
PGP : <br>
<a href="page.php?id=00000000"><img src="articles/00000000/public_key_qrcode.png" width="100%; height: auto"></img></a>
</div>
</div>
</div>
<footer class="container-fluid bg-grey text-center">
<a href="#myPage" title="To Top">
<span class="glyphicon glyphicon-chevron-up"></span>
</a>
<p>Bootstrap Theme Made By <a href="https://www.w3schools.com" title="Visit w3schools">www.w3schools.com</a></p>
</footer>
</body>
</html>

246
home.php Normal file
View File

@@ -0,0 +1,246 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>TOPISTO</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Bangers" rel="stylesheet" type="text/css">
<link href="css/topisto.css" rel="stylesheet" type="text/css">
<link href="css/fonts.css" rel="stylesheet" type="text/css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="js/console.js" defer></script>
<script src="js/lastblock.js" defer></script>
<script src="js/blockexplorer.js" defer></script>
<!--
-- From https://highlightjs.org
-->
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/atom-one-dark.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>
$(document).ready(function(){
// tooltips activation
$('[data-toggle="tooltip"]').tooltip();
// Add smooth scrolling to all links in navbar + footer link
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
$(window).scroll(function() {
$(".slideanim").each(function(){
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
$(this).addClass("slide");
}
if (winTop < 400) $('#logo_topisto').css('visibility', 'hidden');
else {
d = new Date();
$("#gargoyle").attr("src", "images/logo.php?ts="+d.getTime());
$('#logo_topisto').css('visibility', 'visible');
}
});
});
});
</script>
</head>
<body id="myPage" data-spy="scroll" data-target=".navbar" data-offset="60">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="..">
<img id="logo_topisto" src="images/topisto_vert.png" style="border-radius:6px;display:inline-block;visibility:hidden;height:72px;;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)">
<span style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 60px;text-shadow: 2px 2px #ffffff">TOPISTO</span>
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li><a href="#about">About</a></li>
<li><a href="#explorer">Explorer</a></li>
<li><a href="blog.php">Blog</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<div id="about" class="container-fluid">
<div class="row">
<div class="col-sm-8">
<br><br><br>
<h4>This site is a hobby.<br>It's also a testing place where i can do <a href="#blog">things</a> that are impossible at work.</h4>
<p class="text-justify">I like <b>surfing</b> and sailing on the ocean. But during longs winter nights, computing is fun. I'm interested into <b>cryptocurrencies</b>, computationnal art, datavisualisation. I know that <b>42</b> is the answer to <b>the Life, Universe and Everything Else</b>. As <b>Eto Demerzel</b> said to me, the <b>Seldon's Plan</b> will save the Galaxy. My favorites books are the <b>House of leaves</b>, the <b>Necronomicron</b> and the <b>DarkHold</b>. I also know that <b>great power comes with great responsibility</b>. I'm still in <b>the search of Captain Zero</b>, because <b>the Truth is out there</b>.</p>
</div>
<div class="col-sm-4">
<img id="gargoyle" src="images/logo.php" alt="avatar dragon gargoyle" width="100%; height: auto"></img>
</div>
</div>
</div>
<script>
var lastBlockTime = null;
function changeExploreBlock()
{
$('#img_explorer').attr('src', 'images/loading.gif');
block_name = $('#blockSelector').val();
block_url = 'data/getBlockInfo.php';
if (block_name != 'LAST') block_url += '?block_hash='+blockchainExplorer.getblocHashFromName(block_name);
$.getJSON(block_url, function( data ) {
changeExploreBlockDrawing(data);
});
}
function changeExploreBlockDrawing(le_block)
{
var downloadingImage = new Image();
downloadingImage.onload = function(){
$('#img_explorer').attr('src', this.src);
};
downloadingImage.src = 'images/block_image.php?methode=hasard&hash='+le_block.hash;
lastBlockTime = le_block.time;
topistoConsole.log('Time last block : '+lastBlockTime);
compteurTemps();
}
function formatNumber(myNumber, digits)
{
return ('0' + myNumber).slice(-1*digits);
}
function getBlockDate(str_date)
{
return new Date(
str_date.slice(0,4),
str_date.slice(5,7)-1,
str_date.slice(8,10),
str_date.slice(11,13),
str_date.slice(14,16),
str_date.slice(17,19)
);
}
function compteurTemps()
{
if (lastBlockTime == null) return false;
var d1 = getBlockDate(lastBlockTime);
var d2 = new Date();
var msec = d2 - d1;
var yyyy = Math.floor(msec / 365 / 24 / 1000 / 60 / 60);
msec -= yyyy * 365 * 24 * 1000 * 60 * 60;
var jj = Math.floor(msec / 24 / 1000 / 60 / 60);
msec -= jj * 24 * 1000 * 60 * 60;
var hh = formatNumber(Math.floor(msec / 1000 / 60 / 60),2);
msec -= hh * 1000 * 60 * 60;
var mm = formatNumber(Math.floor(msec / 1000 / 60),2);
msec -= mm * 1000 * 60;
var ss = formatNumber(Math.floor(msec / 1000),2);
msec -= ss * 1000;
var libel = 'Elapsed Time since that block : ';
if (yyyy > 0) libel += yyyy+' year(s) ';
if (jj > 0) libel += jj+' day(s) ';
if (hh > 0) libel += hh+' hour(s) ';
if (mm > 0) libel += mm+ ' min ';
libel += ss+' s';
$('#showElapsedTime').html(libel);
return true;
}
$(document).ready(function(){
blockchainListener.addBlockHook(changeExploreBlockDrawing);
setInterval(compteurTemps, 1000);
});
</script>
<div id="explorer" class="container-fluid bg-grey" style="padding-top:10px">
<div class="row">
<div class="col-sm-12">&nbsp;</div>
</div>
</div>
<div class="container-fluid bg-grey" style="padding-top:0px;padding-bottom:10px">
<div class="row">
<div class="col-sm-4">
<br><img id="img_explorer" src="images/loading.gif" width="100%; height: auto">
</div>
<div class="col-sm-8">
<br>
<h2>Explore the Bitcoin's Blockchain</h2>
<h4>This is a drawing of the <select id="blockSelector" onchange="javascript:changeExploreBlock()"><option selected value="LAST">LAST</option></select> block of the Bitcoin's Blockchain.</h4>
<div id="showElapsedTime">&nbsp;</div><br><a href="explorer.php">Click here to see the other blocks</a>
</div>
</div>
</div>
<div id="contact" class="container-fluid bg-grey">
<h4 class="text-center">CONTACT</h4>
<div class="row slideanim">
<div class="col-sm-5">
<p>Contact me</p>
<p><span class="glyphicon glyphicon-map-marker"></span> Shambala</p>
<p><span class="glyphicon glyphicon-globe"></span> Employer : Mutiny</p>
<p><span class="glyphicon glyphicon-phone"></span> +33 4 8 15 16 23 42</p>
<p>
<span class="glyphicon glyphicon-envelope"></span>
<!--Place the code below where you want the link to be displayed-->
<span id="obf"><script>document.getElementById("obf").innerHTML="<n uers=\"znvygb:nyoreg.frnaquvyf@gbcvfgb.arg?fhowrpg=pbagnpg\" gnetrg=\"_oynax\">nyoreg.frnaquvyf@gbcvfgb.arg</n>".replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});</script>
<noscript><span style="unicode-bidi:bidi-override;direction:rtl;">ten.otsipot@slihdnaes.trebla</span></noscript></span>
</p>
</div>
<div class="col-sm-5">
bookmarks : <br>
<a href="http://inconvergent.net/" target="_blank">Inconvergent</a><br>
<a href="http://www.datasketch.es/" target="_blank">Data Sketches</a><br>
<a href="https://bit101.github.io/lab/dailies/170310.html" target="_blank">bit101-github</a><br>
<a href="http://www.imdb.com/title/tt1508021/" target="_blank">being captain zero</a><br>
</div>
<div class="col-sm-2">
PGP : <br>
<a href="page.php?id=00000000"><img src="articles/00000000/public_key_qrcode.png" width="100%; height: auto"></img></a>
</div>
</div>
</div>
<footer class="container-fluid bg-grey text-center">
<a href="#myPage" title="To Top">
<span class="glyphicon glyphicon-chevron-up"></span>
</a>
<p>Bootstrap Theme Made By <a href="https://www.w3schools.com" title="Visit w3schools">www.w3schools.com</a></p>
</footer>
</body>
</html>

View File

@@ -1,106 +0,0 @@
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-8">
<h2>A digital currency</h2>
<p>
Use cryptography.<br>
No "central bank".<br>
P2P network.<br>
</p>
</div>
<div class="col-sm-4 align-middle">
<img src="images/bitcoin.jpg" width="100%; height: auto"></img>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-sm-4 align-middle">
<img src="images/wallet.png" height="300px"></img>
</div>
<div class="col-sm-8">
<h2>WALLET</h2>
<p>
Use cryptography.<br>
No "central bank".<br>
P2P network.<br>
</p>
</div>
</div>
</div>
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-8">
<h2>Transaction</h2>
<p>
When Bob is sending 42 <span class="glyphicon glyphicon-bitcoin"></span> to Alice, the bitcoin protocol is creating a transaction.<br>
A transaction is the balance between his Inputs and his Outputs.
<ul>
<li>First the network needs to be sure that Bob has got enough <span class="glyphicon glyphicon-bitcoin"></span> in his wallet.<br>So Bob will include a list of transactions that he has received before.<br>This is the inputs of the transactions.<br>For example, previous transaction's amount are 10, 25 and another 10, so total inputs are 45 <span class="glyphicon glyphicon-bitcoin"></span></li>
<li>As the input's sum is superior to the amount of the transaction, an ouput is added.<br>This output is the change to Bob.<br>In the example, this 3 <span class="glyphicon glyphicon-bitcoin"></span></li>
<li>Fees are took by the network to process the transaction.<br>Let say it will take 0.5<span class="glyphicon glyphicon-bitcoin"></span>.<br>This is another ouput</li>
<li>So Alice will get only a part of the transaction's amount.<br>this the last output, 41.5<span class="glyphicon glyphicon-bitcoin"></span></li>
</ul>
So the transaction is a made with :
<ul>
<li>Inputs : a list of previous transactions that bob has received</li>
<li>Outputs : a list of amounts to send to Alice, Bob, and fees</li>
<li>A timestamp</li>
</ul>
Then the wallet will broadcast the transaction on the network.<br>
It will be sent to the area called "mempool".<br>
Nodes of the network will validate the transaction by verfying the Inputs and the Ouputs.<br>
A hash of the transaction is computed.<br>
So the transaction is sealed.
</p>
</div>
<div class="col-sm-4 align-middle">
<img src="images/bob_to_alice.gif" width="100%; height: auto"></img>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-sm-4">
<img src="images/tx2block.gif" width="100%; height: auto"></img>
</div>
<div class="col-sm-8">
<h2>Block</h2>
<p>
Then the bitcoin protocol is grouping validated transactions in blocks.<br>
So a block is an array of transactions.<br>
A block is made with :
<ul>
<li>An array of transactions.<br>
That's what my script is drawing.<br>
Running the transactions array, it is computing the sum of each outputs of each transaction.<br>
Then, it draws a rectangle for each sum.<br>
</li>
<li>A "proof of work".<br>The miner is computing a special hash that depends on the array of transaction and that will answer to a constraint.<br>This hash is very difficult to compute. In fact it is not really computed, the miner must test every value until he find the solution.<br></li>
<li>That why the network will give him a reward.<br>This is a special transaction that has no inputs.</li>
</ul>
</p>
</div>
</div>
</div>
<div class="container-fluid bg-grey">
<div class="row">
<div class="col-sm-8">
<h2>Blockchain</h2>
<p>
Each block has a hash and a reference to the ihash of the previous block.<br>
So blocks are chained together.<br>
</p>
</div>
<div class="col-sm-4">
<img src="/images/loading.gif" width="100%; height: auto"></img>
</div>
</div>
</div>

View File

@@ -26,20 +26,20 @@ $methode='hasard';
$mode=9999;
// ---
// --- Le cas échéant, on cherche block passé en argument
// --- Le cas échéant, on cherche le block passé en argument
// ---
if (isset($_REQUEST['hash'])) $block_hash = $_REQUEST['hash'];
if (isset($_REQUEST['methode'])) $methode = $_REQUEST['methode'];
if (isset($_REQUEST['mode'])) $mode = intval($_REQUEST['mode']);
$img = null;
$str_mode = '';
if ($mode != 9999) $str_mode = '-'.$mode;
// ---
// --- Le cas général : on trouve le fichier image demandé
// ---
$imagefilename = DATA_PATH.'/'.$methode.'/'.$block_hash;
if ($mode != 9999) $imagefilename .= '-'.$mode;
$imagefilename .= '.png';
$imagefilename = DATA_PATH.'/'.$methode.'/'.$block_hash.$str_mode.'.png';
if (file_exists($imagefilename)) $img = imagecreatefrompng($imagefilename);
// ---

236
images/block_image_1.php Normal file
View File

@@ -0,0 +1,236 @@
<?php
function tri_filemtime( $a, $b ) { return filemtime($a) - filemtime($b); }
// ---
// --- La config globale
// ---
chdir('/opt/TOPISTO/apps');
require_once '/opt/TOPISTO/apps/global/inc/config.php';
// ---
// --- External dependances
// ---
require TOPISTO_PATH.'/ressources/vendor/autoload.php';
// ---
// --- Internal dependances
// ---
require_once APP_PATH.'/blockchain/inc/block.php';
// ---
// --- Par défaut on cherche le dernier block
// ---
$block_hash = '*';
$methode='hasard';
$mode=9999;
// ---
// --- Le cas échéant, on cherche block passé en argument
// ---
if (isset($_REQUEST['hash'])) $block_hash = $_REQUEST['hash'];
if (isset($_REQUEST['methode'])) $methode = $_REQUEST['methode'];
if (isset($_REQUEST['mode'])) $mode = intval($_REQUEST['mode']);
$img = null;
// ---
// --- Le cas général : on trouve le fichier image demandé
// ---
$imagefilename = DATA_PATH.'/'.$methode.'/'.$block_hash;
if ($mode != 9999) $imagefilename .= '-'.$mode;
$imagefilename .= '.png';
echo $imagefilename.PHP_EOL;
if (file_exists($imagefilename)) die('OK');
else die('PROBLEM');
if (file_exists($imagefilename)) $img = imagecreatefrompng($imagefilename);
// ---
// --- "strict" est un flag qui indique que l'on veut précisément
// --- ce que les paramètres demandent
// ---
if (($img==null)&&(!isset($_REQUEST['strict'])))
{
//
// On n'a pas passé de HASH
//
if (($img==null)&&(!isset($_REQUEST['hash'])))
{
//
// On prend le dernier connu pour la méthode et le mode
//
$myarray = glob(DATA_PATH.'/'.$methode.'/*-'.$mode.'.png');
if (isset($myarray[0]))
{
usort( $myarray, tri_filemtime );
$img = imagecreatefrompng($myarray[0]);
}
//
// On prend le dernier connu pour la méthode tout mode confondu
//
if ($img==null)
{
$myarray = glob(DATA_PATH.'/'.$methode.'/*.png');
if (isset($myarray[0]))
{
usort( $myarray, tri_filemtime );
$img = imagecreatefrompng($myarray[0]);
}
}
}
//
// On a passé un HASH
//
if (($img==null)&&(isset($_REQUEST['hash'])))
{
//
// On cherche le bon HASH et la bonne méthode
//
$imagefilename = DATA_PATH.'/'.$methode.'/'.$block_hash.'.png';
if (($img==null)&&(file_exists($imagefilename)))
{
$img = imagecreatefrompng($imagefilename);
}
//
// En fait on s'en fiche de la méthode tant qu'on a le bon HASH
//
$imagefilename = DATA_PATH.'/hasard/'.$block_hash.'.png';
if (($img==null)&&(file_exists($imagefilename)))
{
$img = imagecreatefrompng($imagefilename);
}
}
}
//
// On n'a rien trouvé, donc on dessine ce qui est demandé
//
if ($img==null)
{
if ($mode == 9999) $mode = 0;
if ($block_hash == '*') $block_hash = blockchain::getLastCacheBlockHash();
if ($methode == 'hasard') $methode = 'treemap';
$imagefilename = DATA_PATH.'/'.$methode.'/'.$block_hash.'.png';
$the_block = blockchain::getBlockWithHash($block_hash);
if ($the_block === FALSE) die();
$the_name = blockchain::hash2SpecialName($the_block->hash);
if ($the_name == $the_block->hash) $the_name ='';
$bandeau = 50;
$marge = 25;
$text_border = 20;
$width = GRAPH_WIDTH;
$height = GRAPH_HEIGHT;
// Pour que l'image simple ait les proportions que l'image full
$width = $marge + ($width*2) + (2*$text_border);
$height = $marge + ($height*2);
$img_w = $width;
$img_h = $height+(2*$bandeau);
$type=2;
if (count($the_block->tx)==1) $type=4;
// création d'une image plus haute pour inclure bandeaux haut et bas
$img = imagecreatetruecolor($img_w, $img_h);
$param0 = blockchain::DrawBlockHeaderFooter($the_block, $img, $bandeau);
$parametres = [];
$parametres['x'] = 0;
$parametres['y'] = $bandeau;
$parametres['width'] = $width;
$parametres['height'] = $height;
$parametres['methode'] = $mode;
$parametres['type'] = $type;
$parametres['transparent_color'] = $param0[0];
$parametres['background_color'] = $param0[1];
$parametres['font_color'] = $param0[2];
$parametres['fontname'] = $param0[3];
$parametres['font_RGB'] = $param0[4];
$parametres['background_RGB'] = $param0[5];
switch($methode)
{
case 'veraMolnar':
require_once APP_PATH.'/methode/veraMolnar/inc/treemap.php';
topisto_veraMolnar::DrawBlock($the_block, $img, $parametres);
break;
case 'treemapV2':
require_once APP_PATH.'/methode/treemapV2/inc/treemap.php';
topisto_treemap::DrawBlock($the_block, $img, $parametres);
break;
case 'treemap_fuzzy':
require_once APP_PATH.'/methode/treemap_fuzzy/inc/treemap.php';
topisto_treemap_fuzzy::DrawBlock($the_block, $img, 0, $bandeau, $width, $height, $mode, $type);
break;
case 'spline':
require_once APP_PATH.'/methode/spline/inc/splines.php';
topisto_spline::DefaultDrawBlock($the_block, $img, 0, $bandeau, $width, $height, $mode, $type);
break;
case 'spline_2':
require_once APP_PATH.'/methode/spline/inc/splines.php';
topisto_spline::DrawBlock($the_block, $img, 0, $bandeau, $width, $height, $mode, 200, $type);
break;
case 'treemap' :
default:
require_once APP_PATH.'/methode/treemap/inc/treemap.php';
topisto_treemap::DrawBlock($the_block, $img, 0, $bandeau, $width, $height, $mode, $type);
break;
}
// Les textes
/*
* INUTILE depuis que blockchain::DrawBlockHeaderFooter ajoute elle-même les textes
*
putenv('GDFONTPATH='.RESS_PATH.'/fonts/');
$font = 'DS-DIGIB.TTF';
$fontColor = imagecolorallocate($img, 227,227,153);
$the_texte = "Height : ".$the_block->height;
imagettftext($img,18, 0, 5, $bandeau-5, $fontColor, $font, $the_texte);
$the_texte = "Inputs : ".$the_block->topisto_inputs;
if ($type == 4) $the_texte = "Reward : ".$the_block->topisto_reward;
imagettftext($img,15, 0, 5, $bandeau+$height+18, $fontColor, $font, $the_texte);
if ($the_name == '') $the_name = date('Ymd H:m:s', $the_block->time);
$bbox = imagettfbbox(14, 0, $font, $the_name);
imagettftext($img, 14, 0, ($img_w-3)-($bbox[2]-$bbox[0]), ($bandeau-5), $fontColor, $font, $the_name);
*/
// Sauvegarder l'image et ajouter
// - un lien sur le mode
// - un lien dans le dossier "hasard"
$imagefilename2 = str_replace(".png","-$mode.png", $imagefilename);
imagepng($img,$imagefilename2);
if (!file_exists($imagefilename)) link($imagefilename2, $imagefilename);
$imagefilename2 = str_replace("methode/$methode/","methode/hasard/", $imagefilename);
if (!file_exists($imagefilename2)) link($imagefilename, $imagefilename2);
}
$seconds_to_cache = 7200;
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);
?>

View File

@@ -1,29 +1,62 @@
<?php
$alea=rand(0,100);
// valeur par défaut
$rank = -1;
// Surcharge par les arguments
extract($_REQUEST, EXTR_IF_EXISTS);
$logo='topisto_vert.png';
if ($alea > 30)
{
$files = glob('logo/medium/*/topisto_vert.png');
usort($files, function($a, $b) {
return filemtime($a) > filemtime($b);
});
shuffle($files);
$logo = $files[0];
}
$logo='topisto_vert_tr.png';
$block_image = @imagecreatefrompng($logo);
$width = imagesx($block_image);
$height = imagesy($block_image);
// create the destination/output image.
$img=imagecreatetruecolor( $width, $height );
// enable alpha blending on the destination image.
imagealphablending($img, false);
imagesavealpha($img,true);
// Allocate a transparent color and fill the new image with it.
// Without this the image will have a black background instead of being transparent.
//$transparent = imagecolorallocatealpha( $img, 255, 255, 255, 127 );
//imagefill( $img, 0, 0, $transparent );
// copy the thumbnail into the output image.
// imagecopyresampled($img,$block_image, 0, 0, 0, 0, $width, $height, $width, $height );
$files = glob('logo/tr/topisto_*.png');
usort($files, function($a, $b) {
return filemtime($a) > filemtime($b);
});
if ($rank < 0)
{
shuffle($files);
$rank = 0;
}
// Borner l'index aux valeurs du tableau
$rank = $rank % count($files);
$superpose = @imagecreatefrompng($files[$rank]);
imagecopyresampled($img,$superpose, 0, 0, 0, 0, $width, $height, imagesx($superpose), imagesy($superpose));
imagedestroy($superpose);
imagecopymerge($img, $block_image, 0, 0, 0, 0, $width, $height, 45);
// ---
// --- envoyer l'image au navigateur
// ---
header("Content-Type: image/png");
imagepng($block_image);
imagepng($img);
imagedestroy($img);
imagedestroy($block_image);
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,8 @@
convert \
topisto_vert.png \
-channel rgba \
-matte \
-fuzz 40% \
-fill "rgba(255,255,255,0.5)" \
-opaque "rgb(255,255,255)" \
semi_transparent.png

View File

@@ -0,0 +1,16 @@
#!/bin/bash
rm -f *.png
# monochrome
convert ../../topisto_vert.png -monochrome topisto_tmp1.png
composite -compose copy_opacity ../topisto_mask.png topisto_tmp1.png topisto_tmp2.png
rm -f topisto_tmp?.png
# grayscale
convert ../../topisto_vert.png -type Grayscale topisto_tmp1.png
composite -compose copy_opacity ../topisto_mask.png topisto_tmp1.png topisto_tmp2.png
convert topisto_tmp2.png -negate topisto_grayscale.png
rm -f topisto_tmp?.png
exit 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

8
images/logo/tr/gmic.sh Executable file
View File

@@ -0,0 +1,8 @@
toto=$1
gmic ../../topisto_vert_tr.png $@ -output topisto_tmp_$toto.png
convert topisto_tmp_$toto.png -fuzz 10% -transparent white topisto_tmp_2_$toto.png
composite -compose copy_opacity ../topisto_mask.png topisto_tmp_2_$toto.png topisto_$toto.png
rm -f topisto_tmp_$toto.png topisto_tmp_2_$toto.png

28
images/logo/tr/go.sh Executable file
View File

@@ -0,0 +1,28 @@
source gmic.sh fx_engrave 0.5,4,0,7.68,15.2,0,0,1,10,1,0,0,0,1,0 gui_merge_layers
source gmic.sh fx_bokeh 3,8,0,30,8,4,0.3,0.2,210,210,80,160,0.7,30,20,20,1,2,170,130,20,110,0.15,0
source gmic.sh fx_8bits 25,800,16,0
#source gmic.sh fire_edges 0.7,0.25,0.5,25,20
source gmic.sh fx_diffusiontensors 10,5,3,1,0.15,1,0,3,0
source gmic.sh feltpen fx_feltpen 300,50,1,0.1,20,5,0
source gmic.sh gtutor_fpaint 0.5,0.5,0,0,45,0.5,0.5,0.5,0
source gmic.sh fx_graphic_novelfxl 0,2,6,5,20,0,0.62,14,0,1,0.5,0.78,1.92,0,0,0,1,1,1,0.5,0.8,1.28
source gmic.sh fx_illustration_look 100,0,0,0,0
source gmic.sh fx_lylejk_painting 10,2,4,10,0
source gmic.sh fx_painting 5,2.5,1.5,50,1,0
source gmic.sh fx_posterize 150,30,1,6,0,0,1,0
source gmic.sh fx_quadtree 2,1024,1.05,0,2.33,0.68,0.39,1,0
source gmic.sh fx_vector_painting 9.37,0
source gmic.sh boxfitting ,
source gmic.sh cartoon 3,80,15
source gmic.sh cubism ,
source gmic.sh halftone ,
source gmic.sh blur 2 light_relief 0.3,4,0.1,0
source gmic.sh +sketchbw 1 reverse blur[-1] 3 blend[-2,-1] overlay
source gmic.sh mosaic ,
source gmic.sh linify 40
source gmic.sh polygonize 300,1%,0.1%,3%,3%
source gmic.sh poster_hope ,
source gmic.sh rodilius 12,10,300,10 normalize_local 10,6
source gmic.sh stained_glass 20%,0.1
source gmic.sh fx_shapes 1,16,10,2,5,106.8,2,0,0,1,0
source gmic.sh fx_shapeism 2,7,0.38,0,1,5,32,8,3,1,5,0.5,1,0,0,0,255

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

BIN
images/topisto_vert_tr.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
images/topisto_vert_tr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

202
index.php
View File

@@ -17,54 +17,66 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="js/console.js" defer></script>
<script src="js/lastblock.js" defer></script>
<script src="js/blockexplorer.js" defer></script>
<script>
$(document).ready(function(){
// Mask navigator scrollbar
// Doesn't work : can't scroll anymore
//$("body").css('overflow', 'hidden');
// tooltips activation
$('[data-toggle="tooltip"]').tooltip();
// Add smooth scrolling to all links in navbar + footer link
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
$('#myNavbar').on('show.bs.collapse', function () {
$('#logo_topisto').css({'height' : '30px','width' : '30px'});
$('#titre_topisto').css({'font-size' : '30px'});
});
$('#myNavbar').on('hidden.bs.collapse', function () {
$('#logo_topisto').css({'height' : '72px','width' : '72px'});
$('#titre_topisto').css({'font-size' : '60px'});
});
$(window).scroll(function() {
if (isInViewport(document.querySelector('footer')))
{
blockchainExplorer.addBottomBlock();
console.log("Scroll to footer detected !");
}
/*
$(".slideanim").each(function(){
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
blockchainExplorer.addBottomBlock();
$(this).addClass("slide");
}
if (winTop < 400) $('#logo_topisto').css('visibility', 'hidden');
else {
d = new Date();
$("#gargoyle").attr("src", "images/logo.php?ts="+d.getTime());
$('#logo_topisto').css('visibility', 'visible');
}
});
});
*/
});
blockchainExplorer.init(1);
});
var isInViewport = function (elem) {
var bounding = elem.getBoundingClientRect();
return (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};
function showInfos(element)
{
var flag = 2*parseInt($('#mode_selector').val());
$('#blockchain').html('');
if ($('#mode_checkbox').is(":checked")) flag += 1;
blockchainExplorer.init(flag);
}
</script>
</head>
@@ -78,141 +90,41 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="..">
<img id="logo_topisto" src="images/topisto_vert.png" style="border-radius:6px;display:inline-block;visibility:hidden;height:72px;;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)">
<span style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 60px;text-shadow: 2px 2px #ffffff">TOPISTO</span>
<a class="navbar-brand" href="index.php">
<img id="logo_topisto" src="images/topisto_vert.png" style="border-radius:6px;display:inline-block;height:72px;;box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)">
<span id="titre_topisto" style="vertical-align:text-bottom;display:inline-block;color:black;font-family: Bangers, sans-serif;font-size: 60px;text-shadow: 2px 2px #ffffff">TOPISTO</span>
</a>
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav navbar-right">
<li><a href="#about">About</a></li>
<li><a href="about.php">About</a></li>
<li><a href="#explorer">Explorer</a></li>
<li><a href="#blog">Blog</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="blog.php">Blog</a></li>
</ul>
</div>
</div>
</nav>
<div id="about" class="container-fluid">
<div id="explorer" class="container-fluid bg-grey" style="padding-bottom:10px">
<div class="row">
<div class="col-sm-8">
<br><br><br>
<h4>This site is a hobby.<br>It's also a testing place where i can do <a href="#blog">things</a> that are impossible at work.</h4>
<p class="text-justify">I like <b>surfing</b> and sailing on the ocean. But during longs winter nights, computing is fun. I'm interesting into <b>cryptocurrencies</b>, computationnal art, datavisualisation. I know that <b>42</b> is the answer to <b>the Life, Universe and Everything Else</b>. As <b>Eto Demerzel</b> said to me, the <b>Seldon's Plan</b> will save the Galaxy. My favorites books are the <b>House of leaves</b>, the <b>Necronomicron</b> and the <b>DarkHold</b>. I also know that <b>great power comes with great responsibility</b>. I'm still in <b>the search of Captain Zero</b>, because <b>the Truth is out there</b>.</p>
</div>
<div class="col-sm-4">
<img id="gargoyle" src="images/logo.php" alt="avatar dragon gargoyle" width="100%; height: auto"></img>
</div>
</div>
</div>
<div id="explorer" class="container-fluid bg-grey" style="padding-top:10px">
<div class="row">
<div class="col-sm-12">&nbsp;</div>
</div>
</div>
<div class="container-fluid bg-grey" style="padding-top:0px;padding-bottom:10px">
<div class="row">
<div class="col-sm-4">
<span class="align-middle">My Blockchain Explorer</span>
</div>
<div class="col-sm-8 text-right">
<a href="#navigation" onclick="javascript:initBlockchain('GENESIS');" class="btn btn-success btn-lg btn-topisto" data-toggle="tooltip" title="GENESIS">
<span class="glyphicon glyphicon-fast-backward"></span>
</a>
<a href="#navigation" onclick="javascript:gotoBlock('PREVIOUS');" class="btn btn-info btn-lg btn-topisto" data-toggle="tooltip" title="PREVIOUS">
<span class="glyphicon glyphicon-backward"></span>
</a>
<select style="display:none" id="blockSelector" onchange="javascript:blockSelectorChange()" data-width="100%">
<option value="LAST">LAST</option>
<div class="col-sm-12 text-right">
<br>
<select id="mode_selector" onchange="showInfos(this)">
<option value=0>A BTC blockchain explorer</option>
<option value=1>My special Blocks list</option>
</select>
<a id="btn-forward" href="#navigation" onclick="javascript:gotoBlock('NEXT');" class="btn btn-secondary btn-lg btn-topisto" data-toggle="tooltip" title="NEXT">
<span class="glyphicon glyphicon-forward"></span>
</a>
<a href="#navigation" id="fast_forward_btn" onclick="javascript:blockSelectorChange()" class="btn btn-secondary btn-lg btn-topisto" data-toggle="tooltip" title="LAST">
<span class="glyphicon glyphicon-fast-forward"></span>
</a>
<br>Scroll down to see the previous blocks<br>
<label>show infos&nbsp;</label><input id="mode_checkbox" type="checkbox" onchange="showInfos(this)" checked>
</div>
</div>
</div>
<div id="blockchain"></div>
<div id="blog" class="container-fluid bg-grey" style="padding-top:50px;align:right">
<div class="row">
<div class="col-sm-8">&nbsp;</div>
<div class="col-sm-4">
<span style="color:black;font-family: Bangers, sans-serif;font-size: 35px;">Blog</span>
</div>
</div>
</div>
<?php
$odd_even = 0;
$liste = '';
foreach (glob("articles/*/header.html") as $filename) {
$article = basename(dirname($filename));
$odd_even = 1 - $odd_even;
$header = file_get_contents($filename);
if ($odd_even == 0) $header = str_replace('bg-grey','bg-grey-odd',$header);
else $header = str_replace('bg-grey','bg-grey-even',$header);
$header = str_replace('ARTICLE',$article,$header);
if (!file_exists('articles/'.$article.'/content.html'))
{
$header = str_replace('####BUTTON####','',$header);
} else {
echo '<script>';
echo '$(document).ready(function(){';
echo ' $("#'.$article.'_button").on("click", function(event) {';
echo ' window.location="page.php?id='.$article.'"';
echo ' })';
echo '})';
echo '</script>';
$header = str_replace('####BUTTON####','<button id="'.$article.'_button" class="btn btn-default btn-lg float-left">See more</button>',$header);
}
$liste = $header.PHP_EOL.$liste;
}
echo $liste;
?>
<div id="contact" class="container-fluid bg-grey">
<h4 class="text-center">CONTACT</h4>
<div class="row slideanim">
<div class="col-sm-5">
<p>Contact me</p>
<p><span class="glyphicon glyphicon-map-marker"></span> Shambala</p>
<p><span class="glyphicon glyphicon-globe"></span> Employer : Mutiny</p>
<p><span class="glyphicon glyphicon-phone"></span> +00 666 666 666</p>
<p>
<span class="glyphicon glyphicon-envelope"></span>
<!--Place the code below where you want the link to be displayed-->
<span id="obf"><script>document.getElementById("obf").innerHTML="<n uers=\"znvygb:nyoreg.frnaquvyf@gbcvfgb.arg?fhowrpg=pbagnpg\" gnetrg=\"_oynax\">nyoreg.frnaquvyf@gbcvfgb.arg</n>".replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});</script>
<noscript><span style="unicode-bidi:bidi-override;direction:rtl;">ten.otsipot@slihdnaes.trebla</span></noscript></span>
</p>
</div>
<div class="col-sm-5">
bookmarks : <br>
<a href="http://inconvergent.net/" target="_blank">Inconvergent</a><br>
<a href="http://www.datasketch.es/" target="_blank">Data Sketches</a><br>
<a href="https://bit101.github.io/lab/dailies/170310.html" target="_blank">bit101-github</a><br>
<a href="http://www.imdb.com/title/tt1508021/" target="_blank">being captain zero</a><br>
</div>
<div class="col-sm-2">
PGP : <br>
<a href="page.php?id=00000000"><img src="articles/00000000/public_key_qrcode.png" width="100%; height: auto"></img></a>
</div>
</div>
</div>
<footer class="container-fluid bg-grey text-center">
<footer class="container-fluid bg-grey text-center slideanim">
<a href="#myPage" title="To Top">
<span class="glyphicon glyphicon-chevron-up"></span>
</a>
<p>Bootstrap Theme Made By <a href="https://www.w3schools.com" title="Visit w3schools">www.w3schools.com</a></p>
</footer>
</body>
</html>

View File

@@ -1,245 +1,386 @@
// Init array
var liste_blocks = {
'WHALE201810' : '0000000000000000000f9f2dadfb8f312572183272802cbfcc4ff95b4ee6777d',
'BLOCK21E800' : '00000000000000000021e800c1e8df51b22c1588e5a624bea17e9faa34b2dc4a',
'HURRICANE_1' : '0000000000000000000fe6d521a187a5523d5cef6f6c178923ff82ffe5a0f372',
'SEGWIT' : '000000000000000000cbeff0b533f8e1189cf09dfbebf57a8ebe349362811b80',
'SEGWIT_LOCK' : '0000000000000000012e6060980c6475a9a8e62a1bf44b76c5d51f707d54522c',
'BCC' : '00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148',
'BIP_91_LOCK' : '0000000000000000015411ca4b35f7b48ecab015b14de5627b647e262ba0ec40',
'HALVING_2' : '000000000000000002cce816c0ab2c5c269cb081896b7dcb34b8422d6b74ffa1',
'HALVING_1' : '000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e',
'PIZZA' : '00000000006de085dadb3ec413ef074022fe781121b467e98960280dd246bb00',
'TOPISTO' : '000000000a73e64735a2b75c97ea674950a9018da1420d01328a918c9ff9852c',
'LEET' : '000000008bf44a528a09d203203a6a97c165cf53a92ecc27aed0b49b86a19564',
'LUCIFER' : '00000000fc5b3c76f27f810ee775e480ae7fd604fd196b2d8da4257fcd39f4f9',
'THE_ANSWER' : '00000000314e90489514c787d615cea50003af2023796ccdd085b6bcc1fa28f5',
'GENESIS' : '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
};
blockchainExplorer = function(){
var flag_nav = true;
var classes = ['bg-grey-even','bg-grey-odd'];
var cur_class = 0;
var cur_height = [];
// Init array
var _known_blocks = null;
var _liste_blocks = null;
var _classes = ['bg-grey-even','bg-grey-odd'];
var _cur_class = 0;
var _cur_methode = 'hasard';
var _mode = 1;
function precisionRound(number) {
function _precisionRound(number) {
var precision = 4;
var factor = Math.pow(10, precision);
return Math.round((number/100000000) * factor) / factor;
}
}
function addInfoForBlock(block)
function _getblockNameFromHash(hash)
{
var retour = '';
if (_known_blocks != null)
_known_blocks.forEach(function(item){
if (hash == item.hash) retour = item.name;
});
return retour;
}
function _getblocHashFromName(name)
{
var retour = '';
if (_known_blocks != null)
_known_blocks.forEach(function(item){
if (name == item.name) retour = item.hash;
});
return retour;
}
function _convertUTCDateToLocalDate(date) {
var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);
var offset = date.getTimezoneOffset() / 60;
var hours = date.getHours();
newDate.setHours(hours - offset);
return newDate;
}
function _formatDate(unixtime)
{
var ladate = new Date(unixtime*1000);
var ladateStr = "";
ladate = _convertUTCDateToLocalDate(ladate);
ladateStr += ladate.getFullYear();
ladateStr += "/" +("00"+(ladate.getMonth()+1)).slice(-2);
ladateStr += "/" +("00" + ladate.getDate()).slice(-2);
ladateStr += " " +("00" + ladate.getHours()).slice(-2);
ladateStr += ":" +("00" + ladate.getMinutes()).slice(-2);
ladateStr += ":" +("00" + ladate.getSeconds()).slice(-2);
return ladateStr;
}
function _addInfoForBlock(block)
{
var contenu = '';
var downloadingImage = new Image();
var div_label = block.height;
_cur_class = 1 - _cur_class;
blockName = _getblockNameFromHash(block.hash);
// if (blockName != '') blockName = ' ( '+blockName+' )';
if (_mode > 1)
if (block.hash == _liste_blocks['TOP'])
{
div_label = 'LAST';
if (blockName == '') blockName = 'LAST';
}
contenu += ' <div style="height:220px;width:100%;display:block;position:absolute">';
if ((_mode % 2) != 0)
{
var height = '300px';
var contenu = '';
var downloadingImage = new Image();
cur_height.push(block.height);
cur_class = 1 - cur_class;
contenu += ' <h2> <span style="font-size:12px">block</span> '+block.height+'</h2>';
contenu += ' <table width="100%">';
contenu += '<div style="color:black;opacity:1.0;margin-right:30px">';
// contenu += ' <h2> <span style="font-size:12px">block</span> '+block.height+blockName+'</h2>';
//contenu += '<span style="font-size:4px">&nbsp;</span>';
contenu += ' <table width="100%" style="margin-top:3px">';
//contenu += ' <tr><td>hash</td><td align="right"><b>'+block.hash+'</b></td></tr>';
//contenu += ' <tr><td>index</td><td align="right"><b>'+block.block_index+'</b></td></tr>';
contenu += ' <tr><td>timestamp</td><td align="right"><b>'+block.time+'</b></td></tr>';
if (_mode == 3 ) contenu += ' <tr><td>name</td><td align="right"><b>'+blockName+'</b></td></tr>';
contenu += ' <tr><td>height</td><td align="right"><b>'+block.height+'</b></td></tr>';
contenu += ' <tr><td>timestamp</td><td align="right"><b>'+_formatDate(block.time)+'</b></td></tr>';
contenu += ' <tr><td>nonce</td><td align="right"><b>'+block.nonce+'</b></td></tr>';
contenu += ' <tr><td>nb tx</td><td align="right"><b>'+block.n_tx+'</b></td></tr>';
contenu += ' <tr><td>outputs</td><td align="right"><b>'+precisionRound(block.topisto_outputs).toFixed(4)+'</b></td></tr>';
contenu += ' <tr><td>inputs</td><td align="right"><b>'+precisionRound(block.topisto_inputs).toFixed(4)+'</b></td></tr>';
contenu += ' <tr><td>fees</td><td align="right"><b>'+precisionRound(block.topisto_fees).toFixed(4)+'</b></td></tr>';
contenu += ' <tr><td>reward</td><td align="right"><b>'+precisionRound(block.topisto_reward).toFixed(4)+'</b></td></tr>';
contenu += ' <tr><td>outputs</td><td align="right"><b>'+_precisionRound(block.topisto_outputs).toFixed(4)+'</b></td></tr>';
contenu += ' <tr><td>inputs</td><td align="right"><b>'+_precisionRound(block.topisto_inputs).toFixed(4)+'</b></td></tr>';
if (_mode != 3 ) contenu += ' <tr><td>fees</td><td align="right"><b>'+_precisionRound(block.topisto_fees).toFixed(4)+'</b></td></tr>';
contenu += ' <tr><td>reward</td><td align="right"><b>'+_precisionRound(block.topisto_reward).toFixed(4)+'</b></td></tr>';
contenu += ' </table>';
$('#info_'+block.height).html(contenu);
downloadingImage.onload = function(){
$('#img_'+block.height).attr('src', this.src);
//$('#img_'+block.height).attr('height', height);
//$('#img_'+block.height).attr('width','auto');
flag_nav = true;
};
downloadingImage.src = 'images/block_image.php?methode=hasard&hash='+block.hash;
return true;
}
function addDivForBlock(block_height)
{
var contenu = '';
contenu += '<div id="block_'+block_height+'" class="container-fluid '+classes[cur_class]+'">';
contenu += ' <div class="row">';
contenu += ' <div class="col-sm-8" id="info_'+block_height+'">';
contenu += ' <h2>COMPUTING ...</h2>';
contenu += ' </div>';
contenu += ' <div class="col-sm-4 text-right">';
contenu += ' <div width="100%" class="text-center">';
contenu += ' <img id="img_'+block_height+'" src="images/loading.gif" class="img-responsive"></img>';
contenu += ' </div>';
contenu += ' </div>';
contenu += ' </div>';
contenu += '</div>';
$('#blockchain').append(contenu);
return true;
}
contenu += ' </div>';
function addDivForVoid()
$('#info_'+div_label).html(contenu);
contenu = '';
contenu += '<div id="img_'+block.height+'" style="';
contenu += 'height:220px;';
contenu += 'content: "";';
contenu += 'top: 0;';
contenu += 'left: 0;';
contenu += 'bottom: 0;';
contenu += 'right: 0;';
contenu += 'position: relative;';
contenu += 'z-index: -1; ';
contenu += '"></div>'
$('#info_'+div_label).append(contenu);
downloadingImage.onload = function(){
// $('#img_'+block.height).attr('src', this.src);
/*
$('#img_'+block.height).attr('height', _height);
$('#img_'+block.height).attr('width','auto');
*/
var div0 = document.getElementById('img_'+block.height);
div0.style.backgroundImage = "url(" + this.src + ")";
div0.style.backgroundRepeat = "no-repeat";
div0.style.backgroundPosition = "center";
div0.style.backgroundSize = "auto 100%";
if ((_mode %2) == 1) div0.style.opacity=0.3;
flag_nav = true;
};
downloadingImage.src = 'images/block_image.php?methode='+_cur_methode+'&hash='+block.hash;
return true;
}
function _addDiv(block_height)
{
var contenu = '';
contenu += '<div id="block_'+block_height+'" class="container-fluid '+_classes[_cur_class]+'">';
contenu += ' <div class="row">';
contenu += '###BLOCK_DESC###';
contenu += ' </div>';
contenu += '</div>';
return contenu;
}
function _addDivForBlock(block_height, onTop = false)
{
var lediv = document.getElementById('info_'+block_height);
if (lediv === null)
{
var contenu = '';
var tmp;
var contenu = _addDiv(block_height);
var block_desc = '';
contenu += '<div id="the_void" class="container-fluid '+classes[cur_class]+'">';
contenu += ' <div class="row">';
contenu += ' <div class="col-sm-8">';
contenu += ' <h2>the VOID ... </h2>';
contenu += ' </div>';
contenu += ' <div class="col-sm-4 text-right">';
contenu += ' <div width="100%" class="text-center">';
contenu += ' <img src="images/loading.gif" class="img-responsive"></img>';
contenu += ' </div>';
contenu += ' </div>';
contenu += ' </div>';
contenu += '</div>';
block_desc += ' <div class="col-sm-12" id="info_'+block_height+'">';
block_desc += ' <h2>BLOCK '+block_height+' ...</h2>';
block_desc += ' </div>';
$('#blockchain').append(contenu);
tmp = contenu.replace('###BLOCK_DESC###',block_desc)
return true;
}
function toggleForwardBtn()
{
if (cur_height.length < 3)
{
$('#fast_forward_btn').removeClass('btn-success');
$('#fast_forward_btn').addClass('btn-secondary');
$('#btn-forward').removeClass('btn-info');
$('#btn-forward').addClass('btn-secondary');
if (onTop) {
tmp += $('#blockchain').html();
$('#blockchain').html(tmp);
} else {
$('#fast_forward_btn').removeClass('btn-secondary');
$('#fast_forward_btn').addClass('btn-success');
$('#btn-forward').removeClass('btn-secondary');
$('#btn-forward').addClass('btn-info');
$('#blockchain').append(tmp);
}
return true;
}
return true;
}
function _addDivForVoid()
{
return _addDivForBlock('void');
}
function gotoBlock(block_name)
function _gotoBlock(block_name)
{
$(document).scrollTop( $("#explorer").offset().top );
// Bloquer la navigation pendant le calcul
if (!flag_nav)
{
$(document).scrollTop( $("#explorer").offset().top );
// Bloquer la navigation pendant le calcul
if (!flag_nav)
{
window.alert('A block image is currently computed, please wait ...');
return false;
}
flag_nav = false;
if (block_name == 'NEXT')
{
flag_nav = true;
// Supprimer un block
if (cur_height.length < 3)
{
window.alert('No Next Block, you are at '+$('#blockSelector').val()+' block !');
return false;
}
liste_blocks['PREVIOUS'] = liste_blocks['BLOCK_'+cur_height[cur_height.length-1]];
cur_height.pop();
toggleForwardBtn();
$('#block_'+cur_height[cur_height.length-2]).slideDown(400, function() {
// Animation complete.
$('#blockchain').children('div:last').remove();
cur_class = 1 - cur_class;
});
} else {
// Ajouter un block
addDivForBlock(cur_height[cur_height.length-1] - 1);
// Décaler d'un block vers le haut
if (cur_height.length > 1) $('#block_'+cur_height[cur_height.length-2]).slideUp();
block_hash = '';
if (block_name != 'LAST') block_hash = '?block_hash='+liste_blocks[block_name];
$.getJSON('data/getBlockInfo.php'+block_hash, function( data ) {
liste_blocks['PREVIOUS'] = data.prev;
liste_blocks['BLOCK_'+data.height] = data.hash;
addInfoForBlock(data);
toggleForwardBtn();
});
}
return true;
window.alert('A block image is currently computed, please wait ...');
return false;
}
flag_nav = false;
function ajouterPreviousBlock()
if (block_name == 'NEXT')
{
// Bloquer la navigation pendant le calcul
if (!flag_nav) return false;
flag_nav = false;
// Ajouter un div
addDivForBlock(cur_height[cur_height.length-1] - 1);
// Mettre les infos du
block_hash = '?block_hash='+liste_blocks['PREVIOUS'];
$.getJSON('data/getBlockInfo.php'+block_hash, function( data ) {
liste_blocks['PREVIOUS'] = data.prev;
liste_blocks['BLOCK_'+data.height] = data.hash;
addInfoForBlock(data);
});
}
function initBlockchain(block_name)
{
$(document).scrollTop( $("#explorer").offset().top );
$('#blockchain').html('');
cur_height = [];
cur_class = 0;
flag_nav = true;
// Supprimer un block
if (cur_height.length < 3)
{
window.alert('No Next Block, you are at '+$('#blockSelector').val()+' block !');
return false;
}
_liste_blocks['PREVIOUS'] = _liste_blocks['BLOCK_'+cur_height[cur_height.length-1]];
cur_height.pop();
_toggleForwardBtn();
$('#block_'+cur_height[cur_height.length-2]).slideDown(400, function() {
// Animation complete.
$('#blockchain').children('div:last').remove();
_cur_class = 1 - _cur_class;
});
} else {
// Ajouter un block
_addDivForBlock(cur_height[cur_height.length-1] - 1);
// Décaler d'un block vers le haut
if (cur_height.length > 1) $('#block_'+cur_height[cur_height.length-2]).slideUp();
block_hash = '';
if (block_name != 'LAST') block_hash = '?block_hash='+liste_blocks[block_name];
if (block_name != 'LAST') block_hash = '?block_hash='+_liste_blocks[block_name];
$.getJSON('data/getBlockInfo.php'+block_hash, function( data ) {
addDivForBlock(data.height);
addInfoForBlock(data);
_liste_blocks['PREVIOUS'] = data.prev;
_liste_blocks['BLOCK_'+data.height] = data.hash;
_addInfoForBlock(data);
liste_blocks['PREVIOUS'] = data.prev;
if (data.prev != '0000000000000000000000000000000000000000000000000000000000000000')
gotoBlock('PREVIOUS');
else
addDivForVoid();
_toggleForwardBtn();
});
return true;
}
function blockSelectorChange()
{
initBlockchain($('#blockSelector').val());
$('#fast_forward_btn').attr('data-original-title', $('#blockSelector').val());
}
return true;
}
function initBlockExplorer(leblock)
{
// Init the selector
var select = $('#blockSelector');
$.each(liste_blocks, function (key, text) {
select.append(new Option(key, key));
});
if (cur_height.length == 0) initBlockchain('LAST');
}
function _addTopBlock(data, flag = false)
{
if (flag) return "ajouterTopBlock";
$(document).ready(function(){
last_block_hooks.push(initBlockExplorer);
// Maintenir la liste des blocks
_liste_blocks['TOP'] = data.hash;
_liste_blocks['BLOCK_'+data.height] = data.hash;
// Ajouter un div
if (_mode < 2) _addDivForBlock(data.height,true);
// Mettre les infos dans le div
_addInfoForBlock(data);
topistoConsole.log('Last Block on top : '+data.hash);
}
function _addBottomBlock()
{
// Mettre les infos du block
block_hash = '?block_hash='+_liste_blocks['BOTTOM'];
$.getJSON('data/getBlockInfo.php'+block_hash, function( data ) {
// Ajouter un div
_addDivForBlock(data.height, false);
// Mettre les infos dans le div
_addInfoForBlock(data);
_liste_blocks['BLOCK_'+data.height] = data.hash;
_liste_blocks['LENGTH'] += 1;
switch(_mode)
{
case 0:
case 1:
// Récursivité pour précharger par paquets
if (data.height > 0)
_liste_blocks['BOTTOM'] = data.prev;
break;
case 2:
case 3:
if (data.height > 0)
_liste_blocks['BOTTOM'] = _known_blocks[_liste_blocks['LENGTH']-1].hash;
break;
}
if (_liste_blocks['LENGTH'] % 10) _addBottomBlock();
});
}
function _initBlockchain(block_name)
{
var block_hash = '';
_liste_blocks = [];
_liste_blocks['LENGTH'] = 0;
$(document).scrollTop( $("#explorer").offset().top );
$('#blockchain').html('');
if (block_name != 'LAST') block_hash = '?block_hash='+_getblocHashFromName(block_name);
$.getJSON('data/getBlockInfo.php'+block_hash, function( data ) {
_liste_blocks['TOP'] = data.hash;
_liste_blocks['BLOCK_'+data.height] = data.hash;
_liste_blocks['LENGTH'] += 1;
div_label = data.height;
switch(_mode)
{
case 0:
case 1:
// Récursivité pour précharger par paquets
_liste_blocks['BOTTOM'] = data.prev;
break;
case 2:
case 3:
div_label = 'LAST';
_liste_blocks['BOTTOM'] = _known_blocks[0].hash;
break;
}
_addDivForBlock(div_label);
_addInfoForBlock(data);
blockchainListener.addBlockHook(_addTopBlock);
_addBottomBlock();
});
return true;
}
function _blockSelectorChange()
{
_initBlockchain($('#blockSelector').val());
}
function _initBlockSelector()
{
// Init the selector
var select = $('#blockSelector');
$.each(_liste_blocks, function (key, bloc) {
select.append(new Option(bloc.name, bloc.name));
});
}
function _init(mode = 1)
{
_mode = mode;
if (_known_blocks == null)
{
$.getJSON('data/getKnownBlocksList.php', function( data ) {
_known_blocks = data;
_known_blocks.sort(function(a,b){
// sort desc ...
if (a.height < b.height) return 1;
if (a.height > b.height) return -1;
return 0;
});
_initBlockchain('LAST');
return true;
});
} else {
_initBlockchain('LAST');
return true;
}
}
return {
addTopBlock: _addTopBlock,
addBottomBlock: _addBottomBlock,
getblocHashFromName: _getblocHashFromName,
init: _init
};
}();

27
js/console.js Normal file
View File

@@ -0,0 +1,27 @@
/*
* Ce module fournit un log personnalisé
*/
topistoConsole = function(){
var _flag = true;
function _log(texte)
{
if (_flag) console.log(texte);
return _flag;
};
function _on()
{
_flag = true;
return _flag;
};
function _off()
{
_flag = false;
return _flag;
};
return {log: _log, on: _on, off: _off};
}();

View File

@@ -1,34 +1,65 @@
function logBlockHash(leblock)
{
console.log('Last Block detected : '+leblock.hash);
}
/*
* Ce module permet d'écouter la blockchain
* Il maintient un tableau de hooks
* Il vérifie l'existence d'un nouveau block toutes les 30s
* Si un nouveau block est détecté, les hooks sont lancés un par un
*/
blockchainListener = function(){
var last_block = null;
var last_block_hooks = [logBlockHash];
var last_block_refresh_flag = true;
var _last_block = null;
var _last_block_hooks = [];
function _logBlockHash(leblock, flag)
{
if (flag) return "logBlockHash";
topistoConsole.log('Last Block detected : '+leblock.hash);
};
function getLastBlockInfo()
{
$.get( "data/getBlockInfo.php", function( data ) {
if ((last_block == null)||(last_block.hash != data.hash))
{
if (last_block_refresh_flag && (last_block != null))
last_block_refresh_flag = window.confirm('New block detected, apply change ?');
last_block = data;
if (last_block_refresh_flag)
function _isBlockNew(leblock)
{
return ((_last_block == null)||(_last_block.hash != leblock.hash));
};
function _lastBlockTrigger()
{
$.get( "data/getBlockInfo.php", function( data ) {
if (_last_block_hooks.length > 0)
{
last_block_hooks.forEach(function(element) {
element(last_block);
});
if (_isBlockNew(data))
{
if (_last_block = data != null)
{
_last_block_hooks.forEach(function(trigger) {
if (trigger instanceof Function) trigger(data);
});
}
_last_block = data;
}
}
}
}, "json" );
}, "json" );
};
setTimeout(getLastBlockInfo, 30000);
}
function _addBlockHook(addBlockHook){
var hookname = addBlockHook(null, true);
var flag_add = false;
_last_block_hooks.forEach(function(trigger) {
if (trigger instanceof Function)
{
var local_hookname = trigger(null, true);
flag_add = flag_add || (local_hookname == hookname);
}
});
if (!flag_add) _last_block_hooks.push(addBlockHook);
};
function _init(){
_addBlockHook(_logBlockHash);
setInterval(_lastBlockTrigger, 30000);
};
return {init: _init, addBlockHook: _addBlockHook};
}();
$(document).ready(function() {
getLastBlockInfo();
blockchainListener.init();
});

675
js/simpleParallax.js Normal file
View File

@@ -0,0 +1,675 @@
/*!
* simpleParallax - simpleParallax is a simple JavaScript library that gives your website parallax animations on any images,
* @date: 07-12-2019 18:53:52,
* @version: 5.2.0,
* @link: https://simpleparallax.com/
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("simpleParallax", [], factory);
else if(typeof exports === 'object')
exports["simpleParallax"] = factory();
else
root["simpleParallax"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./src/helpers/viewport.js
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Viewport =
/*#__PURE__*/
function () {
function Viewport() {
_classCallCheck(this, Viewport);
this.positions = {
top: 0,
bottom: 0,
height: 0
};
}
_createClass(Viewport, [{
key: "setViewportTop",
value: function setViewportTop(container) {
// if this is a custom container, user the scrollTop
this.positions.top = container ? container.scrollTop : window.pageYOffset;
return this.positions;
}
}, {
key: "setViewportBottom",
value: function setViewportBottom() {
this.positions.bottom = this.positions.top + this.positions.height;
return this.positions;
}
}, {
key: "setViewportAll",
value: function setViewportAll(container) {
// if this is a custom container, user the scrollTop
this.positions.top = container ? container.scrollTop : window.pageYOffset; // if this is a custom container, get the height from the custom container itself
this.positions.height = container ? container.clientHeight : document.documentElement.clientHeight;
this.positions.bottom = this.positions.top + this.positions.height;
return this.positions;
}
}]);
return Viewport;
}();
var viewport = new Viewport();
// CONCATENATED MODULE: ./src/helpers/convertToArray.js
// check wether the element is a Node List, a HTML Collection or an array
// return an array of nodes
var convertToArray = function convertToArray(elements) {
if (NodeList.prototype.isPrototypeOf(elements) || HTMLCollection.prototype.isPrototypeOf(elements)) return Array.from(elements);
if (typeof elements === 'string' || elements instanceof String) return document.querySelectorAll(elements);
return [elements];
};
/* harmony default export */ var helpers_convertToArray = (convertToArray);
// CONCATENATED MODULE: ./src/helpers/cssTransform.js
// Detect css transform
var cssTransform = function cssTransform() {
var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' ');
var transform;
var i = 0;
while (transform === undefined) {
transform = document.createElement('div').style[prefixes[i]] !== undefined ? prefixes[i] : undefined;
i += 1;
}
return transform;
};
/* harmony default export */ var helpers_cssTransform = (cssTransform());
// CONCATENATED MODULE: ./src/helpers/isImageLoaded.js
// check if image is fully loaded
var isImageLoaded = function isImageLoaded(image) {
// check if image is set as the parameter
if (!image) {
return false;
} // check if image has been 100% loaded
if (!image.complete) {
return false;
} // check if the image is displayed
if (typeof image.naturalWidth !== 'undefined' && image.naturalWidth === 0) {
return false;
}
return true;
};
/* harmony default export */ var helpers_isImageLoaded = (isImageLoaded);
// CONCATENATED MODULE: ./src/instances/parallax.js
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function parallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function parallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function parallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) parallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) parallax_defineProperties(Constructor, staticProps); return Constructor; }
var parallax_ParallaxInstance =
/*#__PURE__*/
function () {
function ParallaxInstance(element, options) {
parallax_classCallCheck(this, ParallaxInstance);
// set the element & settings
this.element = element;
this.elementContainer = element;
this.settings = options;
this.isVisible = true;
this.isInit = false;
this.oldTranslateValue = -1;
this.init = this.init.bind(this); // check if images has not been loaded yet
if (helpers_isImageLoaded(element)) {
this.init();
} else {
this.element.addEventListener('load', this.init);
}
}
parallax_createClass(ParallaxInstance, [{
key: "init",
value: function init() {
var _this = this;
// for some reason, <picture> are init an infinite time on windows OS
if (this.isInit) return; // check if element has not been already initialized with simpleParallax
if (this.element.closest('.simpleParallax')) return;
if (this.settings.overflow === false) {
// if overflow option is set to false
// wrap the element into a div to apply overflow
this.wrapElement(this.element);
} // apply the transform style on the image
this.setTransformCSS(); // get the current element offset
this.getElementOffset(); // init the Intesection Observer
this.intersectionObserver(); // get its translated value
this.getTranslateValue(); // apply its translation even if not visible for the first init
this.animate(); // if a delay has been set
if (this.settings.delay > 0) {
// apply a timeout to avoid buggy effect
setTimeout(function () {
// apply the transition style on the image
_this.setTransitionCSS();
}, 10);
} // for some reason, <picture> are init an infinite time on windows OS
this.isInit = true;
} // if overflow option is set to false
// wrap the element into a .simpleParallax div and apply overflow hidden to hide the image excedant (result of the scale)
}, {
key: "wrapElement",
value: function wrapElement() {
// check is current image is in a <picture> tag
var elementToWrap = this.element.closest('picture') || this.element; // create a .simpleParallax wrapper container
var wrapper = document.createElement('div');
wrapper.classList.add('simpleParallax');
wrapper.style.overflow = 'hidden'; // append the image inside the new wrapper
elementToWrap.parentNode.insertBefore(wrapper, elementToWrap);
wrapper.appendChild(elementToWrap);
this.elementContainer = wrapper;
} // unwrap the element from .simpleParallax wrapper container
}, {
key: "unWrapElement",
value: function unWrapElement() {
var wrapper = this.elementContainer;
wrapper.replaceWith.apply(wrapper, _toConsumableArray(wrapper.childNodes));
} // apply default style on element
}, {
key: "setTransformCSS",
value: function setTransformCSS() {
if (this.settings.overflow === false) {
// if overflow option is set to false
// add scale style so the image can be translated without getting out of its container
this.element.style[helpers_cssTransform] = "scale(".concat(this.settings.scale, ")");
} // add will-change CSS property to improve perfomance
this.element.style.willChange = 'transform';
} // apply the transition effet
}, {
key: "setTransitionCSS",
value: function setTransitionCSS() {
// add transition option
this.element.style.transition = "transform ".concat(this.settings.delay, "s ").concat(this.settings.transition);
} // remove style of the element
}, {
key: "unSetStyle",
value: function unSetStyle() {
// remove will change inline style
this.element.style.willChange = '';
this.element.style[helpers_cssTransform] = '';
this.element.style.transition = '';
} // get the current element offset
}, {
key: "getElementOffset",
value: function getElementOffset() {
// get position of the element
var positions = this.elementContainer.getBoundingClientRect(); // get height
this.elementHeight = positions.height; // get offset top
this.elementTop = positions.top + viewport.positions.top; // if there is a custom container
if (this.settings.customContainer) {
// we need to do some calculation to get the position from the parent rather than the viewport
var parentPositions = this.settings.customContainer.getBoundingClientRect();
this.elementTop = positions.top - parentPositions.top + viewport.positions.top;
} // get offset bottom
this.elementBottom = this.elementHeight + this.elementTop;
} // build the Threshold array to cater change for every pixel scrolled
}, {
key: "buildThresholdList",
value: function buildThresholdList() {
var thresholds = [];
for (var i = 1.0; i <= this.elementHeight; i++) {
var ratio = i / this.elementHeight;
thresholds.push(ratio);
}
return thresholds;
} // create the Intersection Observer
}, {
key: "intersectionObserver",
value: function intersectionObserver() {
var options = {
root: null,
threshold: this.buildThresholdList()
};
this.observer = new IntersectionObserver(this.intersectionObserverCallback.bind(this), options);
this.observer.observe(this.element);
} // Intersection Observer Callback to set the element at visible state or not
}, {
key: "intersectionObserverCallback",
value: function intersectionObserverCallback(entries) {
for (var i = entries.length - 1; i >= 0; i--) {
if (entries[i].isIntersecting) {
this.isVisible = true;
} else {
this.isVisible = false;
}
}
} // check if the current element is visible in the Viewport
// for browser that not support Intersection Observer API
}, {
key: "checkIfVisible",
value: function checkIfVisible() {
return this.elementBottom > viewport.positions.top && this.elementTop < viewport.positions.bottom;
} // calculate the range between image will be translated
}, {
key: "getRangeMax",
value: function getRangeMax() {
// get the real height of the image without scale
var elementImageHeight = this.element.clientHeight; // range is calculate with the image height by the scale
this.rangeMax = elementImageHeight * this.settings.scale - elementImageHeight;
} // get the percentage and the translate value to apply on the element
}, {
key: "getTranslateValue",
value: function getTranslateValue() {
// calculate the % position of the element comparing to the viewport
// rounding percentage to a 1 number float to avoid unn unnecessary calculation
var percentage = ((viewport.positions.bottom - this.elementTop) / ((viewport.positions.height + this.elementHeight) / 100)).toFixed(1); // sometime the percentage exceeds 100 or goes below 0
percentage = Math.min(100, Math.max(0, percentage)); // sometime the same percentage is returned
// if so we don't do aything
if (this.oldPercentage === percentage) {
return false;
} // if not range max is set, recalculate it
if (!this.rangeMax) {
this.getRangeMax();
} // transform this % into the max range of the element
// rounding translateValue to a non float int - as minimum pixel for browser to render is 1 (no 0.5)
this.translateValue = (percentage / 100 * this.rangeMax - this.rangeMax / 2).toFixed(0); // sometime the same translate value is returned
// if so we don't do aything
if (this.oldTranslateValue === this.translateValue) {
return false;
} // store the current percentage
this.oldPercentage = percentage;
this.oldTranslateValue = this.translateValue;
return true;
} // animate the image
}, {
key: "animate",
value: function animate() {
var translateValueY = 0;
var translateValueX = 0;
var inlineCss;
if (this.settings.orientation.includes('left') || this.settings.orientation.includes('right')) {
// if orientation option is left or right
// use horizontal axe - X axe
translateValueX = "".concat(this.settings.orientation.includes('left') ? this.translateValue * -1 : this.translateValue, "px");
}
if (this.settings.orientation.includes('up') || this.settings.orientation.includes('down')) {
// if orientation option is up or down
// use vertical axe - Y axe
translateValueY = "".concat(this.settings.orientation.includes('up') ? this.translateValue * -1 : this.translateValue, "px");
} // set style to apply to the element
if (this.settings.overflow === false) {
// if overflow option is set to false
// add the scale style
inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0) scale(").concat(this.settings.scale, ")");
} else {
inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0)");
} // add style on the element using the adequate CSS transform
this.element.style[helpers_cssTransform] = inlineCss;
}
}]);
return ParallaxInstance;
}();
/* harmony default export */ var parallax = (parallax_ParallaxInstance);
// CONCATENATED MODULE: ./src/simpleParallax.js
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return simpleParallax_SimpleParallax; });
function simpleParallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function simpleParallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function simpleParallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) simpleParallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) simpleParallax_defineProperties(Constructor, staticProps); return Constructor; }
var intersectionObserverAvailable = true;
var isInit = false;
var instances = [];
var instancesLength;
var frameID;
var resizeID;
var simpleParallax_SimpleParallax =
/*#__PURE__*/
function () {
function SimpleParallax(elements, options) {
simpleParallax_classCallCheck(this, SimpleParallax);
if (!elements) return;
this.elements = helpers_convertToArray(elements);
this.defaults = {
delay: 0.4,
orientation: 'up',
scale: 1.3,
overflow: false,
transition: 'cubic-bezier(0,0,0,1)',
customContainer: false
};
this.settings = Object.assign(this.defaults, options); // check if the browser handle the Intersection Observer API
if (!('IntersectionObserver' in window)) intersectionObserverAvailable = false;
if (this.settings.customContainer) {
console.log(helpers_convertToArray(this.settings.customContainer)[0]);
this.customContainer = helpers_convertToArray(this.settings.customContainer)[0];
}
this.lastPosition = -1;
this.resizeIsDone = this.resizeIsDone.bind(this);
this.handleResize = this.handleResize.bind(this);
this.proceedRequestAnimationFrame = this.proceedRequestAnimationFrame.bind(this);
this.init();
}
simpleParallax_createClass(SimpleParallax, [{
key: "init",
value: function init() {
viewport.setViewportAll(this.customContainer);
for (var i = this.elements.length - 1; i >= 0; i--) {
var instance = new parallax(this.elements[i], this.settings);
instances.push(instance);
} // update the instance length
instancesLength = instances.length; // only if this is the first simpleParallax init
if (!isInit) {
// init the frame
this.proceedRequestAnimationFrame();
window.addEventListener('resize', this.resizeIsDone);
isInit = true;
}
} // wait for resize to be completely done
}, {
key: "resizeIsDone",
value: function resizeIsDone() {
clearTimeout(resizeID);
resizeID = setTimeout(this.handleResize, 500);
} // handle the resize process, some coordonates need to be re-calculate
}, {
key: "handleResize",
value: function handleResize() {
// re-get all the viewport positions
viewport.setViewportAll(this.customContainer);
for (var i = instancesLength - 1; i >= 0; i--) {
// re-get the current element offset
instances[i].getElementOffset(); // re-get the range if the current element
instances[i].getRangeMax();
} // force the request animation frame to fired
this.lastPosition = -1;
} // animation frame
}, {
key: "proceedRequestAnimationFrame",
value: function proceedRequestAnimationFrame() {
// get the offset top of the viewport
viewport.setViewportTop(this.customContainer);
if (this.lastPosition === viewport.positions.top) {
// if last position if the same than the curent one
// callback the animationFrame and exit the current loop
frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame);
return;
} // get the offset bottom of the viewport
viewport.setViewportBottom(); // proceed with the current element
for (var i = instancesLength - 1; i >= 0; i--) {
this.proceedElement(instances[i]);
} // callback the animationFrame
frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); // store the last position
this.lastPosition = viewport.positions.top;
} // proceed the element
}, {
key: "proceedElement",
value: function proceedElement(instance) {
var isVisible = false; // is not support for Intersection Observer API
// or if this is a custom container
// use old function to check if element visible
if (!intersectionObserverAvailable || this.customContainer) {
isVisible = instance.checkIfVisible(); // if support
// use response from Intersection Observer API Callback
} else {
isVisible = instance.isVisible;
} // if element not visible, stop it
if (!isVisible) return; // if percentage is equal to the last one, no need to continue
if (!instance.getTranslateValue()) {
return;
} // animate the image
instance.animate();
}
}, {
key: "destroy",
value: function destroy() {
var _this = this;
var instancesToDestroy = []; // remove all instances that need to be destroyed from the instances array
instances = instances.filter(function (instance) {
if (_this.elements.includes(instance.element)) {
// push instance that need to be destroyed into instancesToDestroy
instancesToDestroy.push(instance);
return false;
}
return instance;
});
for (var i = instancesToDestroy.length - 1; i >= 0; i--) {
// unset style
instancesToDestroy[i].unSetStyle();
if (this.settings.overflow === false) {
// if overflow option is set to false
// unwrap the element from .simpleParallax wrapper container
instancesToDestroy[i].unWrapElement();
}
} // update the instance length var
instancesLength = instances.length; // if no instances left, remove the raf and resize event = simpleParallax fully destroyed
if (!instancesLength) {
// cancel the animation frame
window.cancelAnimationFrame(frameID); // detach the resize event
window.removeEventListener('resize', this.handleResize);
}
}
}]);
return SimpleParallax;
}();
/***/ })
/******/ ])["default"];
});

Binary file not shown.

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 PixelCog Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,242 @@
Parallax.js
===========
Simple parallax scrolling effect inspired by [Spotify.com](http://spotify.com/) implemented as a jQuery plugin
[http://pixelcog.com/parallax.js/](http://pixelcog.com/parallax.js/)
## Installation
### NPM
```bash
npm i --save jquery-parallax.js
```
### Yarn
```bash
yarn add jquery-parallax.js
```
### Bower
Please note that although Bower is still maintained, they recommend Yarn for new projects.
```bash
$ bower i --save parallax.js
```
### Setup
Include `parallax.min.js` in your document after including jQuery (compatible with jQuery >= 1.7).
```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="/path/to/parallax.min.js"></script>
```
Use these CDN links, provided by jsDelivr.com
```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/parallax.js/1.4.2/parallax.min.js"></script>
```
## Usage
Please note, that `<!DOCTYPE html>` on top of your document is required!
### Via data attributes
To easily add a parallax effect behind an element, add `data-parallax="scroll"` to the element you want to use, and specify an image with `data-image-src="/path/to/image.jpg"`.
```html
<div class="parallax-window" data-parallax="scroll" data-image-src="/path/to/image.jpg"></div>
```
### Via JavaScript
To call the parallax plugin manually, simply select your target element with jQuery and do the following:
```javascript
$('.parallax-window').parallax({imageSrc: '/path/to/image.jpg'});
```
### Notes
What parallax.js will do is create a fixed-position element for each parallax image at the start of the document's body (or another configurable container). This mirror element will sit behind the other elements and match the position and dimensions of its target object.
Due to the nature of this implementation, you must ensure that these parallax objects and any layers below them are transparent so that you can see the parallax effect underneath. Also, if there is no other content in this element, you will need to ensure that it has some fixed dimensions otherwise you won't see anything.
```css
.parallax-window {
min-height: 400px;
background: transparent;
}
```
Also, keep in mind that once initialized, the parallax plugin presumes a fixed page layout unless it encounters a `scroll` or `resize` event. If you have a dynamic page in which another javascript method may alter the DOM, you must manually refresh the parallax effect with the following commands:
```javascript
jQuery(window).trigger('resize').trigger('scroll');
```
### Using inner HTML for complex content
You can use the following syntax to enable complex content for the parallax:
```html
<div class="parallax-window">
<div class="parallax-slider">
<span style="position:absolute; top: 400px; left: 400px;">Some Text</span>
<p>Some other Content</p>
</div>
</div>
```
Please note, that the div with class "parallax-slider" is essential here.
You then need to initialize it through JS and provide the naturalWidth and naturalHeight options in order to be rendered correctly.
```
$('.parallax-window').parallax({
naturalWidth: 600,
naturalHeight: 400
});
```
This also makes it possible to use responsive images in the slider:
```html
<div class="parallax-window">
<div class="parallax-slider">
<img src="/path/to/image.jpg" srcset="/path/to/image-400px.jpg 400w, /path/to/image-800px.jpg 800w, /path/to/image-1200px.jpg 1200w" sizes="100vw">
</div>
</div>
```
## Options
Options can be passed in via data attributes of JavaScript. For data attributes, append the option name to `data-`, as in `data-image-src=""`.
Note that when specifying these options as html data-attributes, you should convert "camelCased" variable names into "dash-separated" lower-case names (e.g. `zIndex` would be `data-z-index=""`).
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">Name</th>
<th style="width: 100px;">type</th>
<th style="width: 50px;">default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>imageSrc</td>
<td>path</td>
<td>null</td>
<td>You must provide a path to the image you wish to apply to the parallax effect.</td>
</tr>
<tr>
<td>naturalWidth</td>
<td>number</td>
<td>auto</td>
<td rowspan="2">You can provide the natural width and natural height of an image to speed up loading and reduce error when determining the correct aspect ratio of the image.</td>
</tr>
<tr>
<td>naturalHeight</td>
<td>number</td>
<td>auto</td>
</tr>
<tr>
<td>position</td>
<td>xPos yPos</td>
<td>center center</td>
<td rowspan="3">This is analogous to the background-position css property. Specify coordinates as top, bottom, right, left, center, or pixel values (e.g. -10px 0px). The parallax image will be positioned as close to these values as possible while still covering the target element.</td>
</tr>
<tr>
<td>positionX</td>
<td>xPos</td>
<td>center</td>
</tr>
<tr>
<td>positionY</td>
<td>yPos</td>
<td>center</td>
</tr>
<tr>
<td>speed</td>
<td>float</td>
<td>0.2</td>
<td>The speed at which the parallax effect runs. 0.0 means the image will appear fixed in place, and 1.0 the image will flow at the same speed as the page content.</td>
</tr>
<tr>
<td>zIndex</td>
<td>number</td>
<td>-100</td>
<td>The z-index value of the fixed-position elements. By default these will be behind everything else on the page.</td>
</tr>
<tr>
<td>bleed</td>
<td>number</td>
<td>0</td>
<td>You can optionally set the parallax mirror element to extend a few pixels above and below the mirrored element. This can hide slow or stuttering scroll events in certain browsers.</td>
</tr>
<tr>
<td>iosFix</td>
<td>boolean</td>
<td>true</td>
<td>iOS devices are incompatable with this plugin. If true, this option will set the parallax image as a static, centered background image whenever it detects an iOS user agent. Disable this if you wish to implement your own graceful degradation.</td>
</tr>
<tr>
<td>androidFix</td>
<td>boolean</td>
<td>true</td>
<td>If true, this option will set the parallax image as a static, centered background image whenever it detects an Android user agent. Disable this if you wish to enable the parallax scrolling effect on Android devices.</td>
</tr>
<tr>
<td>overScrollFix</td>
<td>boolean</td>
<td>false</td>
<td>(Experimental) If true, will freeze the parallax effect when "over scrolling" in browsers like Safari to prevent unexpected gaps caused by negative scroll positions.</td>
</tr>
<tr>
<td>mirrorContainer</td>
<td>jQuery Selector</td>
<td>body</td>
<td>The parallax mirror will be prepended into this container.</td>
</tr>
</tbody>
</table>
## Contributing
If you have a pull request you would like to submit, please ensure that you update the minified version of the library along with your code changes. This project uses [uglifyjs](https://www.npmjs.com/package/uglify-js) to perform code compression.
Please use the following command:
uglifyjs parallax.js --comments -m -c -o parallax.min.js
LICENSE
=======
The MIT License (MIT)
Copyright (c) 2016 PixelCog Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,20 @@
{
"name": "parallax.js",
"version": "1.5.0",
"homepage": "http://pixelcog.com/parallax.js/",
"description": "Simple parallax scrolling effect inspired by spotify.com implemented as a jQuery plugin",
"authors": [
"Mike Greiling <mike@pixelcog.com> (http://pixelcog.com)",
"Wolfgang Stöttinger (http://www.wolfography.at)"
],
"main": "parallax.min.js",
"license": "MIT",
"keywords" : ["parallax", "scroll", "scrolling", "image"],
"ignore": [
".jshintrc",
"**/*.txt"
],
"dependencies": {
"jquery": ">=1.7"
}
}

View File

@@ -0,0 +1,31 @@
{
"name": "jquery-parallax.js",
"version": "1.5.0",
"description": "Simple parallax scrolling effect inspired by spotify.com implemented as a jQuery plugin",
"main": "parallax.min.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/pixelcog/parallax.js.git"
},
"keywords": [
"parallax",
"scroll",
"scrolling",
"image"
],
"author": [
"Mike Greiling <mike@pixelcog.com> (http://pixelcog.com)",
"Wolfgang Stöttinger (http://www.wolfography.at)"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/pixelcog/parallax.js/issues"
},
"homepage": "https://github.com/pixelcog/parallax.js#readme",
"dependencies": {
"jquery": ">=1.7"
}
}

View File

@@ -0,0 +1,412 @@
/*!
* parallax.js v1.5.0 (http://pixelcog.github.io/parallax.js/)
* @copyright 2016 PixelCog, Inc.
* @license MIT (https://github.com/pixelcog/parallax.js/blob/master/LICENSE)
*/
;(function ( $, window, document, undefined ) {
// Polyfill for requestAnimationFrame
// via: https://gist.github.com/paulirish/1579671
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
// Parallax Constructor
function Parallax(element, options) {
var self = this;
if (typeof options == 'object') {
delete options.refresh;
delete options.render;
$.extend(this, options);
}
this.$element = $(element);
if (!this.imageSrc && this.$element.is('img')) {
this.imageSrc = this.$element.attr('src');
}
var positions = (this.position + '').toLowerCase().match(/\S+/g) || [];
if (positions.length < 1) {
positions.push('center');
}
if (positions.length == 1) {
positions.push(positions[0]);
}
if (positions[0] == 'top' || positions[0] == 'bottom' || positions[1] == 'left' || positions[1] == 'right') {
positions = [positions[1], positions[0]];
}
if (this.positionX !== undefined) positions[0] = this.positionX.toLowerCase();
if (this.positionY !== undefined) positions[1] = this.positionY.toLowerCase();
self.positionX = positions[0];
self.positionY = positions[1];
if (this.positionX != 'left' && this.positionX != 'right') {
if (isNaN(parseInt(this.positionX))) {
this.positionX = 'center';
} else {
this.positionX = parseInt(this.positionX);
}
}
if (this.positionY != 'top' && this.positionY != 'bottom') {
if (isNaN(parseInt(this.positionY))) {
this.positionY = 'center';
} else {
this.positionY = parseInt(this.positionY);
}
}
this.position =
this.positionX + (isNaN(this.positionX)? '' : 'px') + ' ' +
this.positionY + (isNaN(this.positionY)? '' : 'px');
if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
if (this.imageSrc && this.iosFix && !this.$element.is('img')) {
this.$element.css({
backgroundImage: 'url(' + this.imageSrc + ')',
backgroundSize: 'cover',
backgroundPosition: this.position
});
}
return this;
}
if (navigator.userAgent.match(/(Android)/)) {
if (this.imageSrc && this.androidFix && !this.$element.is('img')) {
this.$element.css({
backgroundImage: 'url(' + this.imageSrc + ')',
backgroundSize: 'cover',
backgroundPosition: this.position
});
}
return this;
}
this.$mirror = $('<div />').prependTo(this.mirrorContainer);
var slider = this.$element.find('>.parallax-slider');
var sliderExisted = false;
if (slider.length == 0)
this.$slider = $('<img />').prependTo(this.$mirror);
else {
this.$slider = slider.prependTo(this.$mirror)
sliderExisted = true;
}
this.$mirror.addClass('parallax-mirror').css({
visibility: 'hidden',
zIndex: this.zIndex,
position: 'fixed',
top: 0,
left: 0,
overflow: 'hidden'
});
this.$slider.addClass('parallax-slider').one('load', function() {
if (!self.naturalHeight || !self.naturalWidth) {
self.naturalHeight = this.naturalHeight || this.height || 1;
self.naturalWidth = this.naturalWidth || this.width || 1;
}
self.aspectRatio = self.naturalWidth / self.naturalHeight;
Parallax.isSetup || Parallax.setup();
Parallax.sliders.push(self);
Parallax.isFresh = false;
Parallax.requestRender();
});
if (!sliderExisted)
this.$slider[0].src = this.imageSrc;
if (this.naturalHeight && this.naturalWidth || this.$slider[0].complete || slider.length > 0) {
this.$slider.trigger('load');
}
}
// Parallax Instance Methods
$.extend(Parallax.prototype, {
speed: 0.2,
bleed: 0,
zIndex: -100,
iosFix: true,
androidFix: true,
position: 'center',
overScrollFix: false,
mirrorContainer: 'body',
refresh: function() {
this.boxWidth = this.$element.outerWidth();
this.boxHeight = this.$element.outerHeight() + this.bleed * 2;
this.boxOffsetTop = this.$element.offset().top - this.bleed;
this.boxOffsetLeft = this.$element.offset().left;
this.boxOffsetBottom = this.boxOffsetTop + this.boxHeight;
var winHeight = Parallax.winHeight;
var docHeight = Parallax.docHeight;
var maxOffset = Math.min(this.boxOffsetTop, docHeight - winHeight);
var minOffset = Math.max(this.boxOffsetTop + this.boxHeight - winHeight, 0);
var imageHeightMin = this.boxHeight + (maxOffset - minOffset) * (1 - this.speed) | 0;
var imageOffsetMin = (this.boxOffsetTop - maxOffset) * (1 - this.speed) | 0;
var margin;
if (imageHeightMin * this.aspectRatio >= this.boxWidth) {
this.imageWidth = imageHeightMin * this.aspectRatio | 0;
this.imageHeight = imageHeightMin;
this.offsetBaseTop = imageOffsetMin;
margin = this.imageWidth - this.boxWidth;
if (this.positionX == 'left') {
this.offsetLeft = 0;
} else if (this.positionX == 'right') {
this.offsetLeft = - margin;
} else if (!isNaN(this.positionX)) {
this.offsetLeft = Math.max(this.positionX, - margin);
} else {
this.offsetLeft = - margin / 2 | 0;
}
} else {
this.imageWidth = this.boxWidth;
this.imageHeight = this.boxWidth / this.aspectRatio | 0;
this.offsetLeft = 0;
margin = this.imageHeight - imageHeightMin;
if (this.positionY == 'top') {
this.offsetBaseTop = imageOffsetMin;
} else if (this.positionY == 'bottom') {
this.offsetBaseTop = imageOffsetMin - margin;
} else if (!isNaN(this.positionY)) {
this.offsetBaseTop = imageOffsetMin + Math.max(this.positionY, - margin);
} else {
this.offsetBaseTop = imageOffsetMin - margin / 2 | 0;
}
}
},
render: function() {
var scrollTop = Parallax.scrollTop;
var scrollLeft = Parallax.scrollLeft;
var overScroll = this.overScrollFix ? Parallax.overScroll : 0;
var scrollBottom = scrollTop + Parallax.winHeight;
if (this.boxOffsetBottom > scrollTop && this.boxOffsetTop <= scrollBottom) {
this.visibility = 'visible';
this.mirrorTop = this.boxOffsetTop - scrollTop;
this.mirrorLeft = this.boxOffsetLeft - scrollLeft;
this.offsetTop = this.offsetBaseTop - this.mirrorTop * (1 - this.speed);
} else {
this.visibility = 'hidden';
}
this.$mirror.css({
transform: 'translate3d('+this.mirrorLeft+'px, '+(this.mirrorTop - overScroll)+'px, 0px)',
visibility: this.visibility,
height: this.boxHeight,
width: this.boxWidth
});
this.$slider.css({
transform: 'translate3d('+this.offsetLeft+'px, '+this.offsetTop+'px, 0px)',
position: 'absolute',
height: this.imageHeight,
width: this.imageWidth,
maxWidth: 'none'
});
}
});
// Parallax Static Methods
$.extend(Parallax, {
scrollTop: 0,
scrollLeft: 0,
winHeight: 0,
winWidth: 0,
docHeight: 1 << 30,
docWidth: 1 << 30,
sliders: [],
isReady: false,
isFresh: false,
isBusy: false,
setup: function() {
if (this.isReady) return;
var self = this;
var $doc = $(document), $win = $(window);
var loadDimensions = function() {
Parallax.winHeight = $win.height();
Parallax.winWidth = $win.width();
Parallax.docHeight = $doc.height();
Parallax.docWidth = $doc.width();
};
var loadScrollPosition = function() {
var winScrollTop = $win.scrollTop();
var scrollTopMax = Parallax.docHeight - Parallax.winHeight;
var scrollLeftMax = Parallax.docWidth - Parallax.winWidth;
Parallax.scrollTop = Math.max(0, Math.min(scrollTopMax, winScrollTop));
Parallax.scrollLeft = Math.max(0, Math.min(scrollLeftMax, $win.scrollLeft()));
Parallax.overScroll = Math.max(winScrollTop - scrollTopMax, Math.min(winScrollTop, 0));
};
$win.on('resize.px.parallax load.px.parallax', function() {
loadDimensions();
self.refresh();
Parallax.isFresh = false;
Parallax.requestRender();
})
.on('scroll.px.parallax load.px.parallax', function() {
loadScrollPosition();
Parallax.requestRender();
});
loadDimensions();
loadScrollPosition();
this.isReady = true;
var lastPosition = -1;
function frameLoop() {
if (lastPosition == window.pageYOffset) { // Avoid overcalculations
window.requestAnimationFrame(frameLoop);
return false;
} else lastPosition = window.pageYOffset;
self.render();
window.requestAnimationFrame(frameLoop);
}
frameLoop();
},
configure: function(options) {
if (typeof options == 'object') {
delete options.refresh;
delete options.render;
$.extend(this.prototype, options);
}
},
refresh: function() {
$.each(this.sliders, function(){ this.refresh(); });
this.isFresh = true;
},
render: function() {
this.isFresh || this.refresh();
$.each(this.sliders, function(){ this.render(); });
},
requestRender: function() {
var self = this;
self.render();
self.isBusy = false;
},
destroy: function(el){
var i,
parallaxElement = $(el).data('px.parallax');
parallaxElement.$mirror.remove();
for(i=0; i < this.sliders.length; i+=1){
if(this.sliders[i] == parallaxElement){
this.sliders.splice(i, 1);
}
}
$(el).data('px.parallax', false);
if(this.sliders.length === 0){
$(window).off('scroll.px.parallax resize.px.parallax load.px.parallax');
this.isReady = false;
Parallax.isSetup = false;
}
}
});
// Parallax Plugin Definition
function Plugin(option) {
return this.each(function () {
var $this = $(this);
var options = typeof option == 'object' && option;
if (this == window || this == document || $this.is('body')) {
Parallax.configure(options);
}
else if (!$this.data('px.parallax')) {
options = $.extend({}, $this.data(), options);
$this.data('px.parallax', new Parallax(this, options));
}
else if (typeof option == 'object')
{
$.extend($this.data('px.parallax'), options);
}
if (typeof option == 'string') {
if(option == 'destroy'){
Parallax.destroy(this);
}else{
Parallax[option]();
}
}
});
}
var old = $.fn.parallax;
$.fn.parallax = Plugin;
$.fn.parallax.Constructor = Parallax;
// Parallax No Conflict
$.fn.parallax.noConflict = function () {
$.fn.parallax = old;
return this;
};
// Parallax Data-API
$( function () {
$('[data-parallax="scroll"]').parallax();
});
}(jQuery, window, document));

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-env"]
}

View File

@@ -0,0 +1,4 @@
# Browsers that we support
last 2 versions
not IE > 0
not ie_mob > 0

View File

@@ -0,0 +1,21 @@
module.exports = {
env: {
browser: true,
es6: true
},
extends: 'airbnb-base',
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly'
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module'
},
rules: {
indent: ['error', 4],
'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
'max-len': ['error', { code: 150 }],
'no-prototype-builtins': 0
}
};

View File

@@ -0,0 +1,8 @@
node_modules/
dist/index\.html
dist/test\.js
package-lock\.json
dist/index\.js

View File

@@ -0,0 +1 @@
v11.5.0

View File

@@ -0,0 +1 @@
dist/

View File

@@ -0,0 +1,9 @@
{
"useTabs": false,
"printWidth": 300,
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "none",
"jsxBracketSameLine": false,
"semi": true
}

View File

@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at geoffrey.signorato@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 geosenna
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,130 @@
![simpleParallax logo](https://simpleparallax.b-cdn.net/images/logo.png)
[![GitHub version](https://badge.fury.io/gh/geosenna%2FsimpleParallax.svg)](https://badge.fury.io/gh/geosenna%2FsimpleParallax)
[![](https://data.jsdelivr.com/v1/package/npm/simple-parallax-js/badge?style=rounded)](https://www.jsdelivr.com/package/npm/simple-parallax-js)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
# What is simpleParallax?
simpleParallax is a very simple and tiny Vanilla JS library which adds parallax animations on any images.
Where it may be laborious to get results through other plugins, simpleParallax stands out for its ease and its visual rendering. The parallax effect is directly applied on image tags, there is no need to use background images. You can read one case study [here](https://medium.com/@geoffrey.signorato/case-study-create-a-parallax-effect-directly-on-img-tags-with-javascript-35b8daf81471).
Any image will fit. Try it out!
## Installation
Simply copy/paste the below snippet just before your closing `</body>` tag:
```html
<script src="simpleParallax.js"></script>
```
or use the below CDN link provided by [jsDelivr.com](https://www.jsdelivr.com/package/npm/simple-parallax-js):
```html
<script src="https://cdn.jsdelivr.net/npm/simple-parallax-js@5.2.0/dist/simpleParallax.min.js"></script>
```
or you can install it via [npm/yarn](https://www.npmjs.com/package/simple-parallax-js):
```sh
#npm
npm install simple-parallax-js
#yarn
yarn add simple-parallax-js
```
You can import it as follow:
```javascript
import simpleParallax from 'simple-parallax-js';
```
## Initialization
Giving the following HTML:
```html
<img class="thumbnail" src="image.jpg" alt="image">
```
Simply add the following JavaScript code:
```javascript
var image = document.getElementsByClassName('thumbnail');
new simpleParallax(image);
```
This also work with several images:
```javascript
var images = document.querySelectorAll('img');
new simpleParallax(images);
```
## Settings
Setting | Type | Default | Hint
--- | --- | --- | ---
orientation | string | up | up - right - down - left - up left - up right - down left - down right
scale | int | 1.3 | need to be above 1.0
overflow | boolean | false |
delay | int | 0.4 | the delay is in second
transition | string | false | any CSS transition
customContainer | string or node | false | this can be a string of directly a node
You can apply these settings with the following JS code:
```javascript
var images = document.querySelectorAll('.thumbnail');
new simpleParallax(images, {
delay: 0,
orientation: 'down',
scale: 1.3,
overflow: true,
customContainer: '.container'
});
```
### orientation - *string*
This is the direction of the parallax effect. Choose *up* and when scrolling down, the image will translate from bottom to top. When scroll up, the image will translate from top to bottom.
### scale - *int*
The higher the scale is set, the more visible the parallax effect will be. In return, the image will lose in quality. To reduce the lossless effect, if the scale is set at 1.5 and you image is 500px width, do the simple math 500 * 1.5 = 750. So you can choose a 750px image to replace your 500px one, and don't see any quality leak.
### overflow - *boolean*
By default, the image is scaled to apply a parallax effect without any overflow on the layout (you can check the [case study](https://medium.com/@geoffrey.signorato/case-study-create-a-parallax-effect-directly-on-img-tags-with-javascript-35b8daf81471) to have a better understanding). when overflow is set to true, the image will translate out of its natural flow.
### delay - *int*
When a delay is set, the translation of the image will slightly continue when the user stop scrolling. That gives a very nice effect.
### transition - *string*
The transition works closely with the delay setting. The transition will add any CSS effect to the delay setting.
### customContainer - *string or node*
In some cases, you want the parallax effects to be apply on a container that have its own scroll, and not apply the parallax effects via the document scroll.
## Methods
Destroy a simpleParallax instance:
```javascript
var images = document.querySelectorAll('img');
var instance = new simpleParallax(images);
instance.destroy();
```
## Examples
You can find some examples [here](https://simpleparallax.com/#examples).
## Compatibility
You can apply simpleParallax on picture tags/srcset images.
## Author
[Geoffrey Signorato](https://github.com/geosigno/)
## Contributing
Open an issue or a pull request to suggest changes or additions.

View File

@@ -0,0 +1,675 @@
/*!
* simpleParallax - simpleParallax is a simple JavaScript library that gives your website parallax animations on any images,
* @date: 07-12-2019 18:53:52,
* @version: 5.2.0,
* @link: https://simpleparallax.com/
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("simpleParallax", [], factory);
else if(typeof exports === 'object')
exports["simpleParallax"] = factory();
else
root["simpleParallax"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./src/helpers/viewport.js
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var Viewport =
/*#__PURE__*/
function () {
function Viewport() {
_classCallCheck(this, Viewport);
this.positions = {
top: 0,
bottom: 0,
height: 0
};
}
_createClass(Viewport, [{
key: "setViewportTop",
value: function setViewportTop(container) {
// if this is a custom container, user the scrollTop
this.positions.top = container ? container.scrollTop : window.pageYOffset;
return this.positions;
}
}, {
key: "setViewportBottom",
value: function setViewportBottom() {
this.positions.bottom = this.positions.top + this.positions.height;
return this.positions;
}
}, {
key: "setViewportAll",
value: function setViewportAll(container) {
// if this is a custom container, user the scrollTop
this.positions.top = container ? container.scrollTop : window.pageYOffset; // if this is a custom container, get the height from the custom container itself
this.positions.height = container ? container.clientHeight : document.documentElement.clientHeight;
this.positions.bottom = this.positions.top + this.positions.height;
return this.positions;
}
}]);
return Viewport;
}();
var viewport = new Viewport();
// CONCATENATED MODULE: ./src/helpers/convertToArray.js
// check wether the element is a Node List, a HTML Collection or an array
// return an array of nodes
var convertToArray = function convertToArray(elements) {
if (NodeList.prototype.isPrototypeOf(elements) || HTMLCollection.prototype.isPrototypeOf(elements)) return Array.from(elements);
if (typeof elements === 'string' || elements instanceof String) return document.querySelectorAll(elements);
return [elements];
};
/* harmony default export */ var helpers_convertToArray = (convertToArray);
// CONCATENATED MODULE: ./src/helpers/cssTransform.js
// Detect css transform
var cssTransform = function cssTransform() {
var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' ');
var transform;
var i = 0;
while (transform === undefined) {
transform = document.createElement('div').style[prefixes[i]] !== undefined ? prefixes[i] : undefined;
i += 1;
}
return transform;
};
/* harmony default export */ var helpers_cssTransform = (cssTransform());
// CONCATENATED MODULE: ./src/helpers/isImageLoaded.js
// check if image is fully loaded
var isImageLoaded = function isImageLoaded(image) {
// check if image is set as the parameter
if (!image) {
return false;
} // check if image has been 100% loaded
if (!image.complete) {
return false;
} // check if the image is displayed
if (typeof image.naturalWidth !== 'undefined' && image.naturalWidth === 0) {
return false;
}
return true;
};
/* harmony default export */ var helpers_isImageLoaded = (isImageLoaded);
// CONCATENATED MODULE: ./src/instances/parallax.js
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function parallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function parallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function parallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) parallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) parallax_defineProperties(Constructor, staticProps); return Constructor; }
var parallax_ParallaxInstance =
/*#__PURE__*/
function () {
function ParallaxInstance(element, options) {
parallax_classCallCheck(this, ParallaxInstance);
// set the element & settings
this.element = element;
this.elementContainer = element;
this.settings = options;
this.isVisible = true;
this.isInit = false;
this.oldTranslateValue = -1;
this.init = this.init.bind(this); // check if images has not been loaded yet
if (helpers_isImageLoaded(element)) {
this.init();
} else {
this.element.addEventListener('load', this.init);
}
}
parallax_createClass(ParallaxInstance, [{
key: "init",
value: function init() {
var _this = this;
// for some reason, <picture> are init an infinite time on windows OS
if (this.isInit) return; // check if element has not been already initialized with simpleParallax
if (this.element.closest('.simpleParallax')) return;
if (this.settings.overflow === false) {
// if overflow option is set to false
// wrap the element into a div to apply overflow
this.wrapElement(this.element);
} // apply the transform style on the image
this.setTransformCSS(); // get the current element offset
this.getElementOffset(); // init the Intesection Observer
this.intersectionObserver(); // get its translated value
this.getTranslateValue(); // apply its translation even if not visible for the first init
this.animate(); // if a delay has been set
if (this.settings.delay > 0) {
// apply a timeout to avoid buggy effect
setTimeout(function () {
// apply the transition style on the image
_this.setTransitionCSS();
}, 10);
} // for some reason, <picture> are init an infinite time on windows OS
this.isInit = true;
} // if overflow option is set to false
// wrap the element into a .simpleParallax div and apply overflow hidden to hide the image excedant (result of the scale)
}, {
key: "wrapElement",
value: function wrapElement() {
// check is current image is in a <picture> tag
var elementToWrap = this.element.closest('picture') || this.element; // create a .simpleParallax wrapper container
var wrapper = document.createElement('div');
wrapper.classList.add('simpleParallax');
wrapper.style.overflow = 'hidden'; // append the image inside the new wrapper
elementToWrap.parentNode.insertBefore(wrapper, elementToWrap);
wrapper.appendChild(elementToWrap);
this.elementContainer = wrapper;
} // unwrap the element from .simpleParallax wrapper container
}, {
key: "unWrapElement",
value: function unWrapElement() {
var wrapper = this.elementContainer;
wrapper.replaceWith.apply(wrapper, _toConsumableArray(wrapper.childNodes));
} // apply default style on element
}, {
key: "setTransformCSS",
value: function setTransformCSS() {
if (this.settings.overflow === false) {
// if overflow option is set to false
// add scale style so the image can be translated without getting out of its container
this.element.style[helpers_cssTransform] = "scale(".concat(this.settings.scale, ")");
} // add will-change CSS property to improve perfomance
this.element.style.willChange = 'transform';
} // apply the transition effet
}, {
key: "setTransitionCSS",
value: function setTransitionCSS() {
// add transition option
this.element.style.transition = "transform ".concat(this.settings.delay, "s ").concat(this.settings.transition);
} // remove style of the element
}, {
key: "unSetStyle",
value: function unSetStyle() {
// remove will change inline style
this.element.style.willChange = '';
this.element.style[helpers_cssTransform] = '';
this.element.style.transition = '';
} // get the current element offset
}, {
key: "getElementOffset",
value: function getElementOffset() {
// get position of the element
var positions = this.elementContainer.getBoundingClientRect(); // get height
this.elementHeight = positions.height; // get offset top
this.elementTop = positions.top + viewport.positions.top; // if there is a custom container
if (this.settings.customContainer) {
// we need to do some calculation to get the position from the parent rather than the viewport
var parentPositions = this.settings.customContainer.getBoundingClientRect();
this.elementTop = positions.top - parentPositions.top + viewport.positions.top;
} // get offset bottom
this.elementBottom = this.elementHeight + this.elementTop;
} // build the Threshold array to cater change for every pixel scrolled
}, {
key: "buildThresholdList",
value: function buildThresholdList() {
var thresholds = [];
for (var i = 1.0; i <= this.elementHeight; i++) {
var ratio = i / this.elementHeight;
thresholds.push(ratio);
}
return thresholds;
} // create the Intersection Observer
}, {
key: "intersectionObserver",
value: function intersectionObserver() {
var options = {
root: null,
threshold: this.buildThresholdList()
};
this.observer = new IntersectionObserver(this.intersectionObserverCallback.bind(this), options);
this.observer.observe(this.element);
} // Intersection Observer Callback to set the element at visible state or not
}, {
key: "intersectionObserverCallback",
value: function intersectionObserverCallback(entries) {
for (var i = entries.length - 1; i >= 0; i--) {
if (entries[i].isIntersecting) {
this.isVisible = true;
} else {
this.isVisible = false;
}
}
} // check if the current element is visible in the Viewport
// for browser that not support Intersection Observer API
}, {
key: "checkIfVisible",
value: function checkIfVisible() {
return this.elementBottom > viewport.positions.top && this.elementTop < viewport.positions.bottom;
} // calculate the range between image will be translated
}, {
key: "getRangeMax",
value: function getRangeMax() {
// get the real height of the image without scale
var elementImageHeight = this.element.clientHeight; // range is calculate with the image height by the scale
this.rangeMax = elementImageHeight * this.settings.scale - elementImageHeight;
} // get the percentage and the translate value to apply on the element
}, {
key: "getTranslateValue",
value: function getTranslateValue() {
// calculate the % position of the element comparing to the viewport
// rounding percentage to a 1 number float to avoid unn unnecessary calculation
var percentage = ((viewport.positions.bottom - this.elementTop) / ((viewport.positions.height + this.elementHeight) / 100)).toFixed(1); // sometime the percentage exceeds 100 or goes below 0
percentage = Math.min(100, Math.max(0, percentage)); // sometime the same percentage is returned
// if so we don't do aything
if (this.oldPercentage === percentage) {
return false;
} // if not range max is set, recalculate it
if (!this.rangeMax) {
this.getRangeMax();
} // transform this % into the max range of the element
// rounding translateValue to a non float int - as minimum pixel for browser to render is 1 (no 0.5)
this.translateValue = (percentage / 100 * this.rangeMax - this.rangeMax / 2).toFixed(0); // sometime the same translate value is returned
// if so we don't do aything
if (this.oldTranslateValue === this.translateValue) {
return false;
} // store the current percentage
this.oldPercentage = percentage;
this.oldTranslateValue = this.translateValue;
return true;
} // animate the image
}, {
key: "animate",
value: function animate() {
var translateValueY = 0;
var translateValueX = 0;
var inlineCss;
if (this.settings.orientation.includes('left') || this.settings.orientation.includes('right')) {
// if orientation option is left or right
// use horizontal axe - X axe
translateValueX = "".concat(this.settings.orientation.includes('left') ? this.translateValue * -1 : this.translateValue, "px");
}
if (this.settings.orientation.includes('up') || this.settings.orientation.includes('down')) {
// if orientation option is up or down
// use vertical axe - Y axe
translateValueY = "".concat(this.settings.orientation.includes('up') ? this.translateValue * -1 : this.translateValue, "px");
} // set style to apply to the element
if (this.settings.overflow === false) {
// if overflow option is set to false
// add the scale style
inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0) scale(").concat(this.settings.scale, ")");
} else {
inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0)");
} // add style on the element using the adequate CSS transform
this.element.style[helpers_cssTransform] = inlineCss;
}
}]);
return ParallaxInstance;
}();
/* harmony default export */ var parallax = (parallax_ParallaxInstance);
// CONCATENATED MODULE: ./src/simpleParallax.js
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return simpleParallax_SimpleParallax; });
function simpleParallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function simpleParallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function simpleParallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) simpleParallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) simpleParallax_defineProperties(Constructor, staticProps); return Constructor; }
var intersectionObserverAvailable = true;
var isInit = false;
var instances = [];
var instancesLength;
var frameID;
var resizeID;
var simpleParallax_SimpleParallax =
/*#__PURE__*/
function () {
function SimpleParallax(elements, options) {
simpleParallax_classCallCheck(this, SimpleParallax);
if (!elements) return;
this.elements = helpers_convertToArray(elements);
this.defaults = {
delay: 0.4,
orientation: 'up',
scale: 1.3,
overflow: false,
transition: 'cubic-bezier(0,0,0,1)',
customContainer: false
};
this.settings = Object.assign(this.defaults, options); // check if the browser handle the Intersection Observer API
if (!('IntersectionObserver' in window)) intersectionObserverAvailable = false;
if (this.settings.customContainer) {
console.log(helpers_convertToArray(this.settings.customContainer)[0]);
this.customContainer = helpers_convertToArray(this.settings.customContainer)[0];
}
this.lastPosition = -1;
this.resizeIsDone = this.resizeIsDone.bind(this);
this.handleResize = this.handleResize.bind(this);
this.proceedRequestAnimationFrame = this.proceedRequestAnimationFrame.bind(this);
this.init();
}
simpleParallax_createClass(SimpleParallax, [{
key: "init",
value: function init() {
viewport.setViewportAll(this.customContainer);
for (var i = this.elements.length - 1; i >= 0; i--) {
var instance = new parallax(this.elements[i], this.settings);
instances.push(instance);
} // update the instance length
instancesLength = instances.length; // only if this is the first simpleParallax init
if (!isInit) {
// init the frame
this.proceedRequestAnimationFrame();
window.addEventListener('resize', this.resizeIsDone);
isInit = true;
}
} // wait for resize to be completely done
}, {
key: "resizeIsDone",
value: function resizeIsDone() {
clearTimeout(resizeID);
resizeID = setTimeout(this.handleResize, 500);
} // handle the resize process, some coordonates need to be re-calculate
}, {
key: "handleResize",
value: function handleResize() {
// re-get all the viewport positions
viewport.setViewportAll(this.customContainer);
for (var i = instancesLength - 1; i >= 0; i--) {
// re-get the current element offset
instances[i].getElementOffset(); // re-get the range if the current element
instances[i].getRangeMax();
} // force the request animation frame to fired
this.lastPosition = -1;
} // animation frame
}, {
key: "proceedRequestAnimationFrame",
value: function proceedRequestAnimationFrame() {
// get the offset top of the viewport
viewport.setViewportTop(this.customContainer);
if (this.lastPosition === viewport.positions.top) {
// if last position if the same than the curent one
// callback the animationFrame and exit the current loop
frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame);
return;
} // get the offset bottom of the viewport
viewport.setViewportBottom(); // proceed with the current element
for (var i = instancesLength - 1; i >= 0; i--) {
this.proceedElement(instances[i]);
} // callback the animationFrame
frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); // store the last position
this.lastPosition = viewport.positions.top;
} // proceed the element
}, {
key: "proceedElement",
value: function proceedElement(instance) {
var isVisible = false; // is not support for Intersection Observer API
// or if this is a custom container
// use old function to check if element visible
if (!intersectionObserverAvailable || this.customContainer) {
isVisible = instance.checkIfVisible(); // if support
// use response from Intersection Observer API Callback
} else {
isVisible = instance.isVisible;
} // if element not visible, stop it
if (!isVisible) return; // if percentage is equal to the last one, no need to continue
if (!instance.getTranslateValue()) {
return;
} // animate the image
instance.animate();
}
}, {
key: "destroy",
value: function destroy() {
var _this = this;
var instancesToDestroy = []; // remove all instances that need to be destroyed from the instances array
instances = instances.filter(function (instance) {
if (_this.elements.includes(instance.element)) {
// push instance that need to be destroyed into instancesToDestroy
instancesToDestroy.push(instance);
return false;
}
return instance;
});
for (var i = instancesToDestroy.length - 1; i >= 0; i--) {
// unset style
instancesToDestroy[i].unSetStyle();
if (this.settings.overflow === false) {
// if overflow option is set to false
// unwrap the element from .simpleParallax wrapper container
instancesToDestroy[i].unWrapElement();
}
} // update the instance length var
instancesLength = instances.length; // if no instances left, remove the raf and resize event = simpleParallax fully destroyed
if (!instancesLength) {
// cancel the animation frame
window.cancelAnimationFrame(frameID); // detach the resize event
window.removeEventListener('resize', this.handleResize);
}
}
}]);
return SimpleParallax;
}();
/***/ })
/******/ ])["default"];
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
declare module 'simple-parallax-js' {
interface IParallaxSettings {
orientation?: 'up' | 'down' | 'left' | 'right';
scale?: number;
overflow?: boolean;
delay?: number;
transition?: string;
breakpoint?: number;
}
export default class SimpleParallax {
constructor(images: Element | Element[], settings?: IParallaxSettings);
public destroy: () => void;
}
}

Some files were not shown because too many files have changed in this diff Show More