CopierYoutube DApp Model

This commit is contained in:
fred 2023-06-30 21:37:14 +02:00
parent f0f64bd180
commit 905d7f132a
23 changed files with 2306 additions and 0 deletions

View File

@ -0,0 +1 @@
HELLO THERE

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,278 @@
<!DOCTYPE html>
<html>
<head>
<title>_G1VOEU_ : _PLAYER_ : http://astroport.localhost:1234</title>
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/favicon.ico">
<link rel="stylesheet" href="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/demo.css">
<link rel="stylesheet" href="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/jquery-ui.min.css">
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/requestanimationframe.polyfill.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/instascan.min.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/html5-qrcode.min.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/jquery-ui.0.min.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/sphere-hacked.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/jquery.earth-3d.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/world.js"></script>
<script type="text/javascript" src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/index_fichiers/demo.js"></script>
<script src="http://127.0.0.1:8080/ipfs/Qmae5v9zydax9u6C9ceDijURu5PYdd5avmv4NkenCw7RFv/astro.js"></script>
<script type="text/javascript">
examples['simple_mars'] = function() {
$('#sphere').earth3d({
texture: 'http://127.0.0.1:8080/ipfs/QmNNSAJyzVSF2m16dReYgmqmiRkKa5HMKvFUgwhbRzTYto/mars1024x1024.jpg', // texture used by G1Wish planet
dragElement: $('#locations') // where do we catch the mouse drag
});
};
</script>
<style>
body {
padding: 0;
margin: 0;
font-family: sans-serif;
}
.slidecontainer {
width: 80%;
margin: 0 auto;
text-align: center;
}
.gif-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.gif-container img {
margin: 10px;
max-width: 200px;
}
.slider {
width: 100%;
text-align: center;
}
.slider #prev {
float: left;
font-size: 40px;
}
.slider #next {
float: right;
font-size: 40px;
}
#glow-shadows.earth {
background: url(http://127.0.0.1:8080/ipfs/QmTVspfoaNL1BK2CR1vVNrEnwo4PfUjwdQxEt57mGJjsLX/earth-glow-shadows.png);
}
#glow-shadows.mars {
background: url(http://127.0.0.1:8080/ipfs/QmTVspfoaNL1BK2CR1vVNrEnwo4PfUjwdQxEt57mGJjsLX/mars-glow-shadows.png);
}
.flight {
position: absolute;
width: 24px;
height: 25px;
left: 10px;
top: 10px;
background: url(http://127.0.0.1:8080/ipfs/QmTVspfoaNL1BK2CR1vVNrEnwo4PfUjwdQxEt57mGJjsLX/plain.png);
background-size: 100% 100%;
margin-left: -12px;
margin-top: -12.5px;
cursor: pointer;
}
#yellow {
background: black;
position: absolute;
top: 2%;
right: 4%;
width: 55%;
}
#green {
background: black;
position: absolute;
top: 12%;
right: 5%;
width: 45%;
}
#ainfo {
background: grey;
position: absolute;
top: 1%;
right: 1%;
}
</style>
</head>
<body>
<button id="ainfo" onclick="javascript:var x = document.getElementById('yellow'); if (x.style.visibility === 'hidden') {x.style.visibility = 'visible';} else {x.style.visibility = 'hidden';}">0/1</button>
<div id="yellow" >
<iframe name="aframe" id="aframe" src="http://127.0.0.1:8080/ipns/_ASTRONAUTENS_" width="100%" height="640px"></iframe>
</div>
<div id="demo">
<div id="description">
<a href="javascript:FriendWithMe()"><img title="Connect with Me" width=20% src="http://127.0.0.1:8080/ipfs/QmYdWBx32dP14XcbXF7hhtDq7Uu6jFmDaRnuL5t7ARPYkW/l0g0.png" alt="Link in Le Claude"></a>
<div id="countdown"></div>
<h2>G1_G1VOEU_ _PLAYER_</h2>
<div class="subtitle">A Friendly Planet of Friends</div>
<div class="slidecontainer">
<div class="gif-container">
<!-- gifs -->
</div>
<div class="slider">
<a href="#" id="prev">&lt;</a>
<a href="#" id="next">&gt;</a>
</div>
</div>
<script>
function FriendWithMe() {
let cookies = document.cookie;
console.log(cookies);
let salt = prompt("Secret 1");
let pepper = prompt("Secret 2");
let resultUt = 'http://astroport.localhost:1234/?salt=' + salt + '&pepper=' + pepper + '&friend=_G1PUB_';
console.log(resultUt)
homeAstroportStation( resultUt,'aframe', 4000)
}
const gifContainer = document.querySelector('.gif-container');
const prevBtn = document.querySelector('#prev');
const nextBtn = document.querySelector('#next');
const pageSize = 2;
let pageNumber = 0;
let gifs = [];
let urls = [];
let titles = [];
let durees = [];
// Récupérer les données
fetch('http://127.0.0.1:8080_VOEUNS_/__PLAYER_.tiddlers.json')
.then(res => res.json())
.then(data => {
// Extraire les gifanime
gifs = data.map(tiddler => tiddler.gifanime);
urls = data.map(tiddler => tiddler.ipfs);
titles = data.map(tiddler => tiddler.title);
durees = data.map(tiddler => tiddler.duree);
// Afficher les gifs
showGifs();
});
// Afficher les images
function showGifs() {
let start = pageNumber * pageSize;
let end = start + pageSize;
let pageGifs = gifs.slice(start, end);
let pageUrls = urls.slice(start, end);
let pageTitles = titles.slice(start, end);
let pageDurees = durees.slice(start, end);
let output = '';
// Générer le HTML
// <a target="aframe" href="http://127.0.0.1:8080${pageUrls[i]}">
// <a target="aframe" href="http://127.0.0.1:8080/ipns/_ASTRONAUTENS_#${pageTitles[i]}">
pageGifs.forEach((gif, i) => {
output += `
<a target="aframe" href="http://127.0.0.1:8080/ipns/_ASTRONAUTENS_#${pageTitles[i]}">
<img src="http://127.0.0.1:8080${gif}" title="${pageDurees[i]} - ${pageTitles[i]}" />
</a>
`;
});
// Ajouter le HTML
gifContainer.innerHTML = output;
}
// Écouter les évènements
prevBtn.addEventListener('click', () => {
pageNumber--;
showGifs();
});
nextBtn.addEventListener('click', () => {
pageNumber++;
showGifs();
});
</script>
<br><br>
<h3>_PLAYER_ </h3>
<p>
<a target="_PLAYER_" href="http://127.0.0.1:8080/ipns/_ASTRONAUTENS_">
<img src="http://127.0.0.1:8080/ipfs/QmWUpjGFuF7NhpXgkrCmx8Tbu4xjcFpKhE7Bsvt6HeKYxu/g1ticket_qrcode.png" width=300>
</a>
</p>
<h2>:⚡:~ <a href="https://cesium.app">Cesium </a> ~:📱: _____ </h2>
<p>
<div id="astropub"> 🏡 : <a target="gchange" href="https://www.gchange.fr/#/app/user/_G1PUB_/">_G1PUB_</a></div>
</p>
</div>
<div id="showoff">
<div id="container">
<br><br>
<br><br>
<canvas id="sphere" width="400" height="400"></canvas>
<div id="glow-shadows" class="earth"></div>
<canvas id="flights" width="400" height="400"></canvas>
<div id="locations"></div>
</div>
<p><a target="_PLAYER_" href="http://127.0.0.1:8080/ipns/_ASTRONAUTENS_">TW♥BOX of "_PLAYER_"</a></p>
<p>
<br>
<br> 👍 IPFS DATA STORAGE 👍 </p>
<p>Powered by <a href="https://github.com/papiche/Astroport.ONE">Astroport.ONE</a></p>
<p>/ <a href="https://opencollective.com/monnaie-libre/projects/stiits">STI</a> / <a href="https://opencollective.com/monnaie-libre/projects/coeurbox">La♥BOX</a> /
</div>
</div>
<div class="choose_example">
Choose Planet: <select id="example">
<!--
<option value="simple">Simple earth</option>
<option value="simple_tilted">Simple tilted earth</option>
-->
<option value="simple_mars">Simple mars</option>
<!--
<option value="flights">Earth with locations and flights</option>
-->
<option value="locations" selected >Ŋ1 Friends</option>
</select>
</div>
<div class="code">
<a href="#" onclick="$('#example_code').show(); $(this).hide().siblings('a').show(); return false;">Show code</a>
<a href="#" style="display: none;" onclick="$('#example_code').hide(); $(this).hide().siblings('a').show(); return false;">Hide code</a>
<textarea id="example_code" onclick="this.focus();this.select();"></textarea>
</div>
</body></html>

View File

@ -0,0 +1,129 @@
body {
background: black;
margin: 0;
padding: 0;
color: #DDD;
text-align: center;
padding-bottom: 20px;
}
h1 {
margin-top: 10px;
font-size: 40px;
margin-bottom: 10px;
}
.subtitle {
font-size: 20px;
margin-bottom: 20px;
color: #777;
}
a {
color: white;
}
#demo {
overflow: hidden;
}
#description {
text-align: left;
float: left;
width: 49%;
max-width: 500px;
padding-top: 50px;
padding-left: 20px;
}
#showoff {
float: left;
width: 49%;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#container {
position: relative;
display: inline-block;
width: 400px;
height: 400px;
}
#sphere, #flights, #glow-shadows, #locations, #drag {
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 400px;
}
#glow-shadows {
top: 1px;
left: 1px;
}
.location {
position: absolute;
width: 10px;
height: 10px;
left: 10px;
top: 10px;
border: 2px solid white;
margin-left: -5px;
margin-top: -5px;
border-radius: 50%;
cursor: pointer;
}
.location:hover {
width: 15px;
height: 15px;
margin-left: -7.5px;
margin-top: -7.5px;
}
.flight:hover {
width: 36px;
height: 37.5px;
margin-left: -18px;
margin-top: -18.75px;
}
.choose_example {
width: 35%;
margin-left: 32.5%;
}
#example_code {
width: 100%;
height: 200px;
background-color: black;
color: white;
border: 0px;
resize: none;
display: none;
}
.code {
margin-top: 10px;
}
.social {
display: inline-block;
}
.social.twitter {
vertical-align: -3px;
}
.social.google {
vertical-align: -7px;
}

View File

@ -0,0 +1,39 @@
function selectExample(example) {
$('#sphere').earth3d('destroy');
$('#sphere').replaceWith($('<canvas id="sphere" width="400" height="400"></canvas>'));
$('.location').remove();
//~ $('.flight').remove();
//~ $('#flights')[0].getContext('2d').clearRect(0, 0, 400, 400);
if (example == 'simple_mars') {
$('#glow-shadows').removeClass('earth').addClass('mars');
} else {
$('#glow-shadows').removeClass('mars').addClass('earth');
}
var code = examples[example].toString();
code = code.substring(14);
code = code.substring(0, code.length - 2);
var lines = code.split("\n");
for (var i = 0; i < lines.length; i++) {
lines[i] = lines[i].substring(2);
}
code = lines.join("\n");
$('#example_code').val(code);
examples[example]();
}
$(document).ready(function() {
selectExample('locations');
$('#example').change(function() {
selectExample($(this).val());
});
});
function addPath() {
$('#sphere').earth3d('changePaths', {path2: {
origin: 'obj1',
destination: 'obj3'
}});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,851 @@
/*
jquery.earth3d.js
jQuery ui plugin that allow you to draw a beautiful 3d spinning earth on canvas
Author: Sebastien Drouyer
Based on the amazing sphere.js plug of Sam Hasler
Licensed under the MIT license (MIT-LICENSE.txt)
http://sdrdis.github.com/jquery.earth-3d/
Depends:
ui.core.js
Options:
* texture: texture map used by the planet
* sphere: rotation and size of the planet
* defaultSpeed: default spinning speed of the planet
* backToDefaultTime: time (in ms) to return by to default speed when planet is dragged
* locations: locations to display on the planet:
* Each position must have a key, an alpha and delta position (or x and y if you want to display a static location).
Any additional key can be reached via callbacks functions
Example:
{
obj1: {
alpha: Math.PI / 4,
delta: 0,
name: 'location 1'
}
}
* paths: paths and flights to display over the planet:
Each path must have a key, an origin and a destination. The values are the location's key.
You can, if you want to, define flights on these paths.
Each flight has a key, a destination (the location's key) and a position.
The position is the progress a fleet has made on its path.
Any additional key can be reach via callbacks functions.
Example:
{
path: {
origin: 'obj1',
destination: 'obj2',
flights: {
flight: {
position: 0.25,
destination: 'obj2',
name: 'Flight 1'
},
flight2: {
position: 0.25,
destination: 'obj1',
name: 'Flight 2'
}
}
}
}
* flightsCanvas: Dom element which is a canvas and where the flights and paths are drawn
* dragElement: Dom element where we catch the mouse drag
* locationsElement: Dom elements where the locations are drawn
* flightsCanvasPosition: position of the flight canvas (can be use if you have some gap between your planet and your flights
* pixelRadiusMultiplier: (TEMPORARY) used by the getSphereRadiusInPixel (see the functions)
* onInitLocation: callback function which allows you to define what to do when the locations are initialized
* Parameters:
* location: location (coming from locations option)
* widget: earth3d widget object
* onShowLocation: callback function which allows you to define what to do when a location becomes visible (was behind the planet and is now in front of it)
* Parameters:
* location: location (coming from locations option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onRefreshLocation: callback function which allows you to define what to do when a location is refreshed (it moves)
* Parameters:
* location: location (coming from locations option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onHideLocation: callback function which allows you to define what to do when a location becomes invisible (was in front of the planet and is now behind it)
* Parameters:
* location: location (coming from locations option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onInitFlight: callback function which allows you to define what to do when the flights are initialized
* Parameters:
* flight: flight (coming from flights option)
* widget: earth3d widget object
* onShowFlight: callback function which allows you to define what to do when a flight becomes visible (was behind the planet and is now in front of it)
* Parameters:
* flight: flight (coming from flights option)
* widget: earth3d widget object
* onRefreshFlight: callback function which allows you to define what to do when a flight is refreshed (it moves)
* Parameters:
* flight: flight (coming from flights option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onHideFlight: callback function which allows you to define what to do when a flight becomes invisible (was in front of the planet and is now behind it)
* Parameters:
* flight: flight (coming from flights option)
* widget: earth3d widget object
Functions
* getSphereRadiusInPixel: function which allows you to get the sphere radius in pixel
/!| WARNING: this function needs to be refactored, since I didn't find out (my maths courses are far away) how to
get the exact value. I did a basic linear regression, but it is not exact, and you will have to change the pixelRadiusMultiplier
option to get the correct value
* destroy: use this function when you want to destroy the object. It will throw a cancel animation frame, so the
CPU won't be used anymore.
* changePaths: use this function when you want to update paths and flights (options on widget)
it will add the callback functions support
*/
var earth3d;
(function($) {
$.widget('ui.earth3d', {
options: {
texture: '/ipfs/QmRpS3HcsawVGL6D3ZjJwP5HBFivydb4mcMNVykKem3jai/earth1024x1024.jpg',
sphere: {
tilt: 0,
turn: 0,
r: 10
},
defaultSpeed: 20,
backToDefaultTime: 4000,
locations: {
},
paths: {
},
flightsCanvas: null,
dragElement: null,
locationsElement: null,
flightsCanvasPosition: {
x: 0,
y: 0
},
tiling: {horizontal: 1, vertical: 1},
pixelRadiusMultiplier: 0.97,
onInitLocation: function(location, widget) {
var $elem = $('<div class="location"></div>');
$elem.appendTo(widget.options.locationsElement);
$elem.click(function() {
alert('Clicked on ' + location.name + ' : ' + location.link );
window.open( location.link, "AstroTab");
});
location.$element = $elem;
},
onShowLocation: function(location, x, y) {
location.$element.show();
},
onRefreshLocation: function(location, x, y) {
//console.log(x, y);
location.$element.css({
left: x,
top: y
});
},
onHideLocation: function(location, x, y) {
location.$element.hide();
},
onDeleteLocation: function(location) {
location.$element.remove();
},
onInitFlight: function(flight, widget) {
var $elem = $('<div class="flight"></div>');
$elem.appendTo(widget.options.locationsElement);
$elem.click(function() {
alert('Clicked on ' + flight.name);
});
flight.$element = $elem;
},
onShowFlight: function(flight) {
flight.$element.show();
},
onRefreshFlight: function(flight, x, y, angle, widget) {
flight.$element.css({
left: x,
top: y,
'-webkit-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)',
'-moz-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)',
'-o-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)'
});
},
onHideFlight: function(flight) {
flight.$element.hide();
},
onDeleteFlight: function(flight) {
flight.$element.remove();
}
},
earth: null,
posVar: 24 * 3600 * 1000,
lastMousePos: null,
lastSpeed: null,
lastTime: null,
lastTurnByTime: null,
textureWidth: null,
textureHeight: null,
obj: null,
flightsCtx: null,
renderAnimationFrameId: null,
mousePressed: null,
_create: function() {
earth3d = this;
var self = this;
this.obj = $('div');
if (this.options.flightsCanvas !== null) {
this.flightsCtx = this.options.flightsCanvas[0].getContext('2d');
}
createSphere(this.element[0], this.options.texture, function(earth, textureWidth, textureHeight) { self._onSphereCreated(earth, textureWidth, textureHeight); }, this.options.tiling);
if (this.options.dragElement !== null) {
this.options.dragElement
.bind('mousedown vmousedown', function(e) {
self._mouseDragStart(e);
self.mousePressed = true;
})
.bind('mouseup vmouseup', function(e) {
self._mouseDragStop(e);
self.mousePressed = false;
})
.bind('mousemove vmousemove', function(e){
if (self.mousePressed) {
self._mouseDrag(e);
}
});
}
this._initLocations();
this._initFlights();
},
_initLocations: function() {
for (var key in this.options.locations) {
var location = this.options.locations[key];
location.visible = true;
this.options.onInitLocation(location, this);
}
},
_initFlights: function() {
for (var key in this.options.paths) {
var path = this.options.paths[key];
for (var key in path.flights) {
path.flights[key].visible = true;
this.options.onInitFlight(path.flights[key], this);
}
}
},
getSphereRadiusInPixel: function() {
return this.earth.getRadius() / 2;
},
_onSphereCreated: function(earth, textureWidth, textureHeight) {
var self = this;
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.earth = earth;
this.earth.init(this.options.sphere);
this.earth.turnBy = function(time) { return self._turnBy(time); };
var renderAnimationFrame = function(/* time */ time) {
/* time ~= +new Date // the unix time */
earth.renderFrame(time);
self._renderAnimationFrame(time);
self.renderAnimationFrameId = window.requestAnimationFrame(renderAnimationFrame);
};
this.renderAnimationFrameId = window.requestAnimationFrame(renderAnimationFrame);
},
destroy: function() {
window.cancelAnimationFrame(this.renderAnimationFrameId);
},
_renderAnimationFrame: function(time) {
var ry=90+this.options.sphere.tilt;
var rz=180+this.options.sphere.turn;
var RY = (90-ry);
var RZ = (180-rz);
var RX = 0,RY,RZ;
var rx=RX*Math.PI/180;
var ry=RY*Math.PI/180;
var rz=RZ*Math.PI/180;
//console.log(rx, ry, rz);
var r = this.getSphereRadiusInPixel();
var center = {
x: this.element.width() / 2,
y: this.element.height() / 2
}
for (var key in this.options.locations) {
var location = this.options.locations[key];
if (typeof location.delta === 'undefined') {
location.flatPosition = {x: location.x, y: location.y};
this.options.onRefreshLocation(location, location.x, location.y, this);
continue;
}
/*
WARNING: calculation of alphaAngle and deltaAngle is not exact
I had to create the _calibrated functions to modify the deltaAngle to make the result look good on
a spinning planet without rotation. It will totally bug with rotation!
* */
var progression = (((this.posVar + this.textureWidth * location.delta / (2 * Math.PI)) % this.textureWidth) / this.textureWidth);
var alphaAngle = progression * 2 * Math.PI;
var deltaAngle = this._calibrated(progression, location.alpha) * 2 * Math.PI;
var objAlpha = ry + location.alpha - Math.sin(alphaAngle / 2) * 0.15 * (location.alpha - Math.PI / 2) / (Math.PI / 4);
var objDelta = rz + deltaAngle;
var a = this._orbitalTo3d(objAlpha, objDelta, r);
var flatPosition = this._orthographicProjection(a);
if (a.x < 0 && !location.visible) {
this.options.onShowLocation(location, flatPosition.x, flatPosition.y, this);
}
if (a.x > 0 && location.visible) {
this.options.onHideLocation(location, flatPosition.x, flatPosition.y, this);
}
this.options.onRefreshLocation(location, flatPosition.x, flatPosition.y, this);
location.visible = a.x < 0;
location.position = a;
location.flatPosition = flatPosition;
location.rAlpha = objAlpha;
location.rDelta = objDelta;
}
if (this.flightsCtx !== null) {
this.flightsCtx.clearRect(0, 0, this.options.flightsCanvas.width(), this.options.flightsCanvas.height());
for (var key in this.options.paths) {
this._drawPath(this.options.paths[key], center, r);
}
}
},
_line_circle_intersection: function(A, B, C, r) {
var d = {
x: B.x - A.x,
y: B.y - A.y
};
var f = {
x: A.x - C.x,
y: A.y - C.y
};
var a = this._dot(d, d);
var b = 2 * this._dot(f, d);
var c = this._dot(f, f) - r * r;
var discriminant = b * b - 4 * a * c;
if (discriminant < 0) {
return false;
} else {
discriminant = Math.sqrt(discriminant);
var t1 = (-b + discriminant) / (2 * a);
var t2 = (-b - discriminant) / (2 * a);
var sols = [];
if (t1 >= 0 && t1 <= 1) {
sols.push({
x:A.x + t1 * d.x,
y:A.y + t1 * d.y
});
}
if (t2 >= 0 && t2 <= 1) {
sols.push({
x:A.x + t2 * d.x,
y:A.y + t2 * d.y
});
}
return sols;
}
},
_dot: function(A, B) {
return A.x * B.x + A.y * B.y;
},
_drawPath: function(path, center, r) {
var originLocation = this.options.locations[path.origin];
var destinationLocation = this.options.locations[path.destination];
var dotSize = 50;
var spacing = 0.15;
if (typeof originLocation.delta === 'undefined' || typeof destinationLocation.delta === 'undefined') {
var pathVisible = originLocation.visible && destinationLocation.visible;
if (pathVisible) {
var flatDistance = this._distance(originLocation.flatPosition, destinationLocation.flatPosition);
var nb = flatDistance * 0.9 / 20;
// WARNING: we are drawing the paths on canvas, intensively using CPU. Could we gain by instead using SVG or the DOM ?
for (var i = 0; i < nb; i++) {
var fromFlatPosition = {
x: ((nb - i) / nb) * originLocation.flatPosition.x + (i / nb) * destinationLocation.flatPosition.x,
y: ((nb - i) / nb) * originLocation.flatPosition.y + (i / nb) * destinationLocation.flatPosition.y
};
var toFlatPosition = {
x: Math.max(((nb - (i + 1)) / nb), 0) * originLocation.flatPosition.x + Math.min(((i + 1) / nb), 1) * destinationLocation.flatPosition.x,
y: Math.max(((nb - (i + 1)) / nb), 0) * originLocation.flatPosition.y + Math.min(((i + 1) / nb), 1) * destinationLocation.flatPosition.y
};
var diff = {
x: fromFlatPosition.x - toFlatPosition.x,
y: fromFlatPosition.y - toFlatPosition.y,
z: fromFlatPosition.z - toFlatPosition.z
};
fromFlatPosition.x -= diff.x * spacing;
fromFlatPosition.y -= diff.y * spacing;
fromFlatPosition.z -= diff.z * spacing;
toFlatPosition.x += diff.x * spacing;
toFlatPosition.y += diff.y * spacing;
toFlatPosition.z += diff.z * spacing;
this.flightsCtx.lineWidth = 3;
this.flightsCtx.beginPath();
this.flightsCtx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
this.flightsCtx.moveTo(fromFlatPosition.x + this.options.flightsCanvasPosition.x, fromFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.lineTo(toFlatPosition.x + this.options.flightsCanvasPosition.x, toFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.stroke();
}
}
for (var key in path.flights) {
var flight = path.flights[key];
var position = flight.destination == path.destination ? flight.position : (1 - flight.position);
var flightFlatPosition = {
x: (1 - position) * originLocation.flatPosition.x + position * destinationLocation.flatPosition.x,
y: (1 - position) * originLocation.flatPosition.y + position * destinationLocation.flatPosition.y
};
if (!flight.visible && pathVisible) {
this.options.onShowFlight(flight, this);
flight.visible = true;
}
if (flight.visible && !pathVisible) {
this.options.onHideFlight(flight, this);
flight.visible = false;
}
var angle = Math.atan2(destinationLocation.flatPosition.y - originLocation.flatPosition.y, destinationLocation.flatPosition.x - originLocation.flatPosition.x) + (flight.destination == path.destination ? 0 : Math.PI);
//console.log(flightAheadFlatPosition.y - flightFlatPosition.y);
this.options.onRefreshFlight(flight, flightFlatPosition.x, flightFlatPosition.y, angle, this);
}
return;
}
var locationsDistance = this._distance(originLocation.position, destinationLocation.position);
var middlePosition = {
x: 0,
y: 0,
z: 0
};
var radius = this._distance(originLocation.position, middlePosition);
var originP = {
delta: Math.atan2((originLocation.position.y - middlePosition.y), (originLocation.position.x - middlePosition.x)),
alpha: Math.acos((originLocation.position.z - middlePosition.z) / radius)
};
var destinationP = {
delta: Math.atan2((destinationLocation.position.y - middlePosition.y), (destinationLocation.position.x - middlePosition.x)),
alpha: Math.acos((destinationLocation.position.z - middlePosition.z) / radius)
};
if (Math.abs(originP.delta - destinationP.delta) > Math.PI) {
if ((originP.delta - destinationP.delta) > Math.PI) {
originP.delta -= 2 * Math.PI;
} else {
originP.delta += 2 * Math.PI;
}
}
if (path.sens) {
if (((originP.delta - destinationP.delta) > 0 ? 1 : -1) != path.sens) {
if (Math.abs(originP.delta - destinationP.delta) > Math.PI / 2) {
originP.delta += path.sens * 2 * Math.PI;
}
}
} else {
path.sens = (originP.delta - destinationP.delta) > 0 ? 1 : -1;
}
if (!path.nb) {
path.nb = Math.round(((locationsDistance / (2 * r)) * Math.PI * 2 * r + (1 - (locationsDistance / (2 * r))) * locationsDistance) / dotSize);
}
var nb = path.nb;
var maxDistance = 1.2;
for (var i = 0; i < nb; i++) {
var fromP = {
alpha: ((nb - i) / nb) * originP.alpha + (i / nb) * destinationP.alpha,
delta: ((nb - i) / nb) * originP.delta + (i / nb) * destinationP.delta
};
var toP = {
alpha: ((nb - 1 - i) / nb) * originP.alpha + ((i + 1) / nb) * destinationP.alpha,
delta: ((nb - 1 - i) / nb) * originP.delta + ((i + 1) / nb) * destinationP.delta
};
//console.log(i, fromP.alpha, fromP.delta, toP.alpha, toP.delta);
var fromPosition = this._orbitalTo3d(fromP.alpha, fromP.delta, -(Math.sin(Math.PI * i / nb) * (maxDistance - 1) + 1) * radius);
var toPosition = this._orbitalTo3d(toP.alpha, toP.delta, -(Math.sin(Math.PI * (i + 1) / nb) * (maxDistance - 1) + 1) * radius);
var diff = {
x: fromPosition.x - toPosition.x,
y: fromPosition.y - toPosition.y,
z: fromPosition.z - toPosition.z
};
fromPosition.x -= diff.x * spacing;
fromPosition.y -= diff.y * spacing;
fromPosition.z -= diff.z * spacing;
toPosition.x += diff.x * spacing;
toPosition.y += diff.y * spacing;
toPosition.z += diff.z * spacing;
fromPosition.x += middlePosition.x;
fromPosition.y += middlePosition.y;
fromPosition.z += middlePosition.z;
toPosition.x += middlePosition.x;
toPosition.y += middlePosition.y;
toPosition.z += middlePosition.z;
var fromFlatPosition = this._orthographicProjection(fromPosition);
var toFlatPosition = this._orthographicProjection(toPosition);
var fromDistanceCenter = this._distance(fromFlatPosition, center);
var toDistanceCenter = this._distance(toFlatPosition, center);
var fromVisible = true;
var toVisible = true;
if (fromPosition.x > 0) {
if (fromDistanceCenter <= r) {
fromVisible = false;
}
}
if (toPosition.x > 0) {
if (toDistanceCenter <= r) {
toVisible = false;
}
}
//console.log(i, fromVisible, toVisible);
if (!fromVisible && !toVisible) {
continue;
}
if (!fromVisible) {
var intersection = this._line_circle_intersection(fromFlatPosition, toFlatPosition, center, r);
if (intersection.length == 0) {
continue;
}
fromFlatPosition = intersection[0];
}
if (!toVisible) {
var intersection = this._line_circle_intersection(fromFlatPosition, toFlatPosition, center, r);
if (intersection.length == 0) {
continue;
}
toFlatPosition = intersection[0];
}
this.flightsCtx.lineWidth = 3;
this.flightsCtx.beginPath();
this.flightsCtx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
this.flightsCtx.moveTo(fromFlatPosition.x + this.options.flightsCanvasPosition.x, fromFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.lineTo(toFlatPosition.x + this.options.flightsCanvasPosition.x, toFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.stroke();
}
for (var key in path.flights) {
var flight = path.flights[key];
var position = flight.destination == path.destination ? flight.position : (1 - flight.position);
var positionAhead = flight.destination == path.destination ? (flight.position + 0.01) : (1 - (flight.position + 0.01));
var flightP = {
alpha: (1 - position) * originP.alpha + position * destinationP.alpha,
delta: (1 - position) * originP.delta + position * destinationP.delta
};
var flightAheadP = {
alpha: (1 - positionAhead) * originP.alpha + positionAhead * destinationP.alpha,
delta: (1 - positionAhead) * originP.delta + positionAhead * destinationP.delta
};
var flightPosition = this._orbitalTo3d(flightP.alpha, flightP.delta, -(Math.sin(Math.PI * position) * (maxDistance - 1) + 1) * radius);
var flightAheadPosition = this._orbitalTo3d(flightAheadP.alpha, flightAheadP.delta, -(Math.sin(Math.PI * positionAhead) * (maxDistance - 1) + 1) * radius);
flightPosition.x += middlePosition.x;
flightPosition.y += middlePosition.y;
flightPosition.z += middlePosition.z;
flightAheadPosition.x += middlePosition.x;
flightAheadPosition.y += middlePosition.y;
flightAheadPosition.z += middlePosition.z;
var flightFlatPosition = this._orthographicProjection(flightPosition);
var flightAheadFlatPosition = this._orthographicProjection(flightAheadPosition);
var flightDistanceCenter = this._distance(flightFlatPosition, center);
if (!flight.visible && (flightPosition.x < 0 || flightDistanceCenter > r)) {
this.options.onShowFlight(flight, this);
flight.visible = true;
}
if (flight.visible && (flightPosition.x > 0 && flightDistanceCenter < r)) {
this.options.onHideFlight(flight, this);
flight.visible = false;
}
var angle = Math.atan2(flightAheadFlatPosition.y - flightFlatPosition.y, flightAheadFlatPosition.x - flightFlatPosition.x);
//console.log(flightAheadFlatPosition.y - flightFlatPosition.y);
this.options.onRefreshFlight(flight, flightFlatPosition.x, flightFlatPosition.y, angle, this);
}
},
_distance: function(A, B) {
if (A.z) {
return Math.sqrt(
(A.x - B.x) * (A.x - B.x) +
(A.y - B.y) * (A.y - B.y) +
(A.z - B.z) * (A.z - B.z)
);
} else {
return Math.sqrt(
(A.x - B.x) * (A.x - B.x) +
(A.y - B.y) * (A.y - B.y)
);
}
},
// WARNING: temporary function to make the locations look good on a spinning planet without rotation
_calibrated: function(x, alpha) {
var calib = 0.3 + 0.15 * Math.abs(alpha - Math.PI / 2) / (Math.PI / 4);
//console.log(calib);
var y = calib * (4 * (x - 0.5) * (x - 0.5) * (x - 0.5) + 0.5) + (1 - calib) * x;
return y;
},
/* WARNING:
Obviously there is something wrong with _orbitalTo3d and _orthographicProjection, since
I can't get a descent display of locations when the planet is rotated. That's why I had to create the _calibrated
function in the first place. I didn't have time to look precisely into it, and I probably don't know enough math.
I leaved the _3dProjection function I found on wikipedia but is not working. (I might not have correctly understood / write it)
*/
_orbitalTo3d: function(alpha, delta, r) {
return {
x: -r * Math.sin(alpha) * Math.cos(delta),
y: -r * Math.sin(alpha) * Math.sin(delta),
z: -r * Math.cos(alpha)
};
},
_orthographicProjection: function(position) {
return {x: position.y + this.element.width() / 2, y: position.z + this.element.height() / 2};
},
_3dProjection: function(a, c, delta, e) {
// Wikipedia is your friend :) : http://en.wikipedia.org/wiki/3D_projection
var d = {x: 0, y: 0, z: 0};
d.x = Math.cos(delta.y) * (Math.sin(delta.z) * (a.y - c.y) + Math.cos(delta.z) * (a.x - c.x)) - Math.sin(delta.y) * (a.z - c.z);
d.y = Math.sin(delta.x) * (Math.cos(delta.y) * (a.z - c.z) + Math.sin(delta.y) * (Math.sin(delta.z) * (a.y - c.y) + Math.cos(delta.z) * (a.x - c.x)))
+ Math.cos(delta.x) * (Math.cos(delta.z) * (a.y - c.y) - Math.sin(delta.z) * (a.x - c.x))
d.z = Math.cos(delta.x) * (Math.cos(delta.y) * (a.z - c.z) + Math.sin(delta.y) * (Math.sin(delta.z) * (a.y - c.y) + Math.cos(delta.z) * (a.x - c.x)))
- Math.sin(delta.x) * (Math.cos(delta.z) * (a.y - c.y) - Math.sin(delta.z) * (a.x - c.x));
return {
x: d.z, //(d.x - e.x) * (e.y / d.y),
y: d.y //(d.z - e.z) * (e.y / d.y)
};
},
_mouseDragStart: function(e) {
this.lastMousePos = e.clientX;
this.lastSpeed = null;
},
_mouseDrag: function(e) {
this.lastSpeed = (e.clientX - this.lastMousePos);
this.posVar = this.posVar - this.lastSpeed;
this.lastMousePos = e.clientX;
},
_mouseDragStop: function(e) {
this.lastMousePos = null;
this.lastTime = null;
},
_turnBy: function(time) {
if (this.lastTurnByTime === null) {
this.lastTurnByTime = time;
}
var timeDiff = (time - this.lastTurnByTime) / 1000;
if (this.lastMousePos === null) {
if (this.lastSpeed !== null) {
if (this.lastTime === null) {
this.lastTime = time;
}
if (this.options.backToDefaultTime + this.lastTime - time < 0) {
this.lastSpeed = null;
} else {
var backToDef = (this.options.backToDefaultTime + this.lastTime - time) / this.options.backToDefaultTime;
this.posVar -= this.lastSpeed * backToDef + (this.options.defaultSpeed * timeDiff) * (1 - backToDef);
}
} else {
this.posVar -= this.options.defaultSpeed * timeDiff;
}
}
this.lastTurnByTime = time;
return this.posVar;
},
_getQBezierValue: function (t, p1, p2, p3) {
var iT = 1 - t;
return iT * iT * p1 + 2 * iT * t * p2 + t * t * p3;
},
_getQBezierDerivation: function(t, p1, p2, p3) {
return (2 * p1 - 4 * p2 + 2 * p3) * t + 2 * p2 - 2 * p1;
},
_getQBezierAngle: function(startX, startY, cpX, cpY, endX, endY, position) {
var x = this._getQBezierDerivation(position, startX, cpX, endX);
var y = this._getQBezierDerivation(position, startY, cpY, endY);
return Math.atan2(y, x);
},
_getQuadraticCurvePoint: function(startX, startY, cpX, cpY, endX, endY, position) {
return {
x: this._getQBezierValue(position, startX, cpX, endX),
y: this._getQBezierValue(position, startY, cpY, endY),
angle: this._getQBezierAngle(startX, startY, cpX, cpY, endX, endY, position)
};
},
changeLocations: function(locations) {
for (var key in this.options.locations) {
this.options.onDeleteLocation(this.options.locations[key], this);
}
this.options.locations = locations;
this._initLocations();
},
changePaths: function(paths) {
for (var key in this.options.paths) {
var path = this.options.paths[key];
for (var keyFlight in path.flights) {
var flight = path.flights[keyFlight];
this.options.onDeleteFlight(flight, this);
}
}
this.options.paths = paths;
this._initFlights();
}
});
})($);

View File

@ -0,0 +1,99 @@
(function(){var m,aa=function(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}},ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a},ca=function(a){a=["object"==typeof globalThis&&globalThis,a,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error("Cannot find global object");
},da=ca(this),r=function(a,b){if(b)a:{var c=da;a=a.split(".");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}};
r("Symbol",function(a){if(a)return a;var b=function(f,g){this.ia=f;ba(this,"description",{configurable:!0,writable:!0,value:g})};b.prototype.toString=function(){return this.ia};var c="jscomp_symbol_"+(1E9*Math.random()>>>0)+"_",d=0,e=function(f){if(this instanceof e)throw new TypeError("Symbol is not a constructor");return new b(c+(f||"")+"_"+d++,f)};return e});
r("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;c<b.length;c++){var d=da[b[c]];"function"===typeof d&&"function"!=typeof d.prototype[a]&&ba(d.prototype,a,{configurable:!0,writable:!0,value:function(){return ea(aa(this))}})}return a});
var ea=function(a){a={next:a};a[Symbol.iterator]=function(){return this};return a},fa=function(a,b,c){if(null==a)throw new TypeError("The 'this' value for String.prototype."+c+" must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype."+c+" must not be a regular expression");return a+""};
r("String.prototype.endsWith",function(a){return a?a:function(b,c){var d=fa(this,b,"endsWith");b+="";void 0===c&&(c=d.length);c=Math.max(0,Math.min(c|0,d.length));for(var e=b.length;0<e&&0<c;)if(d[--c]!=b[--e])return!1;return 0>=e}});var ha=function(a,b){a instanceof String&&(a+="");var c=0,d=!1,e={next:function(){if(!d&&c<a.length){var f=c++;return{value:b(f,a[f]),done:!1}}d=!0;return{done:!0,value:void 0}}};e[Symbol.iterator]=function(){return e};return e};
r("Array.prototype.entries",function(a){return a?a:function(){return ha(this,function(b,c){return[b,c]})}});r("Array.prototype.keys",function(a){return a?a:function(){return ha(this,function(b){return b})}});r("Object.is",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});
r("Array.prototype.includes",function(a){return a?a:function(b,c){var d=this;d instanceof String&&(d=String(d));var e=d.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));c<e;c++){var f=d[c];if(f===b||Object.is(f,b))return!0}return!1}});r("String.prototype.includes",function(a){return a?a:function(b,c){return-1!==fa(this,b,"includes").indexOf(b,c||0)}});window.gapi=window.gapi||{};window.gapi.ua=(new Date).getTime();/*
Copyright The Closure Library Authors.
SPDX-License-Identifier: Apache-2.0
*/
var t=this||self,ia=function(a){var b=typeof a;return"object"!=b?b:a?Array.isArray(a)?"array":b:"null"},la=function(a){var b=ia(a);return"array"==b||"object"==b&&"number"==typeof a.length},u=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},ma="closure_uid_"+(1E9*Math.random()>>>0),na=0,oa=function(a,b,c){return a.call.apply(a.bind,arguments)},pa=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var e=Array.prototype.slice.call(arguments);
Array.prototype.unshift.apply(e,d);return a.apply(b,e)}}return function(){return a.apply(b,arguments)}},qa=function(a,b,c){qa=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?oa:pa;return qa.apply(null,arguments)},ra=function(a,b){function c(){}c.prototype=b.prototype;a.ya=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.B=function(d,e,f){for(var g=Array(arguments.length-2),k=2;k<arguments.length;k++)g[k-2]=arguments[k];return b.prototype[e].apply(d,
g)}},sa=function(a){return a},ta=function(a){var b=null,c=t.trustedTypes;if(!c||!c.createPolicy)return b;try{b=c.createPolicy(a,{createHTML:sa,createScript:sa,createScriptURL:sa})}catch(d){t.console&&t.console.error(d.message)}return b};function ua(a,b){if(Error.captureStackTrace)Error.captureStackTrace(this,ua);else{var c=Error().stack;c&&(this.stack=c)}a&&(this.message=String(a));void 0!==b&&(this.cause=b)}ra(ua,Error);ua.prototype.name="CustomError";var va;function wa(a,b){a=a.split("%s");for(var c="",d=a.length-1,e=0;e<d;e++)c+=a[e]+(e<b.length?b[e]:"%s");ua.call(this,c+a[d])}ra(wa,ua);wa.prototype.name="AssertionError";function xa(a,b,c,d){var e="Assertion failed";if(c){e+=": "+c;var f=d}else a&&(e+=": "+a,f=b);throw new wa(""+e,f||[]);}
var ya=function(a,b,c){a||xa("",null,b,Array.prototype.slice.call(arguments,2));return a},za=function(a,b){throw new wa("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1));},Aa=function(a,b,c){"string"!==typeof a&&xa("Expected string but got %s: %s.",[ia(a),a],b,Array.prototype.slice.call(arguments,2))};var Ba=Array.prototype.forEach?function(a,b){ya(null!=a.length);Array.prototype.forEach.call(a,b,void 0)}:function(a,b){for(var c=a.length,d="string"===typeof a?a.split(""):a,e=0;e<c;e++)e in d&&b.call(void 0,d[e],e,a)};function Ca(a){var b=a.length;if(0<b){for(var c=Array(b),d=0;d<b;d++)c[d]=a[d];return c}return[]};function Da(a,b){for(var c in a)b.call(void 0,a[c],c,a)};var Ea;var v=function(a,b){this.U=a===Fa&&b||"";this.ja=Ga};v.prototype.G=!0;v.prototype.F=function(){return this.U};v.prototype.toString=function(){return"Const{"+this.U+"}"};var Ia=function(a){if(a instanceof v&&a.constructor===v&&a.ja===Ga)return a.U;za("expected object of type Const, got '"+a+"'");return"type_error:Const"},Ga={},Fa={};var x=function(a,b){this.S=b===Ja?a:""};x.prototype.toString=function(){return this.S.toString()};x.prototype.G=!0;x.prototype.F=function(){return this.S.toString()};
var Ka=function(a){if(a instanceof x&&a.constructor===x)return a.S;za("expected object of type SafeUrl, got '"+a+"' of type "+ia(a));return"type_error:SafeUrl"},La=/^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))/i,Ma=function(a){if(a instanceof x)return a;a="object"==typeof a&&a.G?a.F():String(a);ya(La.test(a),"%s does not match the safe URL pattern",a)||(a="about:invalid#zClosurez");return new x(a,Ja)},Ja={};var Na={},Oa=function(a,b){this.R=b===Na?a:"";this.G=!0};Oa.prototype.F=function(){return this.R.toString()};Oa.prototype.toString=function(){return this.R.toString()};var Pa=function(a,b){this.name=a;this.value=b};Pa.prototype.toString=function(){return this.name};var Qa=new Pa("OFF",Infinity),Ra=new Pa("WARNING",900),Sa=new Pa("CONFIG",700),Ta=function(){this.C=0;this.clear()},Ua;Ta.prototype.clear=function(){this.X=Array(this.C);this.Z=-1;this.ba=!1};var Va=function(a,b,c){this.reset(a||Qa,b,c,void 0,void 0)};Va.prototype.reset=function(){};
var Wa=function(a,b){this.level=null;this.na=[];this.parent=(void 0===b?null:b)||null;this.children=[];this.pa={N:function(){return a}}},Xa=function(a){if(a.level)return a.level;if(a.parent)return Xa(a.parent);za("Root logger has no level set.");return Qa},Ya=function(a,b){for(;a;)a.na.forEach(function(c){c(b)}),a=a.parent},Za=function(){this.entries={};var a=new Wa("");a.level=Sa;this.entries[""]=a},$a,ab=function(a,b){var c=a.entries[b];if(c)return c;c=ab(a,b.slice(0,Math.max(b.lastIndexOf("."),
0)));var d=new Wa(b,c);a.entries[b]=d;c.children.push(d);return d},bb=function(){$a||($a=new Za);return $a};/*
SPDX-License-Identifier: Apache-2.0
*/
var cb=[],db=function(a){var b;if(b=ab(bb(),"safevalues").pa){var c="A URL with content '"+a+"' was sanitized away.",d=Ra;if(a=b)if(a=b&&d){a=d.value;var e=b?Xa(ab(bb(),b.N())):Qa;a=a>=e.value}if(a){d=d||Qa;a=ab(bb(),b.N());"function"===typeof c&&(c=c());Ua||(Ua=new Ta);e=Ua;b=b.N();if(0<e.C){var f=(e.Z+1)%e.C;e.Z=f;e.ba?(e=e.X[f],e.reset(d,c,b),b=e):(e.ba=f==e.C-1,b=e.X[f]=new Va(d,c,b))}else b=new Va(d,c,b);Ya(a,b)}}};-1===cb.indexOf(db)&&cb.push(db);var eb=function(a,b){if(!u(a)||!u(a)||!u(a)||1!==a.nodeType||a.namespaceURI&&"http://www.w3.org/1999/xhtml"!==a.namespaceURI||a.tagName.toUpperCase()!==b.toString()){b=b.toString()+"; got: ";if(u(a))try{var c=a.constructor.displayName||a.constructor.name||Object.prototype.toString.call(a)}catch(d){c="<object could not be stringified>"}else c=void 0===a?"undefined":null===a?"null":typeof a;za("Argument is not an HTML Element with tag name "+(b+c))}return a};var hb=function(a,b){Da(b,function(c,d){c&&"object"==typeof c&&c.G&&(c=c.F());"style"==d?a.style.cssText=c:"class"==d?a.className=c:"for"==d?a.htmlFor=c:fb.hasOwnProperty(d)?a.setAttribute(fb[d],c):0==d.lastIndexOf("aria-",0)||0==d.lastIndexOf("data-",0)?a.setAttribute(d,c):a[d]=c})},fb={cellpadding:"cellPadding",cellspacing:"cellSpacing",colspan:"colSpan",frameborder:"frameBorder",height:"height",maxlength:"maxLength",nonce:"nonce",role:"role",rowspan:"rowSpan",type:"type",usemap:"useMap",valign:"vAlign",
width:"width"},ib=function(a,b,c,d){function e(k){k&&b.appendChild("string"===typeof k?a.createTextNode(k):k)}for(;d<c.length;d++){var f=c[d];if(!la(f)||u(f)&&0<f.nodeType)e(f);else{a:{if(f&&"number"==typeof f.length){if(u(f)){var g="function"==typeof f.item||"string"==typeof f.item;break a}if("function"===typeof f){g="function"==typeof f.item;break a}}g=!1}Ba(g?Ca(f):f,e)}}},jb=function(a,b){b=String(b);"application/xhtml+xml"===a.contentType&&(b=b.toLowerCase());return a.createElement(b)},kb=function(a){ya(a,
"Node cannot be null or undefined.");return 9==a.nodeType?a:a.ownerDocument||a.document},lb=function(a){this.D=a||t.document||document};m=lb.prototype;m.getElementsByTagName=function(a,b){return(b||this.D).getElementsByTagName(String(a))};m.ma=function(a,b,c){var d=this.D,e=arguments,f=e[1],g=jb(d,String(e[0]));f&&("string"===typeof f?g.className=f:Array.isArray(f)?g.className=f.join(" "):hb(g,f));2<e.length&&ib(d,g,e,2);return g};m.createElement=function(a){return jb(this.D,a)};
m.createTextNode=function(a){return this.D.createTextNode(String(a))};m.appendChild=function(a,b){ya(null!=a&&null!=b,"goog.dom.appendChild expects non-null arguments");a.appendChild(b)};m.append=function(a,b){ib(kb(a),a,arguments,1)};m.canHaveChildren=function(a){if(1!=a.nodeType)return!1;switch(a.tagName){case "APPLET":case "AREA":case "BASE":case "BR":case "COL":case "COMMAND":case "EMBED":case "FRAME":case "HR":case "IMG":case "INPUT":case "IFRAME":case "ISINDEX":case "KEYGEN":case "LINK":case "NOFRAMES":case "NOSCRIPT":case "META":case "OBJECT":case "PARAM":case "SCRIPT":case "SOURCE":case "STYLE":case "TRACK":case "WBR":return!1}return!0};
m.removeNode=function(a){return a&&a.parentNode?a.parentNode.removeChild(a):null};m.contains=function(a,b){if(!a||!b)return!1;if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||!!(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a};/*
gapi.loader.OBJECT_CREATE_TEST_OVERRIDE &&*/
var y=window,A=document,mb=y.location,nb=function(){},ob=/\[native code\]/,B=function(a,b,c){return a[b]=a[b]||c},pb=function(a){for(var b=0;b<this.length;b++)if(this[b]===a)return b;return-1},qb=function(a){a=a.sort();for(var b=[],c=void 0,d=0;d<a.length;d++){var e=a[d];e!=c&&b.push(e);c=e}return b},rb=/&/g,sb=/</g,tb=/>/g,ub=/"/g,vb=/'/g,wb=function(a){return String(a).replace(rb,"&amp;").replace(sb,"&lt;").replace(tb,"&gt;").replace(ub,"&quot;").replace(vb,"&#39;")},C=function(){var a;if((a=Object.create)&&
ob.test(a))a=a(null);else{a={};for(var b in a)a[b]=void 0}return a},D=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)},xb=function(a){if(ob.test(Object.keys))return Object.keys(a);var b=[],c;for(c in a)D(a,c)&&b.push(c);return b},E=function(a,b){a=a||{};for(var c in a)D(a,c)&&(b[c]=a[c])},yb=function(a){return function(){y.setTimeout(a,0)}},F=function(a,b){if(!a)throw Error(b||"");},H=B(y,"gapi",{});var I=function(a,b,c){var d=new RegExp("([#].*&|[#])"+b+"=([^&#]*)","g");b=new RegExp("([?#].*&|[?#])"+b+"=([^&#]*)","g");if(a=a&&(d.exec(a)||b.exec(a)))try{c=decodeURIComponent(a[2])}catch(e){}return c},zb=new RegExp(/^/.source+/([a-zA-Z][-+.a-zA-Z0-9]*:)?/.source+/(\/\/[^\/?#]*)?/.source+/([^?#]*)?/.source+/(\?([^#]*))?/.source+/(#((#|[^#])*))?/.source+/$/.source),Ab=/[\ud800-\udbff][\udc00-\udfff]|[^!-~]/g,Bb=new RegExp(/(%([^0-9a-fA-F%]|[0-9a-fA-F]([^0-9a-fA-F%])?)?)*/.source+/%($|[^0-9a-fA-F]|[0-9a-fA-F]($|[^0-9a-fA-F]))/.source,
"g"),Cb=/%([a-f]|[0-9a-fA-F][a-f])/g,Db=/^(https?|ftp|file|chrome-extension):$/i,Eb=function(a){a=String(a);a=a.replace(Ab,function(e){try{return encodeURIComponent(e)}catch(f){return encodeURIComponent(e.replace(/^[^%]+$/g,"\ufffd"))}}).replace(Bb,function(e){return e.replace(/%/g,"%25")}).replace(Cb,function(e){return e.toUpperCase()});a=a.match(zb)||[];var b=C(),c=function(e){return e.replace(/\\/g,"%5C").replace(/\^/g,"%5E").replace(/`/g,"%60").replace(/\{/g,"%7B").replace(/\|/g,"%7C").replace(/\}/g,
"%7D")},d=!!(a[1]||"").match(Db);b.B=c((a[1]||"")+(a[2]||"")+(a[3]||(a[2]&&d?"/":"")));d=function(e){return c(e.replace(/\?/g,"%3F").replace(/#/g,"%23"))};b.query=a[5]?[d(a[5])]:[];b.j=a[7]?[d(a[7])]:[];return b},Fb=function(a){return a.B+(0<a.query.length?"?"+a.query.join("&"):"")+(0<a.j.length?"#"+a.j.join("&"):"")},Gb=function(a,b){var c=[];if(a)for(var d in a)if(D(a,d)&&null!=a[d]){var e=b?b(a[d]):a[d];c.push(encodeURIComponent(d)+"="+encodeURIComponent(e))}return c},Hb=function(a,b,c,d){a=Eb(a);
a.query.push.apply(a.query,Gb(b,d));a.j.push.apply(a.j,Gb(c,d));return Fb(a)},Ib=new RegExp(/\/?\??#?/.source+"("+/[\/?#]/i.source+"|"+/[\uD800-\uDBFF]/i.source+"|"+/%[c-f][0-9a-f](%[89ab][0-9a-f]){0,2}(%[89ab]?)?/i.source+"|"+/%[0-9a-f]?/i.source+")$","i"),Jb=function(a,b){var c=Eb(b);b=c.B;c.query.length&&(b+="?"+c.query.join(""));c.j.length&&(b+="#"+c.j.join(""));var d="";2E3<b.length&&(d=b,b=b.substr(0,2E3),b=b.replace(Ib,""),d=d.substr(b.length));var e=a.createElement("div");a=a.createElement("a");
c=Eb(b);b=c.B;c.query.length&&(b+="?"+c.query.join(""));c.j.length&&(b+="#"+c.j.join(""));b=null===b?"null":void 0===b?"undefined":b;if("string"!==typeof b)throw Error("Expected a string");b=new x(b,Ja);eb(a,"A");b=b instanceof x?b:Ma(b);a.href=Ka(b);e.appendChild(a);a=e.innerHTML;b=new v(Fa,"Assignment to self.");Aa(Ia(b),"must provide justification");ya(!/^[\s\xa0]*$/.test(Ia(b)),"must provide non-empty justification");void 0===Ea&&(Ea=ta("gapi#html"));a=(b=Ea)?b.createHTML(a):a;a=new Oa(a,Na);
if(void 0!==e.tagName){if("script"===e.tagName.toLowerCase())throw Error("Use setTextContent with a SafeScript.");if("style"===e.tagName.toLowerCase())throw Error("Use setTextContent with a SafeStyleSheet.");}a instanceof Oa&&a.constructor===Oa?a=a.R:(za("expected object of type SafeHtml, got '"+a+"' of type "+ia(a)),a="type_error:SafeHtml");e.innerHTML=a;b=String(e.firstChild.href);e.parentNode&&e.parentNode.removeChild(e);c=Eb(b+d);d=c.B;c.query.length&&(d+="?"+c.query.join(""));c.j.length&&(d+=
"#"+c.j.join(""));return d},Kb=/^https?:\/\/[^\/%\\?#\s]+\/[^\s]*$/i;var Lb;var Mb=function(a,b,c,d){if(y[c+"EventListener"])y[c+"EventListener"](a,b,!1);else if(y[d+"tachEvent"])y[d+"tachEvent"]("on"+a,b)},Nb=function(){var a=A.readyState;return"complete"===a||"interactive"===a&&-1==navigator.userAgent.indexOf("MSIE")},Qb=function(a){var b=Ob;if(!Nb())try{b()}catch(c){}Pb(a)},Pb=function(a){if(Nb())a();else{var b=!1,c=function(){if(!b)return b=!0,a.apply(this,arguments)};y.addEventListener?(y.addEventListener("load",c,!1),y.addEventListener("DOMContentLoaded",c,!1)):y.attachEvent&&
(y.attachEvent("onreadystatechange",function(){Nb()&&c.apply(this,arguments)}),y.attachEvent("onload",c))}},Rb=function(a){for(;a.firstChild;)a.removeChild(a.firstChild)},Sb={button:!0,div:!0,span:!0};var M={};M=B(y,"___jsl",C());B(M,"I",0);B(M,"hel",10);var Tb=function(a){return M.dpo?M.h:I(a,"jsh",M.h)},Ub=function(a){var b=B(M,"sws",[]);b.push.apply(b,a)},Vb=function(a){return B(M,"watt",C())[a]},Wb=function(a){var b=B(M,"PQ",[]);M.PQ=[];var c=b.length;if(0===c)a();else for(var d=0,e=function(){++d===c&&a()},f=0;f<c;f++)b[f](e)},Xb=function(a){return B(B(M,"H",C()),a,C())};var Yb=B(M,"perf",C()),Zb=B(Yb,"g",C()),$b=B(Yb,"i",C());B(Yb,"r",[]);C();C();
var ac=function(a,b,c){var d=Yb.r;"function"===typeof d?d(a,b,c):d.push([a,b,c])},N=function(a,b,c){Zb[a]=!b&&Zb[a]||c||(new Date).getTime();ac(a)},cc=function(a,b,c){b&&0<b.length&&(b=bc(b),c&&0<c.length&&(b+="___"+bc(c)),28<b.length&&(b=b.substr(0,28)+(b.length-28)),c=b,b=B($b,"_p",C()),B(b,c,C())[a]=(new Date).getTime(),ac(a,"_p",c))},bc=function(a){return a.join("__").replace(/\./g,"_").replace(/\-/g,"_").replace(/,/g,"_")};var dc=C(),O=[],P=function(a){throw Error("Bad hint: "+a);};O.push(["jsl",function(a){for(var b in a)if(D(a,b)){var c=a[b];"object"==typeof c?M[b]=B(M,b,[]).concat(c):B(M,b,c)}if(b=a.u)a=B(M,"us",[]),a.push(b),(b=/^https:(.*)$/.exec(b))&&a.push("http:"+b[1])}]);var ec=/^(\/[a-zA-Z0-9_\-]+)+$/,fc=[/\/amp\//,/\/amp$/,/^\/amp$/],gc=/^[a-zA-Z0-9\-_\.,!]+$/,hc=/^gapi\.loaded_[0-9]+$/,ic=/^[a-zA-Z0-9,._-]+$/,mc=function(a,b,c,d,e){var f=a.split(";"),g=f.shift(),k=dc[g],h=null;k?h=k(f,b,c,d):P("no hint processor for: "+g);h||P("failed to generate load url");b=h;c=b.match(jc);(d=b.match(kc))&&1===d.length&&lc.test(b)&&c&&1===c.length||P("failed sanity: "+a);try{a="?";if(e&&0<e.length){c=b=0;for(d={};c<e.length;){var l=e[c++];f=void 0;f=u(l)?"o"+(Object.prototype.hasOwnProperty.call(l,
ma)&&l[ma]||(l[ma]=++na)):(typeof l).charAt(0)+l;Object.prototype.hasOwnProperty.call(d,f)||(d[f]=!0,e[b++]=l)}e.length=b;h=h+"?le="+e.join(",");a="&"}if(M.rol){var n=M.ol;n&&n.length&&(h=""+h+a+"ol="+n.length)}}catch(q){}return h},pc=function(a,b,c,d){a=nc(a);hc.test(c)||P("invalid_callback");b=oc(b);d=d&&d.length?oc(d):null;var e=function(f){return encodeURIComponent(f).replace(/%2C/g,",")};return[encodeURIComponent(a.pathPrefix).replace(/%2C/g,",").replace(/%2F/g,"/"),"/k=",e(a.version),"/m=",
e(b),d?"/exm="+e(d):"","/rt=j/sv=1/d=1/ed=1",a.W?"/am="+e(a.W):"",a.fa?"/rs="+e(a.fa):"",a.ha?"/t="+e(a.ha):"","/cb=",e(c)].join("")},nc=function(a){"/"!==a.charAt(0)&&P("relative path");for(var b=a.substring(1).split("/"),c=[];b.length;){a=b.shift();if(!a.length||0==a.indexOf("."))P("empty/relative directory");else if(0<a.indexOf("=")){b.unshift(a);break}c.push(a)}a={};for(var d=0,e=b.length;d<e;++d){var f=b[d].split("="),g=decodeURIComponent(f[0]),k=decodeURIComponent(f[1]);2==f.length&&g&&k&&(a[g]=
a[g]||k)}b="/"+c.join("/");ec.test(b)||P("invalid_prefix");c=0;for(d=fc.length;c<d;++c)fc[c].test(b)&&P("invalid_prefix");c=qc(a,"k",!0);d=qc(a,"am");e=qc(a,"rs");a=qc(a,"t");return{pathPrefix:b,version:c,W:d,fa:e,ha:a}},oc=function(a){for(var b=[],c=0,d=a.length;c<d;++c){var e=a[c].replace(/\./g,"_").replace(/-/g,"_");ic.test(e)&&b.push(e)}return b.join(",")},qc=function(a,b,c){a=a[b];!a&&c&&P("missing: "+b);if(a){if(gc.test(a))return a;P("invalid: "+b)}return null},lc=/^https?:\/\/[a-z0-9_.-]+\.google(rs)?\.com(:\d+)?\/[a-zA-Z0-9_.,!=\-\/]+$/,
kc=/\/cb=/g,jc=/\/\//g;dc.m=function(a,b,c,d){(a=a[0])||P("missing_hint");return"https://apis.google.com"+pc(a,b,c,d)};var rc=decodeURI("%73cript"),sc=/^[-+_0-9\/A-Za-z]+={0,2}$/,tc=function(a,b){for(var c=[],d=0;d<a.length;++d){var e=a[d];e&&0>pb.call(b,e)&&c.push(e)}return c},uc=function(){var a=M.nonce;return void 0!==a?a&&a===String(a)&&a.match(sc)?a:M.nonce=null:A.querySelector?(a=A.querySelector("script[nonce]"))?(a=a.nonce||a.getAttribute("nonce")||"",a&&a===String(a)&&a.match(sc)?M.nonce=a:M.nonce=null):null:null},xc=function(a){if("loading"!=A.readyState)vc(a);else{var b=uc(),c="";null!==b&&(c=' nonce="'+
b+'"');a="<"+rc+' src="'+encodeURI(a)+'"'+c+"></"+rc+">";A.write(wc?wc.createHTML(a):a)}},vc=function(a){var b=A.createElement(rc);b.setAttribute("src",wc?wc.createScriptURL(a):a);a=uc();null!==a&&b.setAttribute("nonce",a);b.async="true";(a=A.getElementsByTagName(rc)[0])?a.parentNode.insertBefore(b,a):(A.head||A.body||A.documentElement).appendChild(b)},zc=function(a,b,c){yc(function(){var d=b===Tb(mb.href)?B(H,"_",C()):C();d=B(Xb(b),"_",d);a(d)},c)},Bc=function(a,b){var c=b||{};"function"==typeof b&&
(c={},c.callback=b);var d=(b=c)&&b._c;if(d)for(var e=0;e<O.length;e++){var f=O[e][0],g=O[e][1];g&&D(d,f)&&g(d[f],a,b)}b=[];a?b=a.split(":"):c.features&&(b=c.features);if(!(a=c.h)&&(a=Tb(mb.href),!a))throw Error("Bad hint: !hint");Ac(b||[],c,a)},Ac=function(a,b,c){var d=!!M.glrp;a=qb(a)||[];var e=b.callback,f=b.config,g=b.timeout,k=b.ontimeout,h=b.onerror,l=void 0;"function"==typeof h&&(l=h);var n=null,q=!1;if(g&&!k||!g&&k)throw"Timeout requires both the timeout parameter and ontimeout parameter to be set";
h=B(Xb(c),"r",[]).sort();var p=B(Xb(c),"L",[]).sort(),J=M.le||[],z=[].concat(h),w=function(R,ja){if(q)return 0;y.clearTimeout(n);p.push.apply(p,G);var ka=((H||{}).config||{}).update;ka?ka(f):f&&B(M,"cu",[]).push(f);if(ja){cc("me0",R,z);try{zc(ja,c,l)}finally{cc("me1",R,z)}}return 1};0<g&&(n=y.setTimeout(function(){q=!0;k()},g));var G=tc(a,p);if(G.length){G=tc(a,h);var K=B(M,"CP",[]),L=K.length;K[L]=function(R){if(!R)return 0;cc("ml1",G,z);var ja=function(Ha){d||(K[L]=null);w(G,R)&&(d&&(K[L]=null),
Wb(function(){e&&e();Ha()}))},ka=function(){var Ha=K[L+1];Ha&&Ha()};0<L&&K[L-1]?K[L]=function(){ja(ka)}:ja(ka)};if(G.length){var gb="loaded_"+M.I++;H[gb]=function(R){K[L](R);H[gb]=null};a=mc(c,G,"gapi."+gb,h,J);h.push.apply(h,G);cc("ml0",G,z);b.sync||y.___gapisync?xc(a):vc(a)}else K[L](nb)}else w(G)&&e&&e()},wc=ta("gapi#gapi");var yc=function(a,b){if(M.hee&&0<M.hel)try{return a()}catch(c){b&&b(c),M.hel--,Bc("debug_error",function(){try{window.___jsl.hefn(c)}catch(d){throw c;}})}else try{return a()}catch(c){throw b&&b(c),c;}};var Cc=H.load;Cc&&B(M,"ol",[]).push(Cc);H.load=function(a,b){return yc(function(){return Bc(a,b)})};var Dc=function(a){var b=window.___jsl=window.___jsl||{};b[a]=b[a]||[];return b[a]},Ec=function(a){var b=window.___jsl=window.___jsl||{};b.cfg=!a&&b.cfg||{};return b.cfg},Fc=function(a){return"object"===typeof a&&/\[native code\]/.test(a.push)},Q=function(a,b,c){if(b&&"object"===typeof b)for(var d in b)!Object.prototype.hasOwnProperty.call(b,d)||c&&"___goc"===d&&"undefined"===typeof b[d]||(a[d]&&b[d]&&"object"===typeof a[d]&&"object"===typeof b[d]&&!Fc(a[d])&&!Fc(b[d])?Q(a[d],b[d]):b[d]&&"object"===
typeof b[d]?(a[d]=Fc(b[d])?[]:{},Q(a[d],b[d])):a[d]=b[d])},Gc=function(a){if(a&&!/^\s+$/.test(a)){for(;0==a.charCodeAt(a.length-1);)a=a.substring(0,a.length-1);try{var b=window.JSON.parse(a)}catch(c){}if("object"===typeof b)return b;try{b=(new Function("return ("+a+"\n)"))()}catch(c){}if("object"===typeof b)return b;try{b=(new Function("return ({"+a+"\n})"))()}catch(c){}return"object"===typeof b?b:{}}},Hc=function(a,b){var c={___goc:void 0};a.length&&a[a.length-1]&&Object.hasOwnProperty.call(a[a.length-
1],"___goc")&&"undefined"===typeof a[a.length-1].___goc&&(c=a.pop());Q(c,b);a.push(c)},Ic=function(a){Ec(!0);var b=window.___gcfg,c=Dc("cu"),d=window.___gu;b&&b!==d&&(Hc(c,b),window.___gu=b);b=Dc("cu");var e=document.scripts||document.getElementsByTagName("script")||[];d=[];var f=[];f.push.apply(f,Dc("us"));for(var g=0;g<e.length;++g)for(var k=e[g],h=0;h<f.length;++h)k.src&&0==k.src.indexOf(f[h])&&d.push(k);0==d.length&&0<e.length&&e[e.length-1].src&&d.push(e[e.length-1]);for(e=0;e<d.length;++e)d[e].getAttribute("gapi_processed")||
(d[e].setAttribute("gapi_processed",!0),(f=d[e])?(g=f.nodeType,f=3==g||4==g?f.nodeValue:f.textContent||""):f=void 0,(f=Gc(f))&&b.push(f));a&&Hc(c,a);d=Dc("cd");a=0;for(b=d.length;a<b;++a)Q(Ec(),d[a],!0);d=Dc("ci");a=0;for(b=d.length;a<b;++a)Q(Ec(),d[a],!0);a=0;for(b=c.length;a<b;++a)Q(Ec(),c[a],!0)},S=function(a){var b=Ec();if(!a)return b;a=a.split("/");for(var c=0,d=a.length;b&&"object"===typeof b&&c<d;++c)b=b[a[c]];return c===a.length&&void 0!==b?b:void 0},Jc=function(a,b){var c;if("string"===typeof a){var d=
c={};a=a.split("/");for(var e=0,f=a.length;e<f-1;++e){var g={};d=d[a[e]]=g}d[a[e]]=b}else c=a;Ic(c)};var Kc=function(){var a=window.__GOOGLEAPIS;a&&(a.googleapis&&!a["googleapis.config"]&&(a["googleapis.config"]=a.googleapis),B(M,"ci",[]).push(a),window.__GOOGLEAPIS=void 0)};var Lc={callback:1,clientid:1,cookiepolicy:1,openidrealm:-1,includegrantedscopes:-1,requestvisibleactions:1,scope:1},Mc=!1,Nc=C(),Oc=function(){if(!Mc){for(var a=document.getElementsByTagName("meta"),b=0;b<a.length;++b){var c=a[b].name.toLowerCase();if(0==c.lastIndexOf("google-signin-",0)){c=c.substring(14);var d=a[b].content;Lc[c]&&d&&(Nc[c]=d)}}if(window.self!==window.top){a=document.location.toString();for(var e in Lc)0<Lc[e]&&(b=I(a,e,""))&&(Nc[e]=b)}Mc=!0}e=C();E(Nc,e);return e},Pc=function(a){return!!(a.clientid&&
a.scope&&a.callback)};var Qc=function(){this.i=window.console};Qc.prototype.log=function(a){this.i&&this.i.log&&this.i.log(a)};Qc.prototype.error=function(a){this.i&&(this.i.error?this.i.error(a):this.i.log&&this.i.log(a))};Qc.prototype.warn=function(a){this.i&&(this.i.warn?this.i.warn(a):this.i.log&&this.i.log(a))};Qc.prototype.debug=function(){};var Rc=new Qc;var Sc=function(){return!!M.oa},Tc=function(){};var T=B(M,"rw",C()),Uc=function(a){for(var b in T)a(T[b])},Vc=function(a,b){(a=T[a])&&a.state<b&&(a.state=b)};var U=function(a){var b=window.___jsl=window.___jsl||{};b.cfg=b.cfg||{};b=b.cfg;if(!a)return b;a=a.split("/");for(var c=0,d=a.length;b&&"object"===typeof b&&c<d;++c)b=b[a[c]];return c===a.length&&void 0!==b?b:void 0};var Wc=/^https?:\/\/(?:\w|[\-\.])+\.google\.(?:\w|[\-:\.])+(?:\/[^\?#]*)?\/u\/(\d)\//,Xc=/^https?:\/\/(?:\w|[\-\.])+\.google\.(?:\w|[\-:\.])+(?:\/[^\?#]*)?\/b\/(\d{10,21})\//,Yc=function(){var a=U("googleapis.config/sessionIndex");"string"===typeof a&&254<a.length&&(a=null);null==a&&(a=window.__X_GOOG_AUTHUSER);"string"===typeof a&&254<a.length&&(a=null);if(null==a){var b=window.google;b&&(a=b.authuser)}"string"===typeof a&&254<a.length&&(a=null);null==a&&(b=window.location.href,a=I(b,"authuser")||
null,null==a&&(a=(a=b.match(Wc))?a[1]:null));if(null==a)return null;a=String(a);254<a.length&&(a=null);return a},Zc=function(){var a=U("googleapis.config/sessionDelegate");"string"===typeof a&&21<a.length&&(a=null);null==a&&(a=(a=window.location.href.match(Xc))?a[1]:null);if(null==a)return null;a=String(a);21<a.length&&(a=null);return a};var $c,V,W=void 0,X=function(a){try{return t.JSON.parse.call(t.JSON,a)}catch(b){return!1}},Y=function(a){return Object.prototype.toString.call(a)},ad=Y(0),bd=Y(new Date(0)),cd=Y(!0),dd=Y(""),ed=Y({}),fd=Y([]),gd=function(a,b){if(b)for(var c=0,d=b.length;c<d;++c)if(a===b[c])throw new TypeError("Converting circular structure to JSON");d=typeof a;if("undefined"!==d){c=Array.prototype.slice.call(b||[],0);c[c.length]=a;b=[];var e=Y(a);if(null!=a&&"function"===typeof a.toJSON&&(Object.prototype.hasOwnProperty.call(a,
"toJSON")||(e!==fd||a.constructor!==Array&&a.constructor!==Object)&&(e!==ed||a.constructor!==Array&&a.constructor!==Object)&&e!==dd&&e!==ad&&e!==cd&&e!==bd))return gd(a.toJSON.call(a),c);if(null==a)b[b.length]="null";else if(e===ad)a=Number(a),isNaN(a)||isNaN(a-a)?a="null":-0===a&&0>1/a&&(a="-0"),b[b.length]=String(a);else if(e===cd)b[b.length]=String(!!Number(a));else{if(e===bd)return gd(a.toISOString.call(a),c);if(e===fd&&Y(a.length)===ad){b[b.length]="[";var f=0;for(d=Number(a.length)>>0;f<d;++f)f&&
(b[b.length]=","),b[b.length]=gd(a[f],c)||"null";b[b.length]="]"}else if(e==dd&&Y(a.length)===ad){b[b.length]='"';f=0;for(c=Number(a.length)>>0;f<c;++f)d=String.prototype.charAt.call(a,f),e=String.prototype.charCodeAt.call(a,f),b[b.length]="\b"===d?"\\b":"\f"===d?"\\f":"\n"===d?"\\n":"\r"===d?"\\r":"\t"===d?"\\t":"\\"===d||'"'===d?"\\"+d:31>=e?"\\u"+(e+65536).toString(16).substr(1):32<=e&&65535>=e?d:"\ufffd";b[b.length]='"'}else if("object"===d){b[b.length]="{";d=0;for(f in a)Object.prototype.hasOwnProperty.call(a,
f)&&(e=gd(a[f],c),void 0!==e&&(d++&&(b[b.length]=","),b[b.length]=gd(f),b[b.length]=":",b[b.length]=e));b[b.length]="}"}else return}return b.join("")}},hd=/[\0-\x07\x0b\x0e-\x1f]/,id=/^([^"]*"([^\\"]|\\.)*")*[^"]*"([^"\\]|\\.)*[\0-\x1f]/,jd=/^([^"]*"([^\\"]|\\.)*")*[^"]*"([^"\\]|\\.)*\\[^\\\/"bfnrtu]/,kd=/^([^"]*"([^\\"]|\\.)*")*[^"]*"([^"\\]|\\.)*\\u([0-9a-fA-F]{0,3}[^0-9a-fA-F])/,ld=/"([^\0-\x1f\\"]|\\[\\\/"bfnrt]|\\u[0-9a-fA-F]{4})*"/g,md=/-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][-+]?[0-9]+)?/g,nd=/[ \t\n\r]+/g,
od=/[^"]:/,pd=/""/g,qd=/true|false|null/g,rd=/00/,sd=/[\{]([^0\}]|0[^:])/,td=/(^|\[)[,:]|[,:](\]|\}|[,:]|$)/,ud=/[^\[,:][\[\{]/,vd=/^(\{|\}|\[|\]|,|:|0)+/,wd=/\u2028/g,xd=/\u2029/g,yd=function(a){a=String(a);if(hd.test(a)||id.test(a)||jd.test(a)||kd.test(a))return!1;var b=a.replace(ld,'""');b=b.replace(md,"0");b=b.replace(nd,"");if(od.test(b))return!1;b=b.replace(pd,"0");b=b.replace(qd,"0");if(rd.test(b)||sd.test(b)||td.test(b)||ud.test(b)||!b||(b=b.replace(vd,"")))return!1;a=a.replace(wd,"\\u2028").replace(xd,
"\\u2029");b=void 0;try{b=W?[X(a)]:eval("(function (var_args) {\n return Array.prototype.slice.call(arguments, 0);\n})(\n"+a+"\n)")}catch(c){return!1}return b&&1===b.length?b[0]:!1},zd=function(){var a=((t.document||{}).scripts||[]).length;if((void 0===$c||void 0===W||V!==a)&&-1!==V){$c=W=!1;V=-1;try{try{W=!!t.JSON&&'{"a":[3,true,"1970-01-01T00:00:00.000Z"]}'===t.JSON.stringify.call(t.JSON,{a:[3,!0,new Date(0)],c:function(){}})&&!0===X("true")&&3===X('[{"a":3}]')[0].a}catch(b){}$c=W&&!X("[00]")&&
!X('"\u0007"')&&!X('"\\0"')&&!X('"\\v"')}finally{V=a}}},Ad=function(a){if(-1===V)return!1;zd();return($c?X:yd)(a)},Bd=function(a){if(-1!==V)return zd(),W?t.JSON.stringify.call(t.JSON,a):gd(a)},Cd=!Date.prototype.toISOString||"function"!==typeof Date.prototype.toISOString||"1970-01-01T00:00:00.000Z"!==(new Date(0)).toISOString(),Dd=function(){var a=Date.prototype.getUTCFullYear.call(this);return[0>a?"-"+String(1E6-a).substr(1):9999>=a?String(1E4+a).substr(1):"+"+String(1E6+a).substr(1),"-",String(101+
Date.prototype.getUTCMonth.call(this)).substr(1),"-",String(100+Date.prototype.getUTCDate.call(this)).substr(1),"T",String(100+Date.prototype.getUTCHours.call(this)).substr(1),":",String(100+Date.prototype.getUTCMinutes.call(this)).substr(1),":",String(100+Date.prototype.getUTCSeconds.call(this)).substr(1),".",String(1E3+Date.prototype.getUTCMilliseconds.call(this)).substr(1),"Z"].join("")};Date.prototype.toISOString=Cd?Dd:Date.prototype.toISOString;var Ed=function(){this.blockSize=-1};var Fd=function(){this.blockSize=-1;this.blockSize=64;this.g=[];this.M=[];this.ka=[];this.J=[];this.J[0]=128;for(var a=1;a<this.blockSize;++a)this.J[a]=0;this.K=this.v=0;this.reset()};ra(Fd,Ed);Fd.prototype.reset=function(){this.g[0]=1732584193;this.g[1]=4023233417;this.g[2]=2562383102;this.g[3]=271733878;this.g[4]=3285377520;this.K=this.v=0};
var Gd=function(a,b,c){c||(c=0);var d=a.ka;if("string"===typeof b)for(var e=0;16>e;e++)d[e]=b.charCodeAt(c)<<24|b.charCodeAt(c+1)<<16|b.charCodeAt(c+2)<<8|b.charCodeAt(c+3),c+=4;else for(e=0;16>e;e++)d[e]=b[c]<<24|b[c+1]<<16|b[c+2]<<8|b[c+3],c+=4;for(e=16;80>e;e++){var f=d[e-3]^d[e-8]^d[e-14]^d[e-16];d[e]=(f<<1|f>>>31)&4294967295}b=a.g[0];c=a.g[1];var g=a.g[2],k=a.g[3],h=a.g[4];for(e=0;80>e;e++){if(40>e)if(20>e){f=k^c&(g^k);var l=1518500249}else f=c^g^k,l=1859775393;else 60>e?(f=c&g|k&(c|g),l=2400959708):
(f=c^g^k,l=3395469782);f=(b<<5|b>>>27)+f+h+l+d[e]&4294967295;h=k;k=g;g=(c<<30|c>>>2)&4294967295;c=b;b=f}a.g[0]=a.g[0]+b&4294967295;a.g[1]=a.g[1]+c&4294967295;a.g[2]=a.g[2]+g&4294967295;a.g[3]=a.g[3]+k&4294967295;a.g[4]=a.g[4]+h&4294967295};
Fd.prototype.update=function(a,b){if(null!=a){void 0===b&&(b=a.length);for(var c=b-this.blockSize,d=0,e=this.M,f=this.v;d<b;){if(0==f)for(;d<=c;)Gd(this,a,d),d+=this.blockSize;if("string"===typeof a)for(;d<b;){if(e[f]=a.charCodeAt(d),++f,++d,f==this.blockSize){Gd(this,e);f=0;break}}else for(;d<b;)if(e[f]=a[d],++f,++d,f==this.blockSize){Gd(this,e);f=0;break}}this.v=f;this.K+=b}};
Fd.prototype.digest=function(){var a=[],b=8*this.K;56>this.v?this.update(this.J,56-this.v):this.update(this.J,this.blockSize-(this.v-56));for(var c=this.blockSize-1;56<=c;c--)this.M[c]=b&255,b/=256;Gd(this,this.M);for(c=b=0;5>c;c++)for(var d=24;0<=d;d-=8)a[b]=this.g[c]>>d&255,++b;return a};var Hd=function(){this.T=new Fd};Hd.prototype.reset=function(){this.T.reset()};var Id=y.crypto,Jd=!1,Kd=0,Ld=0,Md=1,Nd=0,Od="",Pd=function(a){a=a||y.event;var b=a.screenX+a.clientX<<16;b+=a.screenY+a.clientY;b*=(new Date).getTime()%1E6;Md=Md*b%Nd;0<Kd&&++Ld==Kd&&Mb("mousemove",Pd,"remove","de")},Qd=function(a){var b=new Hd;a=unescape(encodeURIComponent(a));for(var c=[],d=0,e=a.length;d<e;++d)c.push(a.charCodeAt(d));b.T.update(c);b=b.T.digest();a="";for(c=0;c<b.length;c++)a+="0123456789ABCDEF".charAt(Math.floor(b[c]/16))+"0123456789ABCDEF".charAt(b[c]%16);return a};
Jd=!!Id&&"function"==typeof Id.getRandomValues;Jd||(Nd=1E6*(screen.width*screen.width+screen.height),Od=Qd(A.cookie+"|"+A.location+"|"+(new Date).getTime()+"|"+Math.random()),Kd=U("random/maxObserveMousemove")||0,0!=Kd&&Mb("mousemove",Pd,"add","at"));var Rd=function(){var a=M.onl;if(!a){a=C();M.onl=a;var b=C();a.e=function(c){var d=b[c];d&&(delete b[c],d())};a.a=function(c,d){b[c]=d};a.r=function(c){delete b[c]}}return a},Sd=function(a,b){b=b.onload;return"function"===typeof b?(Rd().a(a,b),b):null},Td=function(a){F(/^\w+$/.test(a),"Unsupported id - "+a);return'onload="window.___jsl.onl.e(&#34;'+a+'&#34;)"'},Ud=function(a){Rd().r(a)};var Vd={allowtransparency:"true",frameborder:"0",hspace:"0",marginheight:"0",marginwidth:"0",scrolling:"no",style:"",tabindex:"0",vspace:"0",width:"100%"},Wd={allowtransparency:!0,onload:!0},Xd=0,Yd=function(a){F(!a||Kb.test(a),"Illegal url for new iframe - "+a)},Zd=function(a,b,c,d,e){Yd(c.src);var f,g=Sd(d,c),k=g?Td(d):"";try{document.all&&(f=a.createElement('<iframe frameborder="'+wb(String(c.frameborder))+'" scrolling="'+wb(String(c.scrolling))+'" '+k+' name="'+wb(String(c.name))+'"/>'))}catch(l){}finally{f||
(f=(a?new lb(kb(a)):va||(va=new lb)).ma("IFRAME"),g&&(f.onload=function(){f.onload=null;g.call(this)},Ud(d)))}f.setAttribute("ng-non-bindable","");for(var h in c)a=c[h],"style"===h&&"object"===typeof a?E(a,f.style):Wd[h]||f.setAttribute(h,String(a));(h=e&&e.beforeNode||null)||e&&e.dontclear||Rb(b);b.insertBefore(f,h);f=h?h.previousSibling:b.lastChild;c.allowtransparency&&(f.allowTransparency=!0);return f};var $d=/^:[\w]+$/,ae=/:([a-zA-Z_]+):/g,be=function(){var a=Yc()||"0",b=Zc();var c=Yc()||a;var d=Zc(),e="";c&&(e+="u/"+encodeURIComponent(String(c))+"/");d&&(e+="b/"+encodeURIComponent(String(d))+"/");c=e||null;(e=(d=!1===U("isLoggedIn"))?"_/im/":"")&&(c="");var f=U("iframes/:socialhost:"),g=U("iframes/:im_socialhost:");return Lb={socialhost:f,ctx_socialhost:d?g:f,session_index:a,session_delegate:b,session_prefix:c,im_prefix:e}},ce=function(a,b){return be()[b]||""},de=function(a){return function(b,
c){return a?be()[c]||a[c]||"":be()[c]||""}};var ee=function(a){var b;a.match(/^https?%3A/i)&&(b=decodeURIComponent(a));a=b?b:a;return Jb(document,a)},fe=function(a){a=a||"canonical";for(var b=document.getElementsByTagName("link"),c=0,d=b.length;c<d;c++){var e=b[c],f=e.getAttribute("rel");if(f&&f.toLowerCase()==a&&(e=e.getAttribute("href"))&&(e=ee(e))&&null!=e.match(/^https?:\/\/[\w\-_\.]+/i))return e}return window.location.href};var ge={se:"0"},he={post:!0},ie={style:"position:absolute;top:-10000px;width:450px;margin:0px;border-style:none"},je="onPlusOne _ready _close _open _resizeMe _renderstart oncircled drefresh erefresh".split(" "),ke=B(M,"WI",C()),le=function(a,b,c){var d;var e={};var f=d=a;"plus"==a&&b.action&&(d=a+"_"+b.action,f=a+"/"+b.action);(d=S("iframes/"+d+"/url"))||(d=":im_socialhost:/:session_prefix::im_prefix:_/widget/render/"+f+"?usegapi=1");for(var g in ge)e[g]=g+"/"+(b[g]||ge[g])+"/";e=Jb(A,d.replace(ae,
de(e)));g="iframes/"+a+"/params/";f={};E(b,f);(d=S("lang")||S("gwidget/lang"))&&(f.hl=d);he[a]||(f.origin=window.location.origin||window.location.protocol+"//"+window.location.host);f.exp=S(g+"exp");if(g=S(g+"location"))for(d=0;d<g.length;d++){var k=g[d];f[k]=y.location[k]}switch(a){case "plus":case "follow":g=f.href;d=b.action?void 0:"publisher";g=(g="string"==typeof g?g:void 0)?ee(g):fe(d);f.url=g;delete f.href;break;case "plusone":g=(g=b.href)?ee(g):fe();f.url=g;g=b.db;d=S();null==g&&d&&(g=d.db,
null==g&&(g=d.gwidget&&d.gwidget.db));f.db=g||void 0;g=b.ecp;d=S();null==g&&d&&(g=d.ecp,null==g&&(g=d.gwidget&&d.gwidget.ecp));f.ecp=g||void 0;delete f.href;break;case "signin":f.url=fe()}M.ILI&&(f.iloader="1");delete f["data-onload"];delete f.rd;for(var h in ge)f[h]&&delete f[h];f.gsrc=S("iframes/:source:");h=S("inline/css");"undefined"!==typeof h&&0<c&&h>=c&&(f.ic="1");h=/^#|^fr-/;c={};for(var l in f)D(f,l)&&h.test(l)&&(c[l.replace(h,"")]=f[l],delete f[l]);l="q"==S("iframes/"+a+"/params/si")?f:
c;h=Oc();for(var n in h)!D(h,n)||D(f,n)||D(c,n)||(l[n]=h[n]);n=[].concat(je);(l=S("iframes/"+a+"/methods"))&&"object"===typeof l&&ob.test(l.push)&&(n=n.concat(l));for(var q in b)D(b,q)&&/^on/.test(q)&&("plus"!=a||"onconnect"!=q)&&(n.push(q),delete f[q]);delete f.callback;c._methods=n.join(",");return Hb(e,f,c)},me=["style","data-gapiscan"],oe=function(a){for(var b=C(),c=0!=a.nodeName.toLowerCase().indexOf("g:"),d=a.attributes.length,e=0;e<d;e++){var f=a.attributes[e],g=f.name,k=f.value;0<=pb.call(me,
g)||c&&0!=g.indexOf("data-")||"null"===k||"specified"in f&&!f.specified||(c&&(g=g.substr(5)),b[g.toLowerCase()]=k)}a=a.style;(c=ne(a&&a.height))&&(b.height=String(c));(a=ne(a&&a.width))&&(b.width=String(a));return b},ne=function(a){var b=void 0;"number"===typeof a?b=a:"string"===typeof a&&(b=parseInt(a,10));return b},re=function(){var a=M.drw;Uc(function(b){if(a!==b.id&&4!=b.state&&"share"!=b.type){var c=b.id,d=b.type,e=b.url;b=b.userParams;var f=A.getElementById(c);if(f){var g=le(d,b,0);g?(f=f.parentNode,
pe(e)!==pe(g)&&(b.dontclear=!0,b.rd=!0,b.ri=!0,b.type=d,qe(f,b),(d=T[f.lastChild.id])&&(d.oid=c),Vc(c,4))):delete T[c]}else delete T[c]}})},pe=function(a){var b=RegExp("(\\?|&)ic=1");return a.replace(/#.*/,"").replace(b,"")};var se,te,ue,ve,we,xe=/(?:^|\s)g-((\S)*)(?:$|\s)/,ye={plusone:!0,autocomplete:!0,profile:!0,signin:!0,signin2:!0};se=B(M,"SW",C());te=B(M,"SA",C());ue=B(M,"SM",C());ve=B(M,"FW",[]);we=null;
var ze=function(a,b){return("string"===typeof a?document.getElementById(a):a)||b},Be=function(a,b){Ae(void 0,!1,a,b)},Ae=function(a,b,c,d){N("ps0",!0);c=ze(c,A);var e=A.documentMode;if(c.querySelectorAll&&(!e||8<e)){e=d?[d]:xb(se).concat(xb(te)).concat(xb(ue));for(var f=[],g=0;g<e.length;g++){var k=e[g];f.push(".g-"+k,"g\\:"+k)}e=c.querySelectorAll(f.join(","))}else e=c.getElementsByTagName("*");c=C();for(f=0;f<e.length;f++){g=e[f];k=d;var h=g.nodeName.toLowerCase(),l=void 0;if(g.getAttribute("data-gapiscan"))k=
null;else{var n=h.indexOf("g:");0==n?l=h.substr(2):(n=(n=String(g.className||g.getAttribute("class")))&&xe.exec(n))&&(l=n[1]);k=!l||!(se[l]||te[l]||ue[l])||k&&l!==k?null:l}k&&(ye[k]||0==g.nodeName.toLowerCase().indexOf("g:")||0!=xb(oe(g)).length)&&(g.setAttribute("data-gapiscan",!0),B(c,k,[]).push(g))}if(b)for(var q in c)for(b=c[q],d=0;d<b.length;d++)b[d].setAttribute("data-onload",!0);for(var p in c)ve.push(p);N("ps1",!0);if((q=ve.join(":"))||a)try{H.load(q,a)}catch(z){Rc.log(z);return}if(Ce(we||
{}))for(var J in c){a=c[J];p=0;for(b=a.length;p<b;p++)a[p].removeAttribute("data-gapiscan");De(J)}else{d=[];for(J in c)for(a=c[J],p=0,b=a.length;p<b;p++)e=a[p],Ee(J,e,oe(e),d,b);Fe(q,d)}},Ge=function(a){var b=B(H,a,{});b.go||(b.go=function(c){return Be(c,a)},b.render=function(c,d){d=d||{};d.type=a;return qe(c,d)})},He=function(a){se[a]=!0},Ie=function(a){te[a]=!0},Je=function(a){ue[a]=!0};var De=function(a,b){var c=Vb(a);b&&c?(c(b),(c=b.iframeNode)&&c.setAttribute("data-gapiattached",!0)):H.load(a,function(){var d=Vb(a),e=b&&b.iframeNode,f=b&&b.userParams;e&&d?(d(b),e.setAttribute("data-gapiattached",!0)):(d=H[a].go,"signin2"==a?d(e,f):d(e&&e.parentNode,f))})},Ce=function(){return!1},Fe=function(){},Ee=function(a,b,c,d,e,f){switch(Ke(b,a,f)){case 0:a=ue[a]?a+"_annotation":a;d={};d.iframeNode=b;d.userParams=c;De(a,d);break;case 1:if(b.parentNode){for(var g in c){if(f=D(c,g))f=c[g],
f=!!f&&"object"===typeof f&&(!f.toString||f.toString===Object.prototype.toString||f.toString===Array.prototype.toString);if(f)try{c[g]=Bd(c[g])}catch(G){delete c[g]}}var k=!0;c.dontclear&&(k=!1);delete c.dontclear;Tc();f=le(a,c,e);g={allowPost:1,attributes:ie};g.dontclear=!k;e={};e.userParams=c;e.url=f;e.type=a;if(c.rd)var h=b;else h=document.createElement("div"),b.setAttribute("data-gapistub",!0),h.style.cssText="position:absolute;width:450px;left:-10000px;",b.parentNode.insertBefore(h,b);e.siteElement=
h;h.id||(b=h,B(ke,a,0),k="___"+a+"_"+ke[a]++,b.id=k);b=C();b[">type"]=a;E(c,b);k=f;c=h;f=g||{};b=f.attributes||{};F(!(f.allowPost||f.forcePost)||!b.onload,"onload is not supported by post iframe (allowPost or forcePost)");g=b=k;$d.test(b)&&(g=U("iframes/"+g.substring(1)+"/url"),F(!!g,"Unknown iframe url config for - "+b));k=Jb(A,g.replace(ae,ce));b=c.ownerDocument||A;h=0;do g=f.id||["I",Xd++,"_",(new Date).getTime()].join("");while(b.getElementById(g)&&5>++h);F(5>h,"Error creating iframe id");h={};
var l={};b.documentMode&&9>b.documentMode&&(h.hostiemode=b.documentMode);E(f.queryParams||{},h);E(f.fragmentParams||{},l);var n=f.pfname;var q=C();U("iframes/dropLegacyIdParam")||(q.id=g);q._gfid=g;q.parent=b.location.protocol+"//"+b.location.host;var p=I(b.location.href,"parent");n=n||"";!n&&p&&(p=I(b.location.href,"_gfid","")||I(b.location.href,"id",""),n=I(b.location.href,"pfname",""),n=p?n+"/"+p:"");n||(p=Ad(I(b.location.href,"jcp","")))&&"object"==typeof p&&(n=(n=p.id)?p.pfname+"/"+n:"");q.pfname=
n;f.connectWithJsonParam&&(p={},p.jcp=Bd(q),q=p);p=I(k,"rpctoken")||h.rpctoken||l.rpctoken;if(!p){if(!(p=f.rpctoken)){p=String;n=Math;var J=n.round;if(Jd){var z=new y.Uint32Array(1);Id.getRandomValues(z);z=Number("0."+z[0])}else z=Md,z+=parseInt(Od.substr(0,20),16),Od=Qd(Od),z/=Nd+Math.pow(16,20);p=p(J.call(n,1E8*z))}q.rpctoken=p}f.rpctoken=p;E(q,f.connectWithQueryParams?h:l);p=b.location.href;q=C();(n=I(p,"_bsh",M.bsh))&&(q._bsh=n);(p=Tb(p))&&(q.jsh=p);f.hintInFragment?E(q,l):E(q,h);k=Hb(k,h,l,f.paramsSerializer);
l=C();E(Vd,l);E(f.attributes,l);l.name=l.id=g;l.src=k;f.eurl=k;h=f||{};q=!!h.allowPost;if(h.forcePost||q&&2E3<k.length){h=Eb(k);l.src="";f.dropDataPostorigin||(l["data-postorigin"]=k);k=Zd(b,c,l,g);if(-1!=navigator.userAgent.indexOf("WebKit")){var w=k.contentWindow.document;w.open();l=w.createElement("div");q={};p=g+"_inner";q.name=p;q.src="";q.style="display:none";Zd(b,l,q,p,f)}l=(f=h.query[0])?f.split("&"):[];f=[];for(q=0;q<l.length;q++)p=l[q].split("=",2),f.push([decodeURIComponent(p[0]),decodeURIComponent(p[1])]);
h.query=[];l=Fb(h);F(Kb.test(l),"Invalid URL: "+l);h=b.createElement("form");h.method="POST";h.target=g;h.style.display="none";g=l instanceof x?l:Ma(l);eb(h,"FORM").action=Ka(g);for(g=0;g<f.length;g++)l=b.createElement("input"),l.type="hidden",l.name=f[g][0],l.value=f[g][1],h.appendChild(l);c.appendChild(h);h.submit();h.parentNode.removeChild(h);w&&w.close();w=k}else w=Zd(b,c,l,g,f);e.iframeNode=w;e.id=w.getAttribute("id");w=e.id;c=C();c.id=w;c.userParams=e.userParams;c.url=e.url;c.type=e.type;c.state=
1;T[w]=c;w=e}else w=null;w&&((e=w.id)&&d.push(e),De(a,w))}},Ke=function(a,b,c){if(a&&1===a.nodeType&&b){if(c)return 1;if(ue[b]){if(Sb[a.nodeName.toLowerCase()])return(a=a.innerHTML)&&a.replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")?0:1}else{if(te[b])return 0;if(se[b])return 1}}return null},qe=function(a,b){var c=b.type;delete b.type;var d=ze(a);if(d){a={};for(var e in b)D(b,e)&&(a[e.toLowerCase()]=b[e]);a.rd=1;(b=!!a.ri)&&delete a.ri;e=[];Ee(c,d,a,e,0,b);Fe(c,e)}else Rc.log("string"==="gapi."+c+".render: missing element "+
typeof a?a:"")};B(H,"platform",{}).go=Be;Ce=function(a){for(var b=["_c","jsl","h"],c=0;c<b.length&&a;c++)a=a[b[c]];b=Tb(mb.href);return!a||0!=a.indexOf("n;")&&0!=b.indexOf("n;")&&a!==b};Fe=function(a,b){Le(a,b)};var Ob=function(a){Ae(a,!0)},Me=function(a,b){b=b||[];for(var c=0;c<b.length;++c)a(b[c]);for(a=0;a<b.length;a++)Ge(b[a])};
O.push(["platform",function(a,b,c){we=c;(b||c.features)&&ve.push(b||c.features.join(":"));Me(He,a);Me(Ie,c._c.annotation);Me(Je,c._c.bimodal);Kc();Ic();if("explicit"!=S("parsetags")){Ub(a);Pc(Oc())&&!S("disableRealtimeCallback")&&Tc();if(c&&(a=c.callback)){var d=yb(a);delete c.callback}Qb(function(){Ob(d)})}}]);H._pl=!0;var Ne=function(a){a=(a=T[a])?a.oid:void 0;if(a){var b=A.getElementById(a);b&&b.parentNode.removeChild(b);delete T[a];Ne(a)}};var Oe=/^\{h:'/,Pe=/^!_/,Qe="",Le=function(a,b){function c(){Mb("message",d,"remove","de")}function d(f){var g=f.data,k=f.origin;if(Re(g,b)){var h=e;e=!1;h&&N("rqe");Se(a,function(){h&&N("rqd");c();for(var l=B(M,"RPMQ",[]),n=0;n<l.length;n++)l[n]({data:g,origin:k})})}}if(0!==b.length){Qe=I(mb.href,"pfname","");var e=!0;Mb("message",d,"add","at");Bc(a,c)}},Re=function(a,b){a=String(a);if(Oe.test(a))return!0;var c=!1;Pe.test(a)&&(c=!0,a=a.substr(2));if(!/^\{/.test(a))return!1;var d=Ad(a);if(!d)return!1;
a=d.f;if(d.s&&a&&-1!=pb.call(b,a)){if("_renderstart"===d.s||d.s===Qe+"/"+a+"::_renderstart")if(d=d.a&&d.a[c?0:1],b=A.getElementById(a),Vc(a,2),d&&b&&d.width&&d.height){a:{c=b.parentNode;a=d||{};if(Sc()){var e=b.id;if(e){d=(d=T[e])?d.state:void 0;if(1===d||4===d)break a;Ne(e)}}(d=c.nextSibling)&&d.getAttribute&&d.getAttribute("data-gapistub")&&(c.parentNode.removeChild(d),c.style.cssText="");d=a.width;var f=a.height,g=c.style;g.textIndent="0";g.margin="0";g.padding="0";g.background="transparent";g.borderStyle=
"none";g.cssFloat="none";g.styleFloat="none";g.lineHeight="normal";g.fontSize="1px";g.verticalAlign="baseline";c=c.style;c.display="inline-block";g=b.style;g.position="static";g.left="0";g.top="0";g.visibility="visible";d&&(c.width=g.width=d+"px");f&&(c.height=g.height=f+"px");a.verticalAlign&&(c.verticalAlign=a.verticalAlign);e&&Vc(e,3)}b["data-csi-wdt"]=(new Date).getTime()}return!0}return!1},Se=function(a,b){Bc(a,b)};var Te=function(a,b){this.P=a;a=b||{};this.qa=Number(a.maxAge)||0;this.aa=a.domain;this.da=a.path;this.ra=!!a.secure};Te.prototype.read=function(){for(var a=this.P+"=",b=document.cookie.split(/;\s*/),c=0;c<b.length;++c){var d=b[c];if(0==d.indexOf(a))return d.substr(a.length)}};
Te.prototype.write=function(a,b){if(!Ue.test(this.P))throw"Invalid cookie name";if(!Ve.test(a))throw"Invalid cookie value";a=this.P+"="+a;this.aa&&(a+=";domain="+this.aa);this.da&&(a+=";path="+this.da);b="number"===typeof b?b:this.qa;if(0<=b){var c=new Date;c.setSeconds(c.getSeconds()+b);a+=";expires="+c.toUTCString()}this.ra&&(a+=";secure");document.cookie=a;return!0};Te.prototype.clear=function(){this.write("",0)};var Ve=/^[-+/_=.:|%&a-zA-Z0-9@]*$/,Ue=/^[A-Z_][A-Z0-9_]{0,63}$/;
Te.iterate=function(a){for(var b=document.cookie.split(/;\s*/),c=0;c<b.length;++c){var d=b[c].split("="),e=d.shift();a(e,d.join("="))}};var We=function(a){this.H=a};We.prototype.read=function(){if(Z.hasOwnProperty(this.H))return Z[this.H]};We.prototype.write=function(a){Z[this.H]=a;return!0};We.prototype.clear=function(){delete Z[this.H]};var Z={};We.iterate=function(a){for(var b in Z)Z.hasOwnProperty(b)&&a(b,Z[b])};var Xe="https:"===window.location.protocol,Ye=Xe||"http:"===window.location.protocol?Te:We,Ze=function(a){var b=a.substr(1),c="",d=window.location.hostname;if(""!==b){c=parseInt(b,10);if(isNaN(c))return null;b=d.split(".");if(b.length<c-1)return null;b.length==c-1&&(d="."+d)}else d="";return{l:"S"==a.charAt(0),domain:d,o:c}},$e=function(){var a,b=null;Ye.iterate(function(c,d){0===c.indexOf("G_AUTHUSER_")&&(c=Ze(c.substring(11)),!a||c.l&&!a.l||c.l==a.l&&c.o>a.o)&&(a=c,b=d)});return{la:a,L:b}};function af(a){if(0!==a.indexOf("GCSC"))return null;var b={ca:!1};a=a.substr(4);if(!a)return b;var c=a.charAt(0);a=a.substr(1);var d=a.lastIndexOf("_");if(-1==d)return b;var e=Ze(a.substr(d+1));if(null==e)return b;a=a.substring(0,d);if("_"!==a.charAt(0))return b;d="E"===c&&e.l;return!d&&("U"!==c||e.l)||d&&!Xe?b:{ca:!0,l:d,va:a.substr(1),domain:e.domain,o:e.o}}
var bf=function(a){if(!a)return[];a=a.split("=");return a[1]?a[1].split("|"):[]},cf=function(a){a=a.split(":");return{clientId:a[0].split("=")[1],ta:bf(a[1]),xa:bf(a[2]),wa:bf(a[3])}},df=function(){var a=$e(),b=a.la;a=a.L;if(null!==a){var c;Ye.iterate(function(f,g){(f=af(f))&&f.ca&&f.l==b.l&&f.o==b.o&&(c=g)});if(c){var d=cf(c),e=d&&d.ta[Number(a)];d=d&&d.clientId;if(e)return{L:a,sa:e,clientId:d}}}return null};var ff=function(){this.Y=ef};m=ff.prototype;m.ga=function(){this.O||(this.A=0,this.O=!0,this.ea())};m.ea=function(){this.O&&(this.Y()?this.A=this.V:this.A=Math.min(2*(this.A||this.V),120),window.setTimeout(qa(this.ea,this),1E3*this.A))};m.A=0;m.V=2;m.Y=null;m.O=!1;var gf=null;Sc=function(){return M.oa=!0};Tc=function(){M.oa=!0;var a=df();(a=a&&a.L)&&Jc("googleapis.config/sessionIndex",a);gf||(gf=B(M,"ss",new ff));a=gf;a.ga&&a.ga()};
var ef=function(){var a=df(),b=a&&a.sa||null,c=a&&a.clientId;Bc("auth",{callback:function(){var d=y.gapi.auth,e={client_id:c,session_state:b};d.checkSessionState(e,function(f){var g=e.session_state,k=!!S("isLoggedIn");f=S("debug/forceIm")?!1:g&&f||!g&&!f;if(k=k!==f)Jc("isLoggedIn",f),Tc(),re(),f||((f=d.signOut)?f():(f=d.setToken)&&f(null));f=Oc();var h=S("savedUserState");g=d._guss(f.cookiepolicy);h=h!=g&&"undefined"!=typeof h;Jc("savedUserState",g);(k||h)&&Pc(f)&&!S("disableRealtimeCallback")&&d._pimf(f,
!0)})}});return!0};O.unshift(["url",function(a,b,c){!a||b&&""!==b||!a.endsWith(".js")||(a=a.substring(0,a.length-3),b=a.lastIndexOf("/")+1,b>=a.length||(a=a.substr(b).split(":").filter(function(d){return!["api","platform"].includes(d)}),c.features=a))}]);N("bs0",!0,window.gapi._bs);N("bs1",!0);delete window.gapi._bs;window.gapi.load("",{callback:window["gapi_onload"],_c:{url:"https://apis.google.com/js/plusone.js",jsl:{ci:{"oauth-flow":{authUrl:"https://accounts.google.com/o/oauth2/auth",proxyUrl:"https://accounts.google.com/o/oauth2/postmessageRelay",disableOpt:!0,idpIframeUrl:"https://accounts.google.com/o/oauth2/iframe",usegapi:!1},debug:{reportExceptionRate:1,forceIm:!1,rethrowException:!0,host:"https://apis.google.com"},enableMultilogin:!0,"googleapis.config":{auth:{useFirstPartyAuthV2:!0},root:"https://content.googleapis.com","root-1p":"https://clients6.google.com"},inline:{css:1},
disableRealtimeCallback:!1,drive_share:{skipInitCommand:!0},csi:{rate:.01},client:{cors:!1},signInDeprecation:{rate:0},include_granted_scopes:!0,llang:"fr",iframes:{youtube:{params:{location:["search","hash"]},url:":socialhost:/:session_prefix:_/widget/render/youtube?usegapi=1",methods:["scroll","openwindow"]},ytsubscribe:{url:"https://www.youtube.com/subscribe_embed?usegapi=1"},plus_circle:{params:{url:""},url:":socialhost:/:session_prefix::se:_/widget/plus/circle?usegapi=1"},plus_share:{params:{url:""},
url:":socialhost:/:session_prefix::se:_/+1/sharebutton?plusShare=true&usegapi=1"},rbr_s:{params:{url:""},url:":socialhost:/:session_prefix::se:_/widget/render/recobarsimplescroller"},":source:":"3p",playemm:{url:"https://play.google.com/work/embedded/search?usegapi=1&usegapi=1"},savetoandroidpay:{url:"https://pay.google.com/gp/v/widget/save"},blogger:{params:{location:["search","hash"]},url:":socialhost:/:session_prefix:_/widget/render/blogger?usegapi=1",methods:["scroll","openwindow"]},evwidget:{params:{url:""},
url:":socialhost:/:session_prefix:_/events/widget?usegapi=1"},partnersbadge:{url:"https://www.gstatic.com/partners/badge/templates/badge.html?usegapi=1"},dataconnector:{url:"https://dataconnector.corp.google.com/:session_prefix:ui/widgetview?usegapi=1"},surveyoptin:{url:"https://www.google.com/shopping/customerreviews/optin?usegapi=1"},":socialhost:":"https://apis.google.com",shortlists:{url:""},hangout:{url:"https://talkgadget.google.com/:session_prefix:talkgadget/_/widget"},plus_followers:{params:{url:""},
url:":socialhost:/_/im/_/widget/render/plus/followers?usegapi=1"},post:{params:{url:""},url:":socialhost:/:session_prefix::im_prefix:_/widget/render/post?usegapi=1"},signin:{params:{url:""},url:":socialhost:/:session_prefix:_/widget/render/signin?usegapi=1",methods:["onauth"]},rbr_i:{params:{url:""},url:":socialhost:/:session_prefix::se:_/widget/render/recobarinvitation"},share:{url:":socialhost:/:session_prefix::im_prefix:_/widget/render/share?usegapi=1"},plusone:{params:{count:"",size:"",url:""},
url:":socialhost:/:session_prefix::se:_/+1/fastbutton?usegapi=1"},comments:{params:{location:["search","hash"]},url:":socialhost:/:session_prefix:_/widget/render/comments?usegapi=1",methods:["scroll","openwindow"]},":im_socialhost:":"https://plus.googleapis.com",backdrop:{url:"https://clients3.google.com/cast/chromecast/home/widget/backdrop?usegapi=1"},visibility:{params:{url:""},url:":socialhost:/:session_prefix:_/widget/render/visibility?usegapi=1"},autocomplete:{params:{url:""},url:":socialhost:/:session_prefix:_/widget/render/autocomplete"},
":signuphost:":"https://plus.google.com",ratingbadge:{url:"https://www.google.com/shopping/customerreviews/badge?usegapi=1"},appcirclepicker:{url:":socialhost:/:session_prefix:_/widget/render/appcirclepicker"},follow:{url:":socialhost:/:session_prefix:_/widget/render/follow?usegapi=1"},community:{url:":ctx_socialhost:/:session_prefix::im_prefix:_/widget/render/community?usegapi=1"},sharetoclassroom:{url:"https://classroom.google.com/sharewidget?usegapi=1"},ytshare:{params:{url:""},url:":socialhost:/:session_prefix:_/widget/render/ytshare?usegapi=1"},
plus:{url:":socialhost:/:session_prefix:_/widget/render/badge?usegapi=1"},family_creation:{params:{url:""},url:"https://families.google.com/webcreation?usegapi=1&usegapi=1"},commentcount:{url:":socialhost:/:session_prefix:_/widget/render/commentcount?usegapi=1"},configurator:{url:":socialhost:/:session_prefix:_/plusbuttonconfigurator?usegapi=1"},zoomableimage:{url:"https://ssl.gstatic.com/microscope/embed/"},appfinder:{url:"https://workspace.google.com/:session_prefix:marketplace/appfinder?usegapi=1"},savetowallet:{url:"https://pay.google.com/gp/v/widget/save"},
person:{url:":socialhost:/:session_prefix:_/widget/render/person?usegapi=1"},savetodrive:{url:"https://drive.google.com/savetodrivebutton?usegapi=1",methods:["save"]},page:{url:":socialhost:/:session_prefix:_/widget/render/page?usegapi=1"},card:{url:":socialhost:/:session_prefix:_/hovercard/card"}}},h:"m;/_/scs/abc-static/_/js/k=gapi.lb.fr.CAOyDGt5mKU.O/d=1/rs=AHpOoo_3N2T_xTSzzfu-Lp8hVcRjkVoYFQ/m=__features__",u:"https://apis.google.com/js/plusone.js",hee:!0,dpo:!1,le:["scs"],glrp:false},platform:"backdrop blogger comments commentcount community donation family_creation follow hangout health page partnersbadge person playemm playreview plus plusone post ratingbadge savetoandroidpay savetodrive savetowallet sharetoclassroom shortlists signin2 surveyoptin visibility youtube ytsubscribe zoomableimage".split(" "),
annotation:["interactivepost","recobar","signin2","autocomplete"]}});}).call(this);

View File

@ -0,0 +1,30 @@
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller
// fixes from Paul Irish and Tino Zijdel
(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, element) {
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);
};
}());

View File

@ -0,0 +1,608 @@
// **Sphere** renders a mathematically perfect textured sphere.
// It calculates the surface of the sphere instead of approximating it with triangles.
// Shamefully hacked by Sébastien Drouyer
/*jshint laxcomma: true, laxbreak: true, browser: true */
(function() {
"use strict";
var opts = { tilt: 40
, turn: 20
};
// Tiling informations
var tiling = {
horizontal: 1,
vertical: 1
};
// frame count, current angle of rotation. inc/dec to turn.
var gCtx;
var gImage, gCtxImg;
//Variable to hold the size of the canvas
var size;
var canvasImageData, textureImageData;
// Constants for indexing dimentions
var X=0, Y=1, Z=2;
var textureWidth, textureHeight;
var hs=30; // Horizontal scale of viewing area
var vs=30; // Vertical scale of viewing area
// NB The viewing area is an abstract rectangle in the 3d world and is not
// the same as the canvas used to display the image.
var F = [0,0,0]; // Focal point of viewer
var S = [0,30,0]; // Centre of sphere/planet
var r=12; // Radius of sphere/planet
// Distance of the viewing area from the focal point. This seems
// to give strange results if it is not equal to S[Y]. It should
// theoreticaly be changable but hs & vs can still be used along
// with r to change how large the sphere apears on the canvas.
// HOWEVER, the values of hs, vs, S[Y], f & r MUST NOT BE TOO BIG
// as this will result in overflow errors which are not traped
// and do not stop the script but will result in incorrect
// displaying of the texture upon the sphere.
var f = 30;
// There may be a solution to the above problem by finding L in
// a slightly different way.
// Since the problem is equivelent to finding the intersection
// in 2D space of a line and a circle then each view area pixel
// and associated vector can be used define a 2D plane in the 3D
// space that 'contains' the vector S-F which is the focal point
// to centre of the sphere.
//
// This is essentialy the same problem but I belive/hope it will
// not result in the same exact solution. I have hunch that the
// math will not result in such big numbers. Since this abstract
// plane will be spinning, it may be posilbe to use the symetry
// of the arangement to reuse 1/4 of the calculations.
// Variables to hold rotations about the 3 axis
var RX = 0,RY,RZ;
// Temp variables to hold them whilst rendering so they won't get updated.
var rx,ry,rz;
var a;
var b;
var b2; // b squared
var bx=F[X]-S[X]; // = 0 for current values of F and S
var by=F[Y]-S[Y];
var bz=F[Z]-S[Z]; // = 0 for current values of F and S
// c = Fx^2 + Sx^2 -2FxSx + Fy^2 + Sy^2 -2FySy + Fz^2 + Sz^2 -2FzSz - r^2
// for current F and S this means c = Sy^2 - r^2
var c = F[X]*F[X] + S[X]*S[X]
+ F[Y]*F[Y] + S[Y]*S[Y]
+ F[Z]*F[Z] + S[Z]*S[Z]
- 2*(F[X]*S[X] + F[Y]*S[Y] + F[Z]*S[Z])
- r*r
;
var c4 = c*4; // save a bit of time maybe during rendering
var s;
var m1 = 0;
//double m2 = 0;
// The following are use to calculate the vector of the current pixel to be
// drawn from the focus position F
var hs_ch; // horizontal scale divided by canvas width
var vs_cv; // vertical scale divided by canvas height
var hhs = 0.5*hs; // half horizontal scale
var hvs = 0.5*vs; // half vertical scale
var V = new Array(3); // vector for storing direction of each pixel from F
var L = new Array(3); // Location vector from S that pixel 'hits' sphere
var VY2=f*f; // V[Y] ^2 NB May change if F changes
var rotCache = {};
var calculateVector = function(h,v) {
// Calculate vector from focus point (Origin, so can ignor) to pixel
V[X]=(hs_ch*h)-hhs;
// V[Y] always the same as view frame doesn't mov
V[Z]=(vs_cv*v)-hvs;
// Vector (L) from S where m*V (m is an unknown scalar) intersects
// surface of sphere is as follows
//
// <pre>
// L = F + mV - S
//
// ,-------.
// / \ -----m------
// | S<-L->| <-V->F
// \ /
// `-------'
//
// L and m are unknown so find magnitude of vectors as the magnitude
// of L is the radius of the sphere
//
// |L| = |F + mV - S| = r
//
// Can be rearranged to form a quadratic
//
// 0 = am&sup2; +bm + c
//
// and solved to find m, using the following formula
//
// <pre>
// ___________
// m = ( -b &PlusMinus; \/(b&sup2;) - 4ac ) /2a
// </pre>
//
// r = |F + mV - S|
// __________________________________________________
// r = v(Fx + mVx -Sx)&sup2; + (Fy + mVy -Sy)&sup2; + (Fz + mVz -Sz)&sup2;
//
// r&sup2; = (Fx + mVx -Sx)&sup2; + (Fy + mVy -Sy)&sup2; + (Fz + mVz -Sz)&sup2;
//
// r&sup2; = (Fx + mVx -Sx)&sup2; + (Fy + mVy -Sy)&sup2; + (Fz + mVz -Sz)&sup2;
//
// 0 = Fx&sup2; + FxVxm -FxSx + FxVxm + Vx&sup2;m&sup2; -SxVxm -SxFx -SxVxm + Sx&sup2;
// +Fy&sup2; + FyVym -FySy + FyVym + Vy&sup2;m&sup2; -SyVym -SyFy -SyVym + Sy&sup2;
// +Fz&sup2; + FzVzm -FzSz + FzVzm + Vz&sup2;m&sup2; -SzVzm -SzFz -SzVzm + Sz&sup2; - r&sup2;
//
// 0 = Vx&sup2;m&sup2; + FxVxm + FxVxm -2SxVxm + Fx&sup2; -FxSx -SxFx + Sx&sup2;
// +Vy&sup2;m&sup2; + FyVym + FyVym -2SyVym + Fy&sup2; -FySy -SyFy + Sy&sup2;
// +Vz&sup2;m&sup2; + FzVzm + FzVzm -2SzVzm + Fz&sup2; -FzSz -SzFz + Sz&sup2; - r&sup2;
//
// 0 = (Vx&sup2; + Vy&sup2; + Vz&sup2;)m&sup2; + (FxVx + FxVx -2SxVx)m + Fx&sup2; - 2FxSx + Sx&sup2;
// + (FyVy + FyVy -2SyVy)m + Fy&sup2; - 2FySy + Sy&sup2;
// + (FzVz + FzVz -2SzVz)m + Fz&sup2; - 2FzSz + Sz&sup2; - r&sup2;
//
// 0 = |Vz|m&sup2; + (FxVx + FxVx -2SxVx)m + |F| - 2FxSx + |S|
// + (FyVy + FyVy -2SyVy)m - 2FySy
// + (FyVy + FyVy -2SyVy)m - 2FySy - r&sup2;
//
// a = |Vz|
// b =
// c = Fx&sup2; + Sx&sup2; -2FxSx + Fy&sup2; + Sy&sup2; -2FySy + Fz&sup2; + Sz&sup2; -2FzSz - r&sup2;
// for current F and S this means c = Sy&sup2; - r&sup2;
// </pre>
// Where a, b and c are as in the code.
// Only the solution for the negative square root term is needed as the
// closest intersection is wanted. The other solution to m would give
// the intersection of the 'back' of the sphere.
a=V[X]*V[X]+VY2+V[Z]*V[Z];
s=(b2-a*c4); // the square root term
// if s is negative then there are no solutions to m and the
// sphere is not visible on the current pixel on the canvas
// so only draw a pixel if the sphere is visable
// 0 is a special case as it is the 'edge' of the sphere as there
// is only one solution. (I have never seen it happen though)
// of the two solutions m1 & m2 the nearest is m1, m2 being the
// far side of the sphere.
if (s > 0) {
m1 = ((-b)-(Math.sqrt(s)))/(2*a);
L[X]=m1*V[X]; // bx+m1*V[X];
L[Y]=by+(m1*V[Y]);
L[Z]=m1*V[Z]; // bz+m1*V[Z];
// Do a couple of rotations on L
var lx=L[X];
var srz = Math.sin(rz);
var crz = Math.cos(rz);
L[X]=lx*crz-L[Y]*srz;
L[Y]=lx*srz+L[Y]*crz;
var lz;
lz=L[Z];
var sry = Math.sin(ry);
var cry = Math.cos(ry);
L[Z]=lz*cry-L[Y]*sry;
L[Y]=lz*sry+L[Y]*cry;
// Calculate the position that this location on the sphere
// coresponds to on the texture
var lh = textureWidth + textureWidth * ( Math.atan2(L[Y],L[X]) + Math.PI ) / (2*Math.PI);
// %textureHeight at end to get rid of south pole bug. probaly means that one
// pixel may be a color from the opposite pole but as long as the
// poles are the same color this won't be noticed.
var lv = textureWidth * Math.floor(textureHeight-1-(textureHeight*(Math.acos(L[Z]/r)/Math.PI)%textureHeight));
return {lv:lv,lh:lh};
}
return null;
};
/**
* Create the sphere function opject
*/
var sphere = function(){
var textureData = textureImageData.data;
var canvasData = canvasImageData.data;
var copyFnc;
if (canvasData.splice){
//2012-04-19 splice on canvas data not supported in any current browser
copyFnc = function(idxC, idxT){
canvasData.splice(idxC, 4 , textureData[idxT + 0]
, textureData[idxT + 1]
, textureData[idxT + 2]
, 255);
};
} else {
copyFnc = function(idxC, idxT){
canvasData[idxC + 0] = textureData[idxT + 0];
canvasData[idxC + 1] = textureData[idxT + 1];
canvasData[idxC + 2] = textureData[idxT + 2];
canvasData[idxC + 3] = 255;
};
}
var getVector = (function(){
var cache = new Array(size*size);
return function(pixel){
if (cache[pixel] === undefined){
var v = Math.floor(pixel / size);
var h = pixel - v * size;
cache[pixel] = calculateVector(h,v);
}
return cache[pixel];
};
})();
var posDelta = textureWidth*0.2/(20*1000);
//var firstFramePos = (new Date()) * posDelta;
var stats = {fastCount: 0, fastSumMs: 0};
return {
posDelta: posDelta,
firstFramePos: (new Date()) * posDelta,
positionsCache: [],
minX: null,
minY: null,
maxX: null,
maxY: null,
init: function(options) {
this.changeRotation(options);
hs=30; // Horizontal scale of viewing area
vs=30; // Vertical scale of viewing area
F = [0,0,0]; // Focal point of viewer
S = [0,30,0]; // Centre of sphere/planet
r=options.r; // Radius of sphere/planet
f = 30;
bx=F[X]-S[X]; // = 0 for current values of F and S
by=F[Y]-S[Y];
bz=F[Z]-S[Z]; // = 0 for current values of F and S
c = F[X]*F[X] + S[X]*S[X]
+ F[Y]*F[Y] + S[Y]*S[Y]
+ F[Z]*F[Z] + S[Z]*S[Z]
- 2*(F[X]*S[X] + F[Y]*S[Y] + F[Z]*S[Z])
- r*r
;
c4 = c*4; // save a bit of time maybe during rendering
m1 = 0;
hhs = 0.5*hs; // half horizontal scale
hvs = 0.5*vs; // half vertical scale
/*V = new Array(3);*/ // vector for storing direction of each pixel from F
L = new Array(3); // Location vector from S that pixel 'hits' sphere
VY2=f*f; // V[Y] ^2 NB May change if F changes
rotCache = {};
if (canvasData.splice){
//2012-04-19 splice on canvas data not supported in any current browser
copyFnc = function(idxC, idxT){
canvasData.splice(idxC, 4 , textureData[idxT + 0]
, textureData[idxT + 1]
, textureData[idxT + 2]
, 255);
};
} else {
copyFnc = function(idxC, idxT){
canvasData[idxC + 0] = textureData[idxT + 0];
canvasData[idxC + 1] = textureData[idxT + 1];
canvasData[idxC + 2] = textureData[idxT + 2];
canvasData[idxC + 3] = 255;
};
}
posDelta = textureWidth*0.2/(20*1000);
//var firstFramePos = (new Date()) * posDelta;
stats = {fastCount: 0, fastSumMs: 0};
getVector = (function(){
var cache = new Array(size*size);
return function(pixel){
if (cache[pixel] === undefined){
var v = Math.floor(pixel / size);
var h = pixel - v * size;
cache[pixel] = calculateVector(h,v);
}
return cache[pixel];
};
})();
},
renderFrame: function(time){
this.RF(time);
return;
stats.firstMs = new Date() - time;
this.renderFrame = this.sumRF;
console.log(rotCache);
for (var key in rotCache){
if (rotCache[key] > 1){
console.log(rotCache[key]);
}
}
},
sumRF: function(time){
this.RF(time);
stats.fastSumMs += new Date() - time;
stats.fastCount++;
if (stats.fastSumMs > stats.firstMs) {
// alert("calc:precompute ratio = 1:"+ stats.fastCount +" "+ stats.fastSumMs +" "+ stats.firstMs);
this.renderFrame = this.RF;
}
},
turnBy: function(time){
return 24*60*60 + this.firstFramePos - time * this.posDelta
},
changeRotation: function(opts) {
ry=90+opts.tilt;
rz=180+opts.turn;
RY = (90-ry);
RZ = (180-rz);
RX = 0,RY,RZ;
},
getRadius: function() {
if (this.minX === null) {
return null;
} else {
return ((this.maxX - this.minX) + (this.maxY - this.minY)) / 2;
}
},
getTexturePointPosition: function(x, y) {
var maxDistance = 30;
for (var i = 0; i < maxDistance; i++) {
var xx
var yy;
var pos;
for (xx = x - i; xx < x + i + 1; xx++) {
yy = y - i;
pos = this.getTexturePointPositionExact(xx, yy);
if (typeof pos !== 'undefined') {
return pos;
}
yy = y + i;
pos = this.getTexturePointPositionExact(xx, yy);
if (typeof pos !== 'undefined') {
return pos;
}
}
for (yy = y - i + 1; yy < y + i; yy++) {
xx = x - i;
pos = this.getTexturePointPositionExact(xx, yy);
if (typeof pos !== 'undefined') {
return pos;
}
xx = x + i;
pos = this.getTexturePointPositionExact(xx, yy);
if (typeof pos !== 'undefined') {
return pos;
}
}
}
},
getTexturePointPositionExact: function(x, y) {
var pixel = this.positionsCache[x + y * textureWidth];
if (typeof pixel === 'undefined') {
return pixel;
} else {
return {x: pixel % size, y: Math.floor(pixel / size), pixel: pixel, originalX: x, originalY: y};
}
},
RF: function(time){
// RX, RY & RZ may change part way through if the newR? (change tilt/turn) meathods are called while
// this meathod is running so put them in temp vars at render start.
// They also need converting from degrees to radians
rx=RX*Math.PI/180;
ry=RY*Math.PI/180;
rz=RZ*Math.PI/180;
// add to 24*60*60 so it will be a day before turnBy is negative and it hits the slow negative modulo bug
var turnBy = this.turnBy(time);
var pixel = size*size;
var h2 = (textureHeight * textureHeight);
this.positionsCache = new Array(h2);
this.minX = null;
this.minY = null;
this.maxX = null;
this.maxY = null;
while(pixel--){
var vector = getVector(pixel);
if (vector !== null){
var x = pixel % size;
var y = Math.floor(pixel / size);
if (this.minX == null) {
this.minX = x;
this.maxX = x;
this.minY = y;
this.maxY = y;
} else {
if (this.minX > x) {
this.minX = x;
}
if (this.maxX < x) {
this.maxX = x;
}
if (this.minY > y) {
this.minY = y;
}
if (this.maxY < y) {
this.maxY = y;
}
}
//rotate texture on sphere
var lh = Math.floor(vector.lh * tiling.horizontal + turnBy * tiling.horizontal) % textureWidth;
/* lh = (lh < 0)
? ((textureWidth-1) - ((lh-1)%textureWidth))
: (lh % textureWidth) ;
*/
var idxC = pixel * 4;
var idxT = ((lh + (vector.lv * tiling.vertical) % h2) * 4);
this.positionsCache[Math.floor(idxT / 4)] = Math.floor(idxC / 4);
/* TODO light for alpha channel or alter s or l in hsl color value?
- fn to calc distance between two points on sphere?
- attenuate light by distance from point and rotate point separate from texture rotation
*/
// Update the values of the pixel;
canvasData[idxC + 0] = textureData[idxT + 0];
canvasData[idxC + 1] = textureData[idxT + 1];
canvasData[idxC + 2] = textureData[idxT + 2];
canvasData[idxC + 3] = 255;
// Slower?
/*
canvasImageData.data[idxC + 0] = textureImageData.data[idxT + 0];
canvasImageData.data[idxC + 1] = textureImageData.data[idxT + 1];
canvasImageData.data[idxC + 2] = textureImageData.data[idxT + 2];
canvasImageData.data[idxC + 3] = 255;
*/
// Faster?
/* copyFnc(idxC,idxT); */
}
}
gCtx.putImageData(canvasImageData, 0, 0);
}};
};
function copyImageToBuffer(aImg)
{
gImage = document.createElement('canvas');
textureWidth = aImg.naturalWidth;
textureHeight = aImg.naturalHeight;
gImage.width = textureWidth;
gImage.height = textureHeight;
gCtxImg = gImage.getContext("2d");
gCtxImg.clearRect(0, 0, textureHeight, textureWidth);
gCtxImg.drawImage(aImg, 0, 0);
textureImageData = gCtxImg.getImageData(0, 0, textureHeight, textureWidth);
hs_ch = (hs / size);
vs_cv = (vs / size);
}
this.createSphere = function (gCanvas, textureUrl, callback, tilingInfos) {
size = Math.min(gCanvas.width, gCanvas.height);
gCtx = gCanvas.getContext("2d");
canvasImageData = gCtx.createImageData(size, size);
tiling = tilingInfos;
hs_ch = (hs / size);
vs_cv = (vs / size);
V[Y]=f;
b=(2*(-f*V[Y]));
b2=Math.pow(b,2);
var img = new Image();
img.onload = function() {
copyImageToBuffer(img);
var earth = sphere();
callback(earth, textureWidth, textureHeight);
// BAD! uses 100% CPU, stats.js runs at 38FPS
/*
function renderFrame(){
earth.renderFrame(new Date);
}
setInterval(renderFrame, 0);
*/
// Better - runs at steady state
/*
(function loop(){
setTimeout(function(){
earth.renderFrame(new Date);
loop();
}, 0);
})();
*/
// Best! only renders frames that will be seen. stats.js runs at 60FPS on my desktop
};
img.setAttribute("src", textureUrl);
};
}).call(this);

View File

@ -0,0 +1,198 @@
var examples = {};
//~ examples['simple'] = function() {
//~ $('#sphere').earth3d({
//~ dragElement: $('#locations') // where do we catch the mouse drag
//~ });
//~ };
//~ examples['simple_tilted'] = function() {
//~ $('#sphere').earth3d({
//~ dragElement: $('#locations'), // where do we catch the mouse drag
//~ sphere: { // rotation and size of the planet
//~ tilt: 40,
//~ turn: 20,
//~ r: 10
//~ }
//~ });
//~ };
examples['locations'] = function() {
/* defining locations to display.
Each position must have a key, an alpha and delta position (or x and y if you want to display a static location).
Any additional key can be reached via callbacks functions.
*/
var locations = {
obj1: {
alpha: Math.PI / 4,
delta: 0,
name: '_usa_',
link: 'https://oasis.astroport.com#usa'
},
obj2: {
alpha: 1 * Math.PI / 4,
delta: -2 * Math.PI / 4,
name: '_africa_',
link: 'https://oasis.astroport.com#africa'
},
obj3: {
alpha: 2 * Math.PI / 4,
delta: 0,
name: '_hawai_',
link: 'https://oasis.astroport.com#awai'
},
obj4: {
alpha: 3 * Math.PI / 4,
delta: 3 * Math.PI / 4,
name: '_australia_',
link: 'https://oasis.astroport.com#australia'
},
obj5: {
alpha: 2.2 * Math.PI / 4,
delta: -0.9 * Math.PI / 4,
name: '_southamerica_',
link: 'https://oasis.astroport.com#southamerica'
},
obj6: {
alpha: 1.2 * Math.PI / 4,
delta: -2 * Math.PI / 4,
name: '_europe_',
link: 'https://oasis.astroport.com#europe'
}
};
$('#sphere').earth3d({
locationsElement: $('#locations'),
dragElement: $('#locations'), // where do we catch the mouse drag
locations: locations
});
};
//~ examples['flights'] = function() {
//~ /* defining locations to display.
//~ Each position must have a key, an alpha and delta position (or x and y if you want to display a static location).
//~ Any additional key can be reached via callbacks functions.
//~ */
//~ var locations = {
//~ obj1: {
//~ alpha: Math.PI / 4,
//~ delta: 0,
//~ name: '_usa_',
//~ link: 'https://oasis.astroport.com#usa'
//~ },
//~ obj2: {
//~ alpha: 1 * Math.PI / 4,
//~ delta: -2 * Math.PI / 4,
//~ name: '_africa_',
//~ link: 'https://oasis.astroport.com#africa'
//~ },
//~ obj3: {
//~ alpha: 2 * Math.PI / 4,
//~ delta: 0,
//~ name: '_hawai_',
//~ link: 'https://oasis.astroport.com#awai'
//~ },
//~ obj4: {
//~ alpha: 3 * Math.PI / 4,
//~ delta: 3 * Math.PI / 4,
//~ name: '_australia_',
//~ link: 'https://oasis.astroport.com#australia'
//~ },
//~ obj5: {
//~ alpha: 2.2 * Math.PI / 4,
//~ delta: -0.9 * Math.PI / 4,
//~ name: '_southamerica_',
//~ link: 'https://oasis.astroport.com#southamerica'
//~ },
//~ obj6: {
//~ alpha: 1.2 * Math.PI / 4,
//~ delta: -2 * Math.PI / 4,
//~ name: '_europe_',
//~ link: 'https://oasis.astroport.com#europe'
//~ },
//~ zero: {
//~ alpha: 0 * Math.PI / 4,
//~ delta: 0 * Math.PI / 4,
//~ name: '_CraftYourWorld_',
//~ link: 'https://ipfs.copylaradio.com/ipfs/QmNcNcYRDUFmR1Ey1MAyhzzZRJEi1Dfq8YXRTXq6XZ9n4A'
//~ },
//~ pi: {
//~ alpha: -3 * Math.PI / 4,
//~ delta: -3 * Math.PI / 4,
//~ name: '_OpenTW_',
//~ link: 'https://astroport.copylaradio.com'
//~ }
//~ };
//~ /* defining paths to display.
//~ Each path must have a key, an origin and a destination. The values are the location's key.
//~ You can, if you want to, define flights on these paths.
//~ Each flight has a key, a destination (the location's key) and a position.
//~ The position is the progress a fleet has made on its path.
//~ Any additional key can be reach via callbacks functions.
//~ */
//~ var paths = {
//~ path: {
//~ origin: 'obj1',
//~ destination: 'obj2',
//~ flights: {
//~ flight: {
//~ position: 0.25,
//~ destination: 'obj2',
//~ name: 'Flight 1'
//~ },
//~ flight2: {
//~ position: 0.25,
//~ destination: 'obj1',
//~ name: 'Flight 2'
//~ }
//~ }
//~ },
//~ path2: {
//~ origin: 'obj1',
//~ destination: 'obj3',
//~ flights: {
//~ flight3: {
//~ position: 0.5,
//~ destination: 'obj3',
//~ name: 'Flight 3'
//~ }
//~ }
//~ },
//~ path3: {
//~ origin: 'obj1',
//~ destination: 'obj4',
//~ flights: {
//~ flight4: {
//~ position: 0.5,
//~ destination: 'obj4',
//~ name: 'Flight 4'
//~ }
//~ }
//~ },
//~ path4: {
//~ origin: 'obj1',
//~ destination: 'obj5'
//~ },
//~ path7: {
//~ origin: 'obj1',
//~ destination: 'obj5',
//~ flights: {
//~ flight5: {
//~ position: 0.25,
//~ destination: 'obj7',
//~ name: 'Flight 5'
//~ }
//~ }
//~ }
//~ }
//~ $('#sphere').earth3d({
//~ flightsCanvas: $('#flights'),
//~ locationsElement: $('#locations'),
//~ dragElement: $('#locations'), // where do we catch the mouse drag
//~ paths: paths,
//~ locations: locations
//~ });
//~ };

BIN
www/CopierYoutube/l0g0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB