initial commit
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
.vercel
|
||||
.output
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
39
README.md
|
@ -1,3 +1,38 @@
|
|||
# www-sveltekit
|
||||
# create-svelte
|
||||
|
||||
A port of the FemtoStar website (www-new) from Sapper to SvelteKit.
|
||||
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npm create svelte@latest
|
||||
|
||||
# create a new project in my-app
|
||||
npm create svelte@latest my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
||||
|
|
18
jsconfig.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
2426
package-lock.json
generated
Normal file
29
package.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "www-sveltekit3",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fontsource/fira-mono": "^4.5.10",
|
||||
"@neoconfetti/svelte": "^1.0.0",
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte-check": "^3.6.0",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.0.3"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"d3": "^7.9.0",
|
||||
"satellite.js": "^5.0.0",
|
||||
"svelte-media-query": "^1.1.2",
|
||||
"topojson": "^3.0.2"
|
||||
}
|
||||
}
|
13
src/app.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
13
src/app.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="global.css">
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
44
src/components/FAQItem.svelte
Normal file
|
@ -0,0 +1,44 @@
|
|||
<script>
|
||||
import { onMount } from "svelte";
|
||||
|
||||
export let title;
|
||||
let hidden = false;
|
||||
|
||||
onMount(async () => {
|
||||
hidden = true;
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="collapsedFAQ">
|
||||
<div class="title" on:click={ ()=> {hidden = !hidden} }>
|
||||
<div class="symbol">{hidden ? '+' : '−'}</div> {title}
|
||||
</div>
|
||||
<div class="faqPoint" style="display: {hidden ? 'none' : 'block'}">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.collapsedFAQ{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.symbol{
|
||||
display: inline-block;
|
||||
width: 1.0em;
|
||||
}
|
||||
.title{
|
||||
color: #72bbd9;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.faqPoint{
|
||||
margin-bottom: 2.0em;
|
||||
}
|
||||
:global(.faqPoint p:first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
</style>
|
61
src/components/FemtoHeader.svelte
Normal file
|
@ -0,0 +1,61 @@
|
|||
<script>
|
||||
import FemtoStarLogo from "./FemtoStarLogo.svelte";
|
||||
</script>
|
||||
|
||||
<div class="femtoHeader">
|
||||
<div class="femtoLogotypeContainer"><FemtoStarLogo /><span class="femtoLogotype">FemtoStar</span></div>
|
||||
<h2>Satellite communications, done differently.</h2>
|
||||
|
||||
<div class="introText">
|
||||
<p>
|
||||
The FemtoStar Project is a global community developing a satellite
|
||||
constellation for secure, open, and private communications - anywhere on
|
||||
planet Earth.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: Jost;
|
||||
src: url(../../Jost.ttf);
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
background-color: #00111d;
|
||||
color: #ffffff;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.femtoLogotypeContainer{
|
||||
|
||||
}
|
||||
|
||||
.femtoLogotype{
|
||||
font-weight: 500;
|
||||
font-family: Jost, sans-serif;
|
||||
font-size: 3.0em;
|
||||
}
|
||||
|
||||
svg {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.introText {
|
||||
width: 100%;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
p {
|
||||
max-width: 512px;
|
||||
}
|
||||
</style>
|
25
src/components/FemtoStarLogo.svelte
Normal file
|
@ -0,0 +1,25 @@
|
|||
<script>
|
||||
export let width = 128;
|
||||
export let height = 100;
|
||||
export let color = "#FFFFFF";
|
||||
export let css_class = "femtostarLogo"
|
||||
</script>
|
||||
|
||||
<svg
|
||||
{width}
|
||||
{height}
|
||||
viewBox="0 0 32 25"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class={css_class}
|
||||
>
|
||||
<path
|
||||
d="M0 0H14.6453V4.5H5.05011V10.0714H14.2846V14.3571H5.05011V25H0V0Z"
|
||||
fill={color}
|
||||
/>
|
||||
<path
|
||||
d="M20.7094 15.6786L17.2104 13.1786L21.3587 8.75L15.4068 7.5L16.7054 3.5L22.2605 6.03572L21.5751 0H25.8317L25.1463 6.03572L30.7014 3.5L32 7.5L26.0481 8.75L30.1964 13.1786L26.6974 15.6786L23.7034 10.4286L20.7094 15.6786Z"
|
||||
fill={color}
|
||||
/>
|
||||
<slot />
|
||||
</svg>
|
32
src/components/Footer.svelte
Normal file
|
@ -0,0 +1,32 @@
|
|||
<script>
|
||||
import FemtoStarLogo from "./FemtoStarLogo.svelte";
|
||||
</script>
|
||||
|
||||
<div class="footer-container">
|
||||
<FemtoStarLogo height={42} width={33} color="#FFFFFF75" />
|
||||
<div class="footer-text">
|
||||
Copyright 2024 - <a href="https://matrix.to/#/!COEHOXujBzfAHAVzPG:matrix.org">Matrix</a> / <a href="https://git.femtostar.com">GitLab</a> / <a href="https://twitter.com/FemtoStar">X</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.footer-text{
|
||||
display: inline-block;
|
||||
margin-left: 1.0em;
|
||||
}
|
||||
|
||||
.footer-container {
|
||||
font-weight: 300;
|
||||
background-color: #00111d;
|
||||
color: white;
|
||||
width: 100%;
|
||||
font-size: 0.7em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
574
src/components/Globe.svelte
Normal file
|
@ -0,0 +1,574 @@
|
|||
<script>
|
||||
import * as d3 from "d3";
|
||||
import MediaQuery from "svelte-media-query";
|
||||
import * as sjs from "satellite.js";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import tles from "../../static/tle.js";
|
||||
import world110m from "../../static/world-110m.js";
|
||||
import * as topojson from "topojson";
|
||||
|
||||
let shouldLoop = true;
|
||||
let tta;
|
||||
|
||||
async function doThing() {
|
||||
let satelliteJs = sjs;
|
||||
var RADIANS = Math.PI / 180;
|
||||
var DEGREES = 180 / Math.PI;
|
||||
var R_EARTH = 6378.137; // equatorial radius (km)
|
||||
|
||||
var disablescroll = false;
|
||||
|
||||
/* =============================================== */
|
||||
/* =============== CLOCK ========================= */
|
||||
/* =============================================== */
|
||||
|
||||
/**
|
||||
* Factory function for keeping track of elapsed time and rates.
|
||||
*/
|
||||
class Clock {
|
||||
constructor() {
|
||||
this._rate = 60; // 1ms elapsed : 60sec simulated
|
||||
this._date = d3.now();
|
||||
this._elapsed = 0;
|
||||
}
|
||||
async date(timeInMs) {
|
||||
if (!arguments.length) return this._date + this._elapsed * this._rate;
|
||||
this._date = timeInMs;
|
||||
return this;
|
||||
}
|
||||
async elapsed(ms) {
|
||||
if (!arguments.length) return this._date - d3.now(); // calculates elapsed
|
||||
this._elapsed = ms;
|
||||
return this;
|
||||
}
|
||||
async rate(secondsPerMsElapsed) {
|
||||
if (!arguments.length) return this._rate;
|
||||
this._rate = secondsPerMsElapsed;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
/* =============== CONVERSION ========================= */
|
||||
/* ==================================================== */
|
||||
|
||||
async function satrecToFeature(satrec, date, props) {
|
||||
var properties = props || {};
|
||||
var positionAndVelocity = satelliteJs.propagate(satrec, date);
|
||||
var gmst = satelliteJs.gstime(date);
|
||||
var positionGd = satelliteJs.eciToGeodetic(
|
||||
positionAndVelocity.position,
|
||||
gmst
|
||||
);
|
||||
properties.height = positionGd.height;
|
||||
return {
|
||||
type: "Feature",
|
||||
properties: properties,
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [
|
||||
positionGd.longitude * DEGREES,
|
||||
positionGd.latitude * DEGREES,
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
/* ==================================================== */
|
||||
/* =============== TLE ================================ */
|
||||
/* ==================================================== */
|
||||
|
||||
/**
|
||||
* Factory function for working with TLE.
|
||||
*/
|
||||
class TLE {
|
||||
constructor() {
|
||||
this._properties;
|
||||
this._date;
|
||||
}
|
||||
async _lines(arry) {
|
||||
return arry.slice(0, 2);
|
||||
}
|
||||
async satrecs(tles) {
|
||||
return tles.map(function (d) {
|
||||
return satelliteJs.twoline2satrec.apply(null, this._lines(d));
|
||||
});
|
||||
}
|
||||
async features(tles) {
|
||||
var date = this._date || d3.now();
|
||||
|
||||
return tles.map(function (d) {
|
||||
var satrec = satelliteJs.twoline2satrec.apply(null, this._lines(d));
|
||||
return satrecToFeature(satrec, date, this._properties(d));
|
||||
});
|
||||
}
|
||||
async lines(func) {
|
||||
if (!arguments.length) return this._lines;
|
||||
this._lines = func;
|
||||
return this;
|
||||
}
|
||||
async properties(func) {
|
||||
if (!arguments.length) return this._properties;
|
||||
this._properties = func;
|
||||
return this;
|
||||
}
|
||||
async date(ms) {
|
||||
if (!arguments.length) return this._date;
|
||||
this._date = ms;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
/* =============== PARSE ============================== */
|
||||
/* ==================================================== */
|
||||
|
||||
/**
|
||||
* Parses text file string of tle into groups.
|
||||
* @return {string[][]} Like [['tle line 1', 'tle line 2'], ...]
|
||||
*/
|
||||
async function parseTle(tleString) {
|
||||
// remove last newline so that we can properly split all the lines
|
||||
var lines = tleString.replace(/\r?\n$/g, "").split(/\r?\n/);
|
||||
|
||||
return lines.reduce(function (acc, cur, index) {
|
||||
if (index % 2 === 0) acc.push([]);
|
||||
acc[acc.length - 1].push(cur);
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
/* =============== SATELLITE ========================== */
|
||||
/* ==================================================== */
|
||||
|
||||
/**
|
||||
* Satellite factory function that wraps satellitejs functionality
|
||||
* and can compute footprints based on TLE and date
|
||||
*
|
||||
* @param {string[][]} tle two-line element
|
||||
* @param {Date} date date to propagate with TLE
|
||||
*/
|
||||
function Satellite(tle, date) {
|
||||
this._satrec = satelliteJs.twoline2satrec(tle[0], tle[1]);
|
||||
this._satNum = this._satrec.satnum; // NORAD Catalog Number
|
||||
|
||||
this._altitude; // km
|
||||
this._position = {
|
||||
lat: null,
|
||||
lng: null,
|
||||
};
|
||||
this._halfAngle; // degrees
|
||||
this._date;
|
||||
this._gmst;
|
||||
|
||||
this.setDate(date);
|
||||
this.update();
|
||||
this._orbitType = this.orbitTypeFromAlt(this._altitude); // LEO, MEO, or GEO
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates satellite position and altitude based on current TLE and date
|
||||
*/
|
||||
Satellite.prototype.update = async function () {
|
||||
var positionAndVelocity = satelliteJs.propagate(this._satrec, this._date);
|
||||
var positionGd = satelliteJs.eciToGeodetic(
|
||||
positionAndVelocity.position,
|
||||
this._gmst
|
||||
);
|
||||
|
||||
this._position = {
|
||||
lat: positionGd.latitude * DEGREES,
|
||||
lng: positionGd.longitude * DEGREES,
|
||||
};
|
||||
this._altitude = positionGd.height;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {GeoJSON.Polygon} GeoJSON describing the satellite's current footprint on the Earth
|
||||
*/
|
||||
Satellite.prototype.getFootprint = function () {
|
||||
var theta = this._halfAngle * RADIANS;
|
||||
|
||||
let coreAngle = this._coreAngle(theta, this._altitude, R_EARTH) * DEGREES;
|
||||
|
||||
return d3
|
||||
.geoCircle()
|
||||
.center([this._position.lng, this._position.lat])
|
||||
.radius(coreAngle)();
|
||||
};
|
||||
|
||||
/**
|
||||
* A conical satellite with half angle casts a circle on the Earth. Find the angle
|
||||
* from the center of the earth to the radius of this circle
|
||||
* @param {number} theta: Satellite half angle in radians
|
||||
* @param {number} altitude Satellite altitude
|
||||
* @param {number} r Earth radius
|
||||
* @returns {number} core angle in radians
|
||||
*/
|
||||
Satellite.prototype._coreAngle = function (theta, altitude, r) {
|
||||
// if FOV is larger than Earth, assume it goes to the tangential point
|
||||
if (Math.sin(theta) > r / (altitude + r)) {
|
||||
return Math.acos(r / (r + altitude));
|
||||
}
|
||||
return (
|
||||
Math.abs(Math.asin(((r + altitude) * Math.sin(theta)) / r)) - theta
|
||||
);
|
||||
};
|
||||
|
||||
Satellite.prototype.halfAngle = function (halfAngle) {
|
||||
if (!arguments.length) return this._halfAngle;
|
||||
this._halfAngle = halfAngle;
|
||||
return this;
|
||||
};
|
||||
|
||||
Satellite.prototype.satNum = function (satNum) {
|
||||
if (!arguments.length) return this._satNum;
|
||||
this._satNum = satNum;
|
||||
return this;
|
||||
};
|
||||
|
||||
Satellite.prototype.altitude = function (altitude) {
|
||||
if (!arguments.length) return this._altitude;
|
||||
this._altitude = altitude;
|
||||
return this;
|
||||
};
|
||||
|
||||
Satellite.prototype.position = function (position) {
|
||||
if (!arguments.length) return this._position;
|
||||
this._position = position;
|
||||
return this;
|
||||
};
|
||||
|
||||
Satellite.prototype.getOrbitType = function () {
|
||||
return this._orbitType;
|
||||
};
|
||||
|
||||
/**
|
||||
* sets both the date and the Greenwich Mean Sidereal Time
|
||||
* @param {Date} date
|
||||
*/
|
||||
Satellite.prototype.setDate = function (date) {
|
||||
this._date = date;
|
||||
this._gmst = satelliteJs.gstime(date);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps an altitude to a type of satellite
|
||||
* @param {number} altitude (in KM)
|
||||
* @returns {'LEO' | 'MEO' | 'GEO'}
|
||||
*/
|
||||
Satellite.prototype.orbitTypeFromAlt = function (altitude) {
|
||||
this._altitude = altitude || this._altitude;
|
||||
return this._altitude < 1200
|
||||
? "LEO"
|
||||
: this._altitude > 22000
|
||||
? "GEO"
|
||||
: "MEO";
|
||||
};
|
||||
|
||||
/* =============================================== */
|
||||
/* =================== GLOBE ===================== */
|
||||
/* =============================================== */
|
||||
|
||||
// Approximate date the tle data was aquired from https://www.space-track.org/#recent
|
||||
var TLE_DATA_DATE = new Date(2015, 11, 3, 17, 36).getTime();
|
||||
|
||||
var activeClock;
|
||||
var sats;
|
||||
|
||||
var svg = d3.select("#globe");
|
||||
|
||||
var width = svg.attr("width");
|
||||
var height = svg.attr("height");
|
||||
|
||||
var projection = d3
|
||||
.geoOrthographic()
|
||||
.scale((height - 10) / 2)
|
||||
.translate([width / 2, height / 2])
|
||||
.rotate([45, -30]);
|
||||
|
||||
var geoPath = d3.geoPath().projection(projection);
|
||||
|
||||
|
||||
|
||||
function initGlobe() {
|
||||
let worldData = world110m;
|
||||
|
||||
svg
|
||||
.append("path")
|
||||
.datum({
|
||||
type: "Sphere",
|
||||
})
|
||||
.style("cursor", "grab")
|
||||
.attr("fill", "#2E86AB")
|
||||
.attr("d", geoPath);
|
||||
|
||||
svg
|
||||
.selectAll(".segment")
|
||||
.data([topojson.feature(worldData, worldData.objects.land)])
|
||||
.enter()
|
||||
.append("path")
|
||||
.style("cursor", "grab")
|
||||
.attr("class", "segment")
|
||||
.attr("d", geoPath)
|
||||
.style("stroke", "#88888800")
|
||||
.style("stroke-width", "0px")
|
||||
.style("fill", "#ffffff")
|
||||
.style("opacity", "1");
|
||||
}
|
||||
|
||||
async function updateSats(date) {
|
||||
sats.forEach(async function (sat) {
|
||||
return sat.setDate(date).update();
|
||||
});
|
||||
return sats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create satellite objects for each record in the TLEs and begin animation
|
||||
* @param {string[][]} parsedTles
|
||||
*/
|
||||
async function initSats(parsedTles) {
|
||||
activeClock = new Clock();
|
||||
|
||||
await activeClock.rate(100);
|
||||
await activeClock.date(TLE_DATA_DATE);
|
||||
|
||||
sats = await Promise.all(
|
||||
parsedTles.map(async function (tle) {
|
||||
var sat = new Satellite(tle, new Date(2015, 11, 3, 17, 36));
|
||||
sat.halfAngle(61.73);
|
||||
return sat;
|
||||
})
|
||||
);
|
||||
|
||||
if (shouldLoop) window.requestAnimationFrame(animateSats);
|
||||
return sats;
|
||||
}
|
||||
|
||||
async function draw() {
|
||||
// redrawGlobe();
|
||||
let allFootprints = svg.selectAll(".footprint");
|
||||
|
||||
let allFootprintsData = allFootprints.data(sats, async function (sat) {
|
||||
return sat.satNum();
|
||||
});
|
||||
|
||||
let allFootprintsDataJoin = allFootprintsData.join(function (enter) {
|
||||
return enter
|
||||
.append("path")
|
||||
.attr("class", function (sat) {
|
||||
return "footprint footprint--" + sat.getOrbitType();
|
||||
})
|
||||
.style("cursor", "grab");
|
||||
});
|
||||
|
||||
allFootprintsDataJoin.attr("d", function (sat) {
|
||||
return geoPath(sat.getFootprint());
|
||||
});
|
||||
|
||||
if(svg.attr("width") != width){
|
||||
svg.selectAll("*").remove();
|
||||
|
||||
width = svg.attr("width");
|
||||
height = svg.attr("height");
|
||||
|
||||
projection.scale((height - 10) / 2);
|
||||
projection.translate([width / 2, height / 2]);
|
||||
projection.rotate([45, -30]);
|
||||
|
||||
initGlobe();
|
||||
redrawGlobe();
|
||||
}
|
||||
}
|
||||
|
||||
async function redrawGlobe() {
|
||||
let allSelectedSegment = svg.selectAll(".segment");
|
||||
allSelectedSegment.attr("d", geoPath);
|
||||
}
|
||||
|
||||
var m0;
|
||||
var o0;
|
||||
|
||||
var preventScroll = function(e){
|
||||
//This function doesn't have to do anything, it just has to exist
|
||||
/*if(disablescroll){
|
||||
e.preventDefault();
|
||||
}*/
|
||||
};
|
||||
|
||||
async function mousedown(e) {
|
||||
m0 = [e.pageX, e.pageY];
|
||||
o0 = projection.rotate();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
async function mousemove(e) {
|
||||
if (m0) {
|
||||
var m1 = [e.pageX, e.pageY];
|
||||
const o1 = [
|
||||
o0[0] + (m1[0] - m0[0]) / 2.5,
|
||||
o0[1] + (m0[1] - m1[1]) / 2.5,
|
||||
];
|
||||
projection.rotate(o1);
|
||||
redrawGlobe();
|
||||
}
|
||||
}
|
||||
|
||||
async function mouseup(e) {
|
||||
if (m0) {
|
||||
mousemove(e);
|
||||
m0 = null;
|
||||
}
|
||||
}
|
||||
|
||||
function touchstart(e){
|
||||
m0 = [e.touches[0].pageX, e.touches[0].pageY];;
|
||||
o0 = projection.rotate();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function touchmove(e){
|
||||
if (m0) {
|
||||
var m1 = [e.touches[0].pageX, e.touches[0].pageY];
|
||||
const o1 = [
|
||||
o0[0] + (m1[0] - m0[0]) / 2.5,
|
||||
o0[1] + (m0[1] - m1[1]) / 2.5,
|
||||
];
|
||||
projection.rotate(o1);
|
||||
redrawGlobe();
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
function touchend(e){
|
||||
if (m0) {
|
||||
m0 = null;
|
||||
}
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
//Stop Chrome from messing up the scroll by adding an event listener on touch events
|
||||
document.addEventListener('touchstart', function(){}, {passive: false});
|
||||
document.addEventListener('touchmove', function(){}, {passive: false});
|
||||
|
||||
svg.on("mousedown", mousedown);
|
||||
d3.select(window).on("mousemove", mousemove)
|
||||
d3.select(window).on("mouseup", mouseup);
|
||||
|
||||
tta.addEventListener("mousedown", mousedown);
|
||||
tta.addEventListener("mousemove", mousemove);
|
||||
tta.addEventListener("mouseup", mouseup);
|
||||
|
||||
tta.addEventListener("touchstart", touchstart);
|
||||
tta.addEventListener("touchmove", touchmove);
|
||||
tta.addEventListener("touchend", touchend);
|
||||
|
||||
async function animateSats(elapsed) {
|
||||
var dateInMsI1 = await activeClock.elapsed(elapsed);
|
||||
var dateInMs = dateInMsI1.date();
|
||||
var date = new Date(await dateInMs);
|
||||
|
||||
updateSats(date);
|
||||
draw();
|
||||
if (shouldLoop) window.requestAnimationFrame(animateSats);
|
||||
}
|
||||
|
||||
initGlobe();
|
||||
|
||||
await initSats(await parseTle(tles));
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
doThing();
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
shouldLoop = false;
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="globeContainer">
|
||||
|
||||
<MediaQuery query="only screen and (max-device-width: 900px) and (orientation: portrait)" let:matches>
|
||||
|
||||
<div class="touch-sensor {matches ? "touch-sensor-small":"touch-sensor-large"}" bind:this={tta} />
|
||||
|
||||
<span id="no-js"><noscript>This interactive widget requires JavaScript.</noscript></span>
|
||||
|
||||
<svg id="globe" class={matches ? "globe globe-small":"globe globe-large"} width={matches ? 250:400} height={matches ? 250:400}/>
|
||||
</MediaQuery>
|
||||
|
||||
<!--<svg id="globe" {width} height={width}/>-->
|
||||
|
||||
<div class="globeText">click and drag</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#no-js{
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
opacity: 30%;
|
||||
}
|
||||
|
||||
.globeContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
background-color: #00111d;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.touch-sensor{
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
padding-top: 0.6em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.touch-sensor-small{
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
border-radius: 125px;
|
||||
}
|
||||
|
||||
.touch-sensor-large{
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
border-radius: 200px;
|
||||
}
|
||||
|
||||
:global(.footprint--LEO) {
|
||||
fill: rgba(255, 177, 64, 0.08);
|
||||
stroke: rgba(255, 177, 64, 0.5);
|
||||
}
|
||||
|
||||
.globeText {
|
||||
text-align: center;
|
||||
font-size: 0.6em;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.globe {
|
||||
z-index: 100;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.globe-small {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.globe-large {
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
24
src/components/IntroText.svelte
Normal file
|
@ -0,0 +1,24 @@
|
|||
<div class="introText">
|
||||
<p>
|
||||
The FemtoStar Project is a global community developing a satellite
|
||||
constellation for secure, open, and private communications - anywhere on
|
||||
planet Earth.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.introText {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
background-color: #00111d;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
p {
|
||||
padding-left: 2em;
|
||||
max-width: 225px;
|
||||
}
|
||||
</style>
|
114
src/components/Nav.svelte
Normal file
|
@ -0,0 +1,114 @@
|
|||
<script>
|
||||
import NavItem from "./NavItem.svelte";
|
||||
import FemtoStarLogo from "./FemtoStarLogo.svelte"
|
||||
export let segment;
|
||||
|
||||
import { page } from '$app/stores';
|
||||
</script>
|
||||
|
||||
<nav>
|
||||
<NavItem {segment} href="." matchingSegment="/" humanName="home">
|
||||
<FemtoStarLogo css_class="navlogo" height={42} width={33} color={$page.url.pathname == "/" ? "#FFFFFF" : "#FFFFFF75"}>home</FemtoStarLogo>
|
||||
</NavItem>
|
||||
|
||||
<NavItem {segment} href="./faq" matchingSegment="/faq" humanName="faq" />
|
||||
|
||||
<NavItem
|
||||
{segment}
|
||||
href="./about-contact"
|
||||
matchingSegment="/about-contact"
|
||||
humanName="about & contact"
|
||||
/>
|
||||
|
||||
<NavItem {segment} href="./donate" matchingSegment="/donate" humanName="donate" />
|
||||
|
||||
<div class="dropdown">
|
||||
<div
|
||||
class="dropdown-name"
|
||||
class:bold={segment === "global-open-infrastructure" ||
|
||||
segment === "privacy-by-design" ||
|
||||
segment === "free-open-source"}
|
||||
>
|
||||
more
|
||||
</div>
|
||||
<div class="dropdown-content">
|
||||
<NavItem
|
||||
{segment}
|
||||
href="./global-open-infrastructure"
|
||||
matchingSegment="/global-open-infrastructure"
|
||||
humanName="global open infrastructure"
|
||||
/>
|
||||
|
||||
<NavItem
|
||||
{segment}
|
||||
href="./privacy-by-design"
|
||||
matchingSegment="/privacy-by-design"
|
||||
humanName="privacy by design"
|
||||
/>
|
||||
|
||||
<NavItem
|
||||
{segment}
|
||||
href="./free-open-source"
|
||||
matchingSegment="/free-open-source"
|
||||
humanName="free and open-source"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
nav {
|
||||
font-weight: 300;
|
||||
background-color: #00111d;
|
||||
color: white;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
vertical-align: center;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
height: 100%;
|
||||
width: 49px;
|
||||
}
|
||||
|
||||
.dropdown-name {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: relative;
|
||||
right: 201px;
|
||||
box-sizing: border-box;
|
||||
background-color: #33414a;
|
||||
color: white;
|
||||
width: 250px;
|
||||
box-shadow: 0 2px 6px -0.25px #00000035;
|
||||
z-index: 1;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.dropdown:hover {
|
||||
background-color: #33414a;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
42
src/components/NavItem.svelte
Normal file
|
@ -0,0 +1,42 @@
|
|||
<script>
|
||||
export let segment;
|
||||
export let humanName;
|
||||
export let href;
|
||||
export let matchingSegment;
|
||||
|
||||
import { page } from '$app/stores';
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="navItem"
|
||||
aria-current={$page.url.pathname === matchingSegment ? "page" : undefined}
|
||||
>
|
||||
<div class="width-placeholder">{humanName}</div>
|
||||
<a rel="prefetch" {href}>{humanName == "home" ? "" : humanName}<slot /></a>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.navItem {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
.width-placeholder{
|
||||
height: 0;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.navItem[aria-current] {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
34
src/components/PartnerContainer.svelte
Normal file
|
@ -0,0 +1,34 @@
|
|||
<script>
|
||||
import Faq from "../routes/faq/+page.svelte";
|
||||
import FaqItem from "./FAQItem.svelte";
|
||||
import FemtoHeader from "./FemtoHeader.svelte";
|
||||
import FemtoStarLogo from "./FemtoStarLogo.svelte";
|
||||
import PartnerItem from "./PartnerItem.svelte"
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.partner-container{
|
||||
padding-top: 3em;
|
||||
width: 100%;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
.partner-text{
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
h2{
|
||||
margin-bottom: 0.1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="partner-container">
|
||||
<div class="partner-text">
|
||||
<h2>Our Partners</h2>
|
||||
The FemtoStar Project is working with an ever-growing community of partners to make FemtoStar a reality.<br>
|
||||
</div>
|
||||
|
||||
<PartnerItem link="https://appliedionsystems.com" alt="Logo of Applied Ion Systems" image="../../ais-logo.png" />
|
||||
<PartnerItem link="https://fossa.systems" alt="Logo of Fossa Systems" image="../../fossa-logo.png" />
|
||||
<PartnerItem link="https://nlnet.nl" alt="Logo of NLNet" image="../../nlnet-logo.png" />
|
||||
<PartnerItem link="https://pine64.org" alt="Logo of Pine64" image="../../pine-logo.png" />
|
||||
</div>
|
13
src/components/PartnerItem.svelte
Normal file
|
@ -0,0 +1,13 @@
|
|||
<script>
|
||||
export let image, alt, link;
|
||||
</script>
|
||||
|
||||
<a href={link}><img alt={alt} src={image} /></a>
|
||||
|
||||
<style>
|
||||
img{
|
||||
margin: 15px;
|
||||
height: 64px;
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
21
src/components/TalkingPointContainer.svelte
Normal file
|
@ -0,0 +1,21 @@
|
|||
<div class="talkingPointContainer">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.talkingPointContainer {
|
||||
background-color: transparent;
|
||||
display: grid;
|
||||
grid-template-columns: 30% auto;
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
|
||||
@media only screen
|
||||
and (max-device-width: 900px)
|
||||
and (orientation: portrait) {
|
||||
.talkingPointContainer {
|
||||
grid-template-columns: auto;
|
||||
grid-template-rows: 115px auto;
|
||||
}
|
||||
}
|
||||
</style>
|
40
src/components/TalkingPointContent.svelte
Normal file
|
@ -0,0 +1,40 @@
|
|||
<style>
|
||||
.talkingPointContentContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
background-color: #00111d;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.talkingPointContentContainer .talkingPointContent {
|
||||
padding-top: 1em;
|
||||
padding-left: 2em;
|
||||
font-size: 1em;
|
||||
max-width: 850px;
|
||||
}
|
||||
|
||||
:global(.talkingPointContent li:not(:last-child)) {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
@media only screen and (max-device-width: 900px) and (orientation: portrait) {
|
||||
.talkingPointContentContainer {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.talkingPointContentContainer .talkingPointContent {
|
||||
padding-top: 0;
|
||||
padding-left: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="talkingPointContentContainer">
|
||||
<div class="talkingPointContent">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
38
src/components/TalkingPointName.svelte
Normal file
|
@ -0,0 +1,38 @@
|
|||
<script>
|
||||
export let text = "replace this";
|
||||
</script>
|
||||
|
||||
<div class="talkingPointNameContainer">
|
||||
<h2 class="talkingPointName">{text}</h2>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.talkingPointNameContainer {
|
||||
width: 100%;
|
||||
height: 115px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-end;
|
||||
background-color: #00111d;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.talkingPointNameContainer .talkingPointName {
|
||||
padding-top: 1.25em;
|
||||
padding-right: 2em;
|
||||
max-width: 250px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@media only screen and (max-device-width: 900px) and (orientation: portrait) {
|
||||
.talkingPointNameContainer {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.talkingPointNameContainer .talkingPointName {
|
||||
padding-top: 0;
|
||||
padding-right: 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
16
src/lib/images/github.svg
Normal file
|
@ -0,0 +1,16 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-3 -3 30 30">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5229 6.47715 22 12 22C17.5229 22 22 17.5229 22 12C22 6.47715 17.5229 2 12 2ZM0 12C0 5.3726 5.3726 0 12 0C18.6274 0 24 5.3726 24 12C24 18.6274 18.6274 24 12 24C5.3726 24 0 18.6274 0 12Z"
|
||||
fill="rgba(0,0,0,0.7)"
|
||||
stroke="none"
|
||||
/>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M9.59162 22.7357C9.49492 22.6109 9.49492 21.4986 9.59162 19.399C8.55572 19.4347 7.90122 19.3628 7.62812 19.1833C7.21852 18.9139 6.80842 18.0833 6.44457 17.4979C6.08072 16.9125 5.27312 16.8199 4.94702 16.6891C4.62091 16.5582 4.53905 16.0247 5.84562 16.4282C7.15222 16.8316 7.21592 17.9303 7.62812 18.1872C8.04032 18.4441 9.02572 18.3317 9.47242 18.1259C9.91907 17.9201 9.88622 17.1538 9.96587 16.8503C10.0666 16.5669 9.71162 16.5041 9.70382 16.5018C9.26777 16.5018 6.97697 16.0036 6.34772 13.7852C5.71852 11.5669 6.52907 10.117 6.96147 9.49369C7.24972 9.07814 7.22422 8.19254 6.88497 6.83679C8.11677 6.67939 9.06732 7.06709 9.73672 7.99999C9.73737 8.00534 10.6143 7.47854 12.0001 7.47854C13.386 7.47854 13.8777 7.90764 14.2571 7.99999C14.6365 8.09234 14.94 6.36699 17.2834 6.83679C16.7942 7.79839 16.3844 8.99999 16.6972 9.49369C17.0099 9.98739 18.2372 11.5573 17.4833 13.7852C16.9807 15.2706 15.9927 16.1761 14.5192 16.5018C14.3502 16.5557 14.2658 16.6427 14.2658 16.7627C14.2658 16.9427 14.4942 16.9624 14.8233 17.8058C15.0426 18.368 15.0585 19.9739 14.8708 22.6234C14.3953 22.7445 14.0254 22.8257 13.7611 22.8673C13.2924 22.9409 12.7835 22.9822 12.2834 22.9982C11.7834 23.0141 11.6098 23.0123 10.9185 22.948C10.4577 22.9051 10.0154 22.8343 9.59162 22.7357Z"
|
||||
fill="rgba(0,0,0,0.7)"
|
||||
stroke="none"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
src/lib/images/svelte-logo.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" style="fill:#ff3e00"/><path d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287" style="fill:#fff"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
src/lib/images/svelte-welcome.png
Normal file
After Width: | Height: | Size: 352 KiB |
BIN
src/lib/images/svelte-welcome.webp
Normal file
After Width: | Height: | Size: 113 KiB |
18
src/routes/+error.svelte
Normal file
|
@ -0,0 +1,18 @@
|
|||
<script>
|
||||
export let status;
|
||||
export let error;
|
||||
|
||||
const dev = process.env.NODE_ENV === "development";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{status}</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>{status}</h1>
|
||||
|
||||
<p>{error.message}</p>
|
||||
|
||||
{#if dev && error.stack}
|
||||
<pre>{error.stack}</pre>
|
||||
{/if}
|
26
src/routes/+layout.svelte
Normal file
|
@ -0,0 +1,26 @@
|
|||
<script>
|
||||
import Footer from "../components/Footer.svelte";
|
||||
import Nav from "../components/Nav.svelte";
|
||||
|
||||
export let segment;
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<Nav {segment} />
|
||||
|
||||
<slot />
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
background-color: #00111d;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
min-height: 100vh;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
}
|
||||
</style>
|
121
src/routes/+page.svelte
Normal file
|
@ -0,0 +1,121 @@
|
|||
<script>
|
||||
import FemtoHeader from "../components/FemtoHeader.svelte";
|
||||
import Globe from "../components/Globe.svelte";
|
||||
import IntroText from "../components/IntroText.svelte";
|
||||
import TalkingPointContainer from "../components/TalkingPointContainer.svelte";
|
||||
import MediaQuery from "svelte-media-query";
|
||||
import TalkingPointContent from "../components/TalkingPointContent.svelte";
|
||||
import TalkingPointName from "../components/TalkingPointName.svelte";
|
||||
import PartnerContainer from "../components/PartnerContainer.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>FemtoStar</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="site">
|
||||
<div class="hero">
|
||||
<div class="container">
|
||||
<MediaQuery query="only screen and (max-device-width: 900px) and (orientation: portrait)" let:matches>
|
||||
{#if matches}
|
||||
<FemtoHeader />
|
||||
<Globe/>
|
||||
{:else}
|
||||
<Globe/>
|
||||
<FemtoHeader />
|
||||
{/if}
|
||||
</MediaQuery>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Global Open Infrastructure" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
Our satellites are open infrastructure - that means anyone can use them
|
||||
without needing to go through an official gateway. This makes FemtoStar
|
||||
a flexible, open, and inherently net-neutral network, able not just to
|
||||
connect users to the services we provide, but to serve as a platform for
|
||||
what others build on top of it.
|
||||
</p>
|
||||
<p>
|
||||
<a rel="prefetch" href="./global-open-infrastructure">Learn more →</a>
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Privacy by design, not just by promise" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
Many products only promise privacy. FemtoStar is different. Privacy and
|
||||
security are verifiably baked into every part of the system, all the way
|
||||
down to the lowest level details. We couldn't violate your privacy even
|
||||
if we wanted to.
|
||||
</p>
|
||||
<p>
|
||||
<a rel="prefetch" href="./privacy-by-design">Learn more →</a>
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName
|
||||
text="Free and open-source technology, built by a global community"
|
||||
/>
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
FemtoStar is free and open-source technology. This goes for software and
|
||||
hardware alike, and, yes, even for the satellites themselves. You have
|
||||
access to the source files, and if you want to make sure the software on
|
||||
your terminal lives up to its privacy and security claims, the source is
|
||||
freely available to use, read, or modify.
|
||||
</p>
|
||||
<p>
|
||||
<a rel="prefetch" href="./free-open-source">Learn more →</a>
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<PartnerContainer />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(.site a) {
|
||||
color: #72bbd9;
|
||||
}
|
||||
.site {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: 1024px;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.hero {
|
||||
margin-top: 3em;
|
||||
margin-bottom: 3em;
|
||||
background-color: aqua;
|
||||
}
|
||||
|
||||
.hero .container {
|
||||
background-color: aquamarine;
|
||||
display: grid;
|
||||
grid-template-columns: 400px auto;
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
|
||||
@media only screen and (max-device-width: 900px) and (orientation: portrait) {
|
||||
.hero {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.hero .container {
|
||||
grid-template-columns: auto;
|
||||
grid-template-rows: 480px auto;
|
||||
}
|
||||
}
|
||||
</style>
|
126
src/routes/about-contact/+page.svelte
Normal file
|
@ -0,0 +1,126 @@
|
|||
<script>
|
||||
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
|
||||
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
|
||||
import TalkingPointName from "../../components/TalkingPointName.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>FemtoStar - About & Contact</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="site">
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Who We Are" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
The FemtoStar Project is a global community of developers working
|
||||
towards one common goal - better, more open, and more private
|
||||
communications, anywhere on earth. At the core of the FemtoStar Project
|
||||
is FemtoStar Inc., a Canadian corporation wholly owned by FemtoStar
|
||||
Project members and tasked with ownership and operation of the FemtoStar
|
||||
satellite constellation. However, development of the hardware and
|
||||
software that make FemtoStar possible is undertaken by a global
|
||||
community of volunteer developers with experience ranging from embedded
|
||||
hardware, to secure telecommunications, to software development, to
|
||||
aerospace.
|
||||
</p>
|
||||
<p>
|
||||
The FemtoStar Project is a global endeavour. All of our members joined
|
||||
the project online, many after coming across the project on their own
|
||||
and contacting us. If you've found us, and you want to help, don't
|
||||
hesitate to contact us.
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Contact" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
Questions? Comments? Want to chat about satellites? Visit us on Matrix
|
||||
at <a
|
||||
href="https://matrix.to/#/!COEHOXujBzfAHAVzPG:matrix.org?via=matrix.org&via=lighthouse.cx&via=nordgedanken.dev"
|
||||
>#femtostar:matrix.org</a
|
||||
>. Alternatively, email us at
|
||||
<span class="j">This address has been hidden to prevent spam being received. If you are reading this website as plain text or through a screen reader, the correct address is the word hello, then the symbol spelled with the letter before B and then the letter after S, then the name of this
|
||||
website or of our satellite, then dot com. </span>h<span class="c">
|
||||
</span>e<span class="c">Lorem</span>l<span class="j">ipsum</span>l<span class="c">dolor</span>o<span class="c">sit</span> а<span class="c">amet</span>t
|
||||
f<span class="c">consectetur</span>e<span class="j">adipiscing</span>m<span class="c">elit</span>t<span class="c">Sed</span>o<span class="j">dolor</span>s<span class="c">sem</span>t<span class="c">lacinia</span>a<span class="c">ac</span>r
|
||||
d<span class="c">euismod</span>о<span class="j">vitae</span>t c<span class="c">hendrerit</span>o<span class="j">sit</span>m (if you have Tutanota, you can send end-to-end encrypted mail here too).
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="History" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
Development of what is now FemtoStar began with a project named Private
|
||||
Mobile Data Protocol (PMDP). While PMDP was intended to be a terrestrial
|
||||
network, many of the design elements now used in the FemtoStar Protocol
|
||||
were initially designed for this project. A series of tests in
|
||||
real-world urban and suburban environments throughout 2019 led to the
|
||||
conclusion that, without a dense network and an impractically large
|
||||
number of towers, reasonable coverage, even only at low speeds and only
|
||||
within city centers, was impractical with a license-free terrestrial
|
||||
network.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In early 2020, the decision was made to research the implementation of a
|
||||
PMDP-like network in a Mobile Satellite Service (MSS) system. While
|
||||
Mobile Satellite Service hardware (such as satellite phones, portable
|
||||
satellite internet terminals, and machine-to-machine/IoT satellite data
|
||||
terminals) is likely less familiar to the typical consumer than hardware
|
||||
for terrestrial mobile networks, the possibility of a satellite-based
|
||||
network offered an opportunity both to solve the coverage problem, and
|
||||
to improve the geolocation-resistance of the system (due to the
|
||||
inherently large footprint of communications satellites).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Within a month, a basic plan had been developed, and many of the
|
||||
remaining problems of the PMDP protocol (such as its lack of any
|
||||
mechanism for payment for service) had been solved. The core of the
|
||||
proposed network was a constellation of very small communications
|
||||
satellites - a design we named FemtoStar.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As the FemtoStar Project grew, development continued throughout 2020. In
|
||||
2021, FemtoStar Inc. was incorporated in Canada as an entity to own and
|
||||
operate the FemtoStar satellite constellation on behalf of the FemtoStar
|
||||
Project.
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.site {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-top: 0;
|
||||
padding-bottom: 3em;
|
||||
max-width: 1024px;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
.c{
|
||||
overflow: hidden;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
position: absolute;
|
||||
}
|
||||
.j{
|
||||
overflow: hidden;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
:global(.site a) {
|
||||
color: #72bbd9;
|
||||
}
|
||||
</style>
|
111
src/routes/donate/+page.svelte
Normal file
|
@ -0,0 +1,111 @@
|
|||
<script>
|
||||
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
|
||||
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
|
||||
import TalkingPointName from "../../components/TalkingPointName.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>FemtoStar - Donate</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="site">
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Donations" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
The FemtoStar Project is a community of volunteers funded by a grant from our partner NLnet,
|
||||
out-of-pocket by some of our members, and from donations by our community. Nobody is required
|
||||
to donate, and we currently don't have much in terms of perks for donors, but if you'd like to see
|
||||
this project succeed and are able to, consider throwing a few dollars our way or setting up
|
||||
a recurring donation through Liberapay.
|
||||
</p>
|
||||
<p>
|
||||
Donations go directly into buying hardware for the project. All of our members are volunteers, and our
|
||||
operating costs apart from hardware are low enough to cover out of pocket. Everything donated here will
|
||||
be spent on hardware to make this project possible.
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Donate via PayPal" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
Via PayPal, we accept both one-time donations directly via PayPal, and recurring donations via Liberapay
|
||||
(processed using PayPal).
|
||||
</p>
|
||||
<p>
|
||||
<b>PayPal (one-time donation):</b> <a href="https://www.paypal.com/donate/?hosted_button_id=M2N5N2B624CNQ&source=url">Click Here</a>
|
||||
</p>
|
||||
<p>
|
||||
<b>Liberapay (recurring donation):</b> <a href="https://liberapay.com/FemtoStar/donate">Click Here</a>
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Donate Cryptocurrency" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
If you would like to make a donation in cryptocurrency, please send any amount of Bitcoin or Monero to
|
||||
one of the following addresses.
|
||||
</p>
|
||||
<p>
|
||||
<b>Bitcoin:</b> <span class="crypto-address">bc1qnytm8arpuz247622yef070nvxx56qp6dqwl80s</span>
|
||||
</p>
|
||||
<p>
|
||||
<b>Monero:</b> <span class="crypto-address">83YcY9dsxARYkS4AaKVNkEJTLMQnuvuzSSij9vC7SqU7eriCpHHBsrs2ijKE6MQjobUShY4D2kjQTZ3XXp7WMtR7PdjKrx9</span>
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Want to donate another way?" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
If you would like to donate via a method not listed above (such as via
|
||||
a different payment processor or in a different cryptocurrency), please
|
||||
<a href="about-contact/">contact us</a> and we'd be glad to help set something up.
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.site {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-top: 0;
|
||||
padding-bottom: 3em;
|
||||
max-width: 1024px;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
.c{
|
||||
overflow: hidden;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
position: absolute;
|
||||
}
|
||||
.j{
|
||||
overflow: hidden;
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.crypto-address{
|
||||
overflow-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
talkingPointContainer{
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
|
||||
:global(.site a) {
|
||||
color: #72bbd9;
|
||||
}
|
||||
</style>
|
||||
|
575
src/routes/faq/+page.svelte
Normal file
|
@ -0,0 +1,575 @@
|
|||
<script>
|
||||
import FAQItem from "../../components/FAQItem.svelte";
|
||||
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
|
||||
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
|
||||
import TalkingPointName from "../../components/TalkingPointName.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>FemtoStar - FAQ</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="site">
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Products and Services" />
|
||||
<TalkingPointContent>
|
||||
<FAQItem
|
||||
title="Do you plan to offer bandwidth tiers? Will there be a data cap?"
|
||||
>
|
||||
<p>
|
||||
All FemtoStar services are delivered on a best-effort basis, at the
|
||||
highest speed technically feasible with the user's hardware and with
|
||||
network traffic at that time. We do not impose artificial restrictions
|
||||
on bandwidth. The flipside of this is that, while we do not limit you
|
||||
to a maximum speed, we cannot guarantee you will always get one
|
||||
particular speed either - getting the maximum possible at all times
|
||||
means that, unlike a service where you are constantly limited to a
|
||||
certain bandwidth even when more is possible, FemtoStar performance
|
||||
will vary. Performance at some times being lower than at some others
|
||||
should be expected.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
FemtoStar service is paid for in terms of the amount of beam time a
|
||||
session consumes - that is, how long the satellite needs to spend
|
||||
using one of its beams to transmit data for that session. This is not
|
||||
the same as the amount of time a user stays connected to the network -
|
||||
because the beam must also serve other users and any particular user's
|
||||
terminal is unlikely to be consuming the full throughput of its link
|
||||
at all times, a connected terminal consumes much less beam time than
|
||||
the amount of time it remains connected, especially when usage is
|
||||
light. What all of this means is that there is no data cap - we don't
|
||||
care about how many bytes you send through the satellite, only how
|
||||
long the satellite must spend handling your traffic.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This means that users with larger, higher-speed terminals (see the
|
||||
above point) able to transfer the same amount of data in a shorter
|
||||
period of time will pay less for the same amount of data transferred,
|
||||
as they will consume less beam time in doing so. Because beam time is
|
||||
the network's most important resource, and is the limiting factor in
|
||||
terms of network performance, we believe that charging for service in
|
||||
terms of the actual resource - beam time - being consumed is the most
|
||||
fair model for service pricing.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="Who makes FemtoStar terminals?">
|
||||
FemtoStar plans to take a hybrid approach to manufacturing and selling
|
||||
terminals. FemtoStar's higher-sales-volume "core" user terminals will be
|
||||
manufactured and sold primarily by hardware partners, allowing us to
|
||||
leverage existing manufacturing and sales infrastructure. Meanwhile,
|
||||
development and reference hardware, as well as more specialized
|
||||
terminals will be made in Canada by FemtoStar, at the same facility
|
||||
where we build our satellites. Every FemtoStar terminal is based on
|
||||
FemtoStar-developed reference designs.
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="What speeds do you anticipate being available?">
|
||||
<p>
|
||||
FemtoStar is a midband Mobile Satellite Service network, designed for
|
||||
speeds in line with other midband Mobile Satellite Service offerings.
|
||||
Here, the term "midband" refers to the level of bandwidth between
|
||||
narrowband services, designed to provide a low-speed connection to
|
||||
small, usually IoT/embedded terminals, and broadband services,
|
||||
designed to provide a high-speed connection to large, expensive, fixed
|
||||
terminals.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
While this middle category of service may be unfamiliar to those more
|
||||
used to terrestrial services, it's common in the in Mobile Satellite
|
||||
Service landscape, and is what's offered by services such as Inmarsat
|
||||
BGAN, Iridium Certus, or Thuraya IP. In these services, as in
|
||||
FemtoStar, designing for this middle category means that users can
|
||||
expect performance much better than a narrowband system, while still
|
||||
having a portable terminal much smaller than those needed for
|
||||
broadband systems. Like the aforementioned MSS options, a typical
|
||||
FemtoStar terminal should provide in the mid-hundreds of kbps, using a
|
||||
terminal roughly the size of a tablet or small laptop.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Of course, FemtoStar's design still allows for flexibility on the size
|
||||
and speed of terminals - users should be able to choose their own
|
||||
balance between speed, cost, and portability. As such, depending on
|
||||
the size of the terminal, FemtoStar should be able to accomodate
|
||||
larger terminals in the megabits-per-second range, or smaller
|
||||
terminals with reduced (if still better than typical narrowband
|
||||
offerings) speeds in a pocket-sized form factor.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="Is the FemtoStar Credit Token a cryptocurrency?">
|
||||
<p>
|
||||
No, at least not by any usual definition of the term. While they are a
|
||||
digital system used to pay for service, and while they do make use of
|
||||
cryptographic signatures for security, FemtoStar Credit Tokens are not
|
||||
transacted on a blockchain, cannot be mined, and are not intended for
|
||||
use as anything other than payment for FemtoStar service. While
|
||||
third-party users are free to buy and sell Credit Tokens at any price
|
||||
they are able to, their value in FemtoStar service is fixed.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="How do I buy FemtoStar tokens? Are they available yet?">
|
||||
<p>
|
||||
Once our network is operational, you will be able to purchase
|
||||
FemtoStar tokens from FemtoStar via a retail token sales portal, from
|
||||
a third-party reseller, in bulk from FemtoStar via a wholesale
|
||||
agreement, or from anyone else willing to sell them to you. While the
|
||||
FemtoStar Project is capable of pre-issuing tokens that will be usable
|
||||
once the network is operational, we do not currently offer pre-issued
|
||||
retail tokens to the general public, due to the inherent risk to
|
||||
consumers of purchasing a service before it is available. If you are
|
||||
interested in working with us to purchase wholesale tokens, for resale
|
||||
as a token reseller or for a large deployment of FemtoStar hardware as
|
||||
an enterprise user, please <a href="./about-contact">contact us</a>.
|
||||
</p>
|
||||
</FAQItem>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Network Architecture and Other Projects" />
|
||||
<TalkingPointContent>
|
||||
<FAQItem title="What about Starlink?">
|
||||
<p>
|
||||
<a href="https://starlink.com">Starlink</a> is a low-earth-orbit communications
|
||||
constellation developed by SpaceX. While we have a tremendous amount of
|
||||
respect for the engineering accomplishments of the Starlink network, its
|
||||
goals and those of FemtoStar are almost entirely separate. While both intend
|
||||
to provide satellite communications service using low-earth orbit constellations,
|
||||
Starlink is designed to provide consumer broadband services to large, fixed
|
||||
terminals (in the satellite industry, this is known as Fixed Satellite
|
||||
Service). FemtoStar, on the other hand, is designed for midband services
|
||||
to small and medium, portable or in-motion terminals (also known as Mobile
|
||||
Satellite Service).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
While the Starlink network is large, its architecture is traditional -
|
||||
it is designed to connect users to official ground stations providing
|
||||
official services. While there has been talk of limited use of
|
||||
Starlink for point-to-point connectivity, such as for high-speed
|
||||
securities trading, SpaceX holds complete control over use of this
|
||||
feature, and it is not a part of their consumer-facing services, nor
|
||||
is it known to be possible with their consumer hardware. FemtoStar's
|
||||
open-infrastructure architecture ensures an inherently net-neutral
|
||||
network, wherein all hardware is usable as a ground station, and even
|
||||
our own services are simply one of many a satellite is able to connect
|
||||
users to.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Starlink terminals are uniquely identified on the network, and can be
|
||||
easily geolocated by the network (whether they report their GPS
|
||||
location is currently unknown, but the network is certainly able to
|
||||
geolocate them accurately, as they are disallowed from accessing the
|
||||
network outside of the small region, or "cell", where their user's
|
||||
address is registered). Starlink users are required to provide a
|
||||
substantial amount of personal information in order to purchase
|
||||
service. Payments are handled on ground infrastructure, based on user
|
||||
accounts. FemtoStar does not require any user account whatsoever, is
|
||||
not restricted to use in a small cell, and handles payments on the
|
||||
satellite itself using FemtoStar Credit Tokens.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="What about Blockstream or Othernet?">
|
||||
<p>
|
||||
<a href="https://blockstream.com">Blockstream</a> is a cryptocurrency
|
||||
company which offers a service named
|
||||
<a href="https://blockstream.com/satellite">Blockstream Satellite</a>.
|
||||
<a href="https://othernet.is">Othernet</a> is a company which broadcasts
|
||||
data, primarily news and other text content, via satellite.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Blockstream Satellite broadcasts the Bitcoin blockchain, one-way, over
|
||||
six geostationary broadcasting satellites, and offers an API to
|
||||
transmit your own short pieces of data over the network, with payment
|
||||
in Bitcoin. While Blockstream does allow for remote access to the
|
||||
Bitcoin blockchain, it is a one-way system - it cannot be used for
|
||||
two-way communications, or to make online cryptocurrency transactions,
|
||||
unless you already have an internet connection and can connect to its
|
||||
API.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Othernet provides one-way, broadcast data service via two
|
||||
geostationary satellites. This data typically consists of news,
|
||||
Wikipedia articles, and other low-data-rate content which can be
|
||||
delivered one-way.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Both of these companies purchase time on existing geostationary
|
||||
broadcasting satellites, of the type typically used for consumer
|
||||
satellite television. These services do not support, nor is the
|
||||
hardware provided for them capable of, any form of uplink from the
|
||||
user terminal. While both services are useful as tools for broadcast
|
||||
data distribution, they are one-way, Broadcasting Satellite Service
|
||||
systems, distinct from two-way communications systems in the Fixed
|
||||
Satellite Service (such as Starlink) and Mobile Satellite Service
|
||||
(such as FemtoStar).
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem
|
||||
title="Are you sure satellites are the right way to do this? Surely a terrestrial network would be easier?"
|
||||
>
|
||||
<p>
|
||||
We're big fans of a number of the terrestrial privacy-respecting
|
||||
communications projects currently in development - in fact, FemtoStar <a
|
||||
href="./about-contact">began as a terrestrial network</a
|
||||
>, named Private Mobile Data Protocol (PMDP).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The fundamental issue of terrestrial networks is the amount of
|
||||
hardware necessary to provide adequate coverage. It has taken decades
|
||||
of development, thousands of licenses to thousands of companies in
|
||||
hundreds of countries, hundreds of billions of dollars at least, and <a
|
||||
href="https://www.mobileworldlive.com/blog/blog-global-base-station-count-7m-or-4-times-higher"
|
||||
>more than 7 million cell towers</a
|
||||
> to build mainstream cellular networks out to their current coverage,
|
||||
and even with this it's likely you still sometimes have problems getting
|
||||
cellular service. We began with the assumption that a terrestrial network
|
||||
would be the only practical solution, and extensively tested PMDP hardware
|
||||
in real-world urban and suburban environments. Eventually, even we - the
|
||||
developers of the technology - were forced to admit that it was impractical
|
||||
without an impractically dense network, even for a small, urban implementation
|
||||
- letalone regional or global coverage.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As a thought experiment in community-run terrestrial networks, next
|
||||
time you leave home, ask yourself if you are ever more than 1
|
||||
kilometer (3200 feet) away from somewhere a mesh node or base station
|
||||
in a community-run terrestrial network could be installed without
|
||||
being removed, stolen, or tampered with, and if anyone nearby would be
|
||||
willing to pay for, install, and maintain such a device. We tried
|
||||
this, with real hardware, in a real city, in 2019, and came to the
|
||||
conclusion that that, in contrast to being an easier solution, it was
|
||||
likely outright impossible in most circumstances.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Where such networks can exist, they genuinely do have some advantages
|
||||
over satellite-based networks - however, in most places, it is simply
|
||||
not realistic to build them. We found this out the hard way. It's also
|
||||
worth noting that FemtoStar can coexist with these networks
|
||||
symbiotically - where these networks can be built, given that this is
|
||||
likely to occur in clusters of nodes or base stations (such as in a
|
||||
city center) separated by a substantial distance, we believe FemtoStar
|
||||
could be extremely useful to link these sections together into larger,
|
||||
more resillient networks.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="What about mesh networks?">
|
||||
<p>
|
||||
See the above point. While mesh networks are able to partially solve
|
||||
the problem of base station range by allowing every user device to
|
||||
extend coverage, this still does not allow for coverage where there
|
||||
are no nodes. The same thought experiment applies - are you always
|
||||
within a kilometer of someone else who might have a node in the mesh?
|
||||
If you have your own node in the mesh, is there ever another node
|
||||
nearby for it to mesh with? If not, a mesh network may not be
|
||||
practical in your situation. Even where mesh networks are practical,
|
||||
FemtoStar could still be used to interconnect regions where the mesh
|
||||
is available, even when they are separated by large regions with no
|
||||
nodes.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem
|
||||
title="I've used satellite internet, and the latency is pretty bad - is this true of FemtoStar too?"
|
||||
>
|
||||
<p>
|
||||
Not to nearly the same degree. While the distance to the satellite
|
||||
does add some amount of latency due to the time taken for the signal
|
||||
to reach the satellite, the round-trip propagation time to a low-earth
|
||||
orbit satellite is a handful of milliseconds, not the hundreds of
|
||||
milliseconds familiar to users of geostationary satellite networks.
|
||||
Ping time on FemtoStar should be less than a tenth of that which a
|
||||
geostationary satellite user would experience, if even that.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="How do you plan to mitigate orbital debris?">
|
||||
<p>
|
||||
In contrast to the vast majority of small satellites, FemtoStar plans
|
||||
to include electric propulsion onboard our satellites, allowing them
|
||||
to be repositioned as needed and cleanly deorbited at end-of-life. The
|
||||
FemtoStar Project is working closely with Applied Ion Systems, a
|
||||
leading developer of open-hardware smallsat propulsion hardware, to
|
||||
develop a specialized implementation of their technology for use
|
||||
onboard the FemtoStar space vehicle. Even in the event of a thruster
|
||||
failure, the solar panel can be positioned to drastically increase
|
||||
atmospheric drag on the satellite, rapidly increasing orbital decay
|
||||
and deorbiting the satellite.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem
|
||||
title="Is this a megaconstellation? How many satellites do you need?"
|
||||
>
|
||||
<p>
|
||||
The network can theoretically work with as little as a single
|
||||
satellite, however of course this configuration does not allow for
|
||||
continuous coverage. Practical constellation layouts begin at around
|
||||
48 satellites (and include the layout shown on our <a href="./"
|
||||
>homepage</a
|
||||
>. We have also considered the possibility of starting with a larger
|
||||
constellation of up to 96 satellites, however we believe the most
|
||||
reasonable approach would be to begin with the minimum practical
|
||||
number of satellites (likely 48) and then scale up the constellation
|
||||
with new satellites as needed.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem
|
||||
title="What if a satellite fails? Will the network become unreliable?"
|
||||
>
|
||||
<p>
|
||||
The FemtoStar network provides multiple levels of protection against
|
||||
failure of spacecraft, and against failure of the network due to
|
||||
failure of a spacecraft, resulting in a resilient network able to
|
||||
mitigate and work around hardware failures onboard satellites. Each
|
||||
satellite incorporates a degree of redundancy previously seen only on
|
||||
far larger satellites, and is designed with longevity in mind. The
|
||||
network as a whole also protects against network-wide failure as a
|
||||
result of the failure of a single satellite - most regions, especially
|
||||
those with a latitude near the inclination of the satellites such as
|
||||
North America Europe, and Oceania, and much of Asia and South America
|
||||
- are covered redundantly, and even elsewhere, the "gap" caused when
|
||||
the only satellite visible to a user has failed is short - lasting
|
||||
only minutes or less before working satellites come into view.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For most users, a satellite failure would likely be noticeable only as
|
||||
a decrease in the network's coverage angle, while for those in the
|
||||
aforementioned near-inclination regions, it might not be noticeable at
|
||||
all. Finally, FemtoStar would be able to rapidly and inexpensively
|
||||
replenish its network with new satellites, either newly-launched or
|
||||
simply moved into place if already available in a storage orbit.
|
||||
</p>
|
||||
</FAQItem>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Privacy and Security" />
|
||||
<TalkingPointContent>
|
||||
<FAQItem
|
||||
title="How is using FemtoStar private when using it indicates that you are looking for privacy?"
|
||||
>
|
||||
<p>
|
||||
FemtoStar is not purely a "privacy" system - we believe it to be
|
||||
competitive with other mobile satellite options, and in all likelihood
|
||||
there will be plenty of FemtoStar users who aren't even aware of, much
|
||||
less interested in, its privacy features. We also believe there will
|
||||
be a number of FemtoStar terminals installed as a part of
|
||||
machine-to-machine data installations, as backup connections for
|
||||
enterprise networks, or as backhaul to community-run terrestrial
|
||||
networks. A user using it for privacy reasons is indistinguishable
|
||||
from any of these users.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Additionally, by this rationale, any privacy-respecting product,
|
||||
service, or system is bad for your privacy, as its use demonstrates
|
||||
that you are looking for privacy. Even if your threat model truly does
|
||||
require that you obscure even the fact that someone is using a system
|
||||
that could be used for privacy-respecting communications, FemtoStar
|
||||
still does substantially better than just about any other
|
||||
privacy-respecting communications network. For one thing, it uses a
|
||||
substantially more directional antenna than any terrestrial mobile,
|
||||
which means its transmitted signal is very weak in any direction but
|
||||
that of the satellite.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Its connection to the satellite is also is encrypted, and even to the
|
||||
satellite, it does not contain a location, terminal identifier, user
|
||||
account, or any other identifying details. The terminal never
|
||||
transmits when it has no session open with the satellite, and, unlike
|
||||
mesh network nodes, it cannot be made to transmit by the traffic of
|
||||
another user unless the terminal's owner has chosen to operate their
|
||||
own service over the network.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem
|
||||
title="Don't FemtoStar's satellites have to know where I am, based on which beam I use?"
|
||||
>
|
||||
<p>
|
||||
In theory, to some extent, but in practice, not meaningfully. In
|
||||
contrast to traditional communications satellites, a FemtoStar
|
||||
satellite, at least for transmit, does not have a consistent beam
|
||||
pattern. Instead, electronic beamforming is used to point each of only
|
||||
a handful of beams, rapidly switching beam patterns as the satellite
|
||||
jumps between active sessions. The footprints within which these beams
|
||||
are usable are hundreds of kilometers across, even at their narrowest,
|
||||
and more than 2000 kilometers long. In addition, knowing where "you"
|
||||
are, as opposed to just knowing the rough area in which one of the
|
||||
network's users is located, requires knowing who you are. As such, the
|
||||
satellite could determine that an anonymous session is within, for
|
||||
example, northern Europe, western North America, or eastern Asia, but
|
||||
not that it is in a particular country or city, and certainly not who
|
||||
that session belongs to.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="You say geolocation-resistant - is it geolocation-proof?">
|
||||
<p>
|
||||
We do not feel that we can promise that there is any two-way wireless
|
||||
communications system where it is truly impossible for an adversary to
|
||||
locate a transmitter given enough time to search for it on the ground.
|
||||
In particular, it is extremely difficult to prevent just about any
|
||||
transmitter from being detectable by a high-gain antenna at short
|
||||
range, no matter how directional or low-power the transmitter may be.
|
||||
However, we also believe that such a search would need to begin
|
||||
relatively close to any terminal it wanted to have a chance of
|
||||
finding, and that it would likely be complicated by the presence of
|
||||
more than one FemtoStar terminal in an area.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Additionally, there's the question of why finding terminals would be
|
||||
worthwhile to an attacker to begin with. Given that such an attack
|
||||
would almost certainly involve the rather labor-intensive task of
|
||||
traveling around an area of interest with a vehicle full of equipment
|
||||
looking for terminals that you cannot identify and cannot monitor the
|
||||
activity of, while also being unable to tell the difference between
|
||||
two intermittently-used terminals and one terminal which has moved, we
|
||||
do feel we can say that this attack is unlikely to fit into many
|
||||
threat models.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A FemtoStar terminal can even be used as a receive-only device if this
|
||||
is acceptable for the user's use case - in this configuration, it
|
||||
would likely be nearly impossible to geolocate, even with this sort of
|
||||
attack.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In short, we don't believe any transmitting device is truly
|
||||
geolocation-proof, but we do believe that geolocation of users can be
|
||||
made impractical for to perform at a large scale, and that its value
|
||||
to an attacker can be substantially diminished. On top of this, we do
|
||||
feel we can safely say that FemtoStar is substantially more
|
||||
geolocation-resistant than any currently-available two-way wireless
|
||||
communications system, and that it is likely that its
|
||||
geolocation-resistance could only be matched or exceeded by another
|
||||
satellite-based system including most or all of the same
|
||||
geolocation-resistance features.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem
|
||||
title="What if the FemtoStar project is taken over by someone I don't trust?"
|
||||
>
|
||||
<p>
|
||||
The FemtoStar architecture does not require that you trust the
|
||||
FemtoStar Project, even to begin with. Because the user is not
|
||||
required to trust the FemtoStar network, in order for the FemtoStar
|
||||
Project, or or an entity who had taken it over, to meaningfully
|
||||
compromise the security of FemtoStar users, many core design elements
|
||||
of the network would need to be changed, necessitating, at minimum, a
|
||||
firmware update to user terminals to accomodate substantial protocol
|
||||
changes. A new update published without
|
||||
<a href="./free-open-source">source code</a> would be immediately suspicious,
|
||||
as would a new update where the newly-released source code disabled privacy
|
||||
features.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem
|
||||
title="FemtoStar Inc. is Canadian - what if I don't trust Canada?"
|
||||
>
|
||||
<p>
|
||||
See the above point. Even if a malicious government were to take over
|
||||
the FemtoStar Project and attempt to surveil its users, they would be
|
||||
incapable of doing so without making changes that would be immediately
|
||||
obvious to users, and to our own developers in other countries.
|
||||
Additionally FemtoStar Inc. in Canada is only one part of the
|
||||
overarching FemtoStar Project - we have developers all over the world.
|
||||
</p>
|
||||
</FAQItem>
|
||||
|
||||
<FAQItem title="What if the satellites themselves are attacked?">
|
||||
<p>
|
||||
While we would never claim that it is impossible that a FemtoStar
|
||||
satellite could be compromised, either remotely or through physical
|
||||
attack, we believe the likelihood of this to be low for a number of
|
||||
reasons.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The most important point here is that FemtoStar satellites are not
|
||||
especially useful targets to an attacker. Due to not being a trusted
|
||||
part of the network, even if they themselves are fully compromised,
|
||||
they cannot be used to compromise FemtoStar users, nor would they be
|
||||
much use as part of a botnet, nor would they provide an attacker with
|
||||
any additional utility in their intended purpose (communications) than
|
||||
is available officially.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
With regards to compromising the satellites from the ground, the
|
||||
satellite's onboard software is subject to intense scrutiny, including
|
||||
through formal proofs, makes extensive use of sandboxing, and, given
|
||||
the relative simplicity of the FemtoStar protocol, presents a small
|
||||
attack surface.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In terms of physical security, while FemtoStar's placement of its
|
||||
infrastructure in orbit certainly grants it a degree of
|
||||
inaccessibility compared to terrestrial infrastructure, there are of
|
||||
course spacecraft which could conceivably reach a FemtoStar satellite,
|
||||
and could hypothetically either tamper with or replace it. However,
|
||||
tampering would require physical capture and substantial disassembly
|
||||
of the satellite, which is detectable and would result in the deletion
|
||||
of onboard keys, resulting in a tampered-with satellite being easily
|
||||
detectable from the ground (even if new software attempted to obscure
|
||||
this tampering), while a replacement satellite would lack the
|
||||
cryptographic keys of the satellite it replaced entirely.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An attacker could opt to attempt to disable, capture, or destroy a
|
||||
satellite altogether - after all, if you want to assume that truly no
|
||||
adversary is off the table, you could choose to consider even the use
|
||||
of anti-satellite weapons. However, an attacker trying to make the
|
||||
network truly unusable would need to destroy or disable not just one
|
||||
satellite, but the entire constellation, and any replacement
|
||||
satellites, and to do so in a way which obscured their involvement, a
|
||||
daunting task even for the largest possible adversaries. This type of
|
||||
attack is also immediately obvious (especially if the satellite is
|
||||
physically destroyed, resulting in the generation of orbital debris),
|
||||
and even this still does not result in an actual compromise
|
||||
(geolocation, identification, etc.) of FemtoStar users.
|
||||
</p>
|
||||
</FAQItem>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.site {
|
||||
padding-top: 0;
|
||||
padding-bottom: 3em;
|
||||
max-width: 1024px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
</style>
|
73
src/routes/free-open-source/+page.svelte
Normal file
|
@ -0,0 +1,73 @@
|
|||
<script>
|
||||
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
|
||||
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
|
||||
import TalkingPointName from "../../components/TalkingPointName.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>FemtoStar - Free & Open Source</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="site">
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName
|
||||
text="Free and open-source technology, built by a global community"
|
||||
/>
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
From the user terminal, to the spacecraft, to the ground station,
|
||||
FemtoStar is powered by free and open-source hardware and software, and
|
||||
we don't just mean the high-level stuff. Notably, in a world first for
|
||||
wide-area communications networks, even the FemtoStar air interface and
|
||||
the low-level radio firmware implementing it will be free and
|
||||
open-source software.
|
||||
</p>
|
||||
<p>
|
||||
This isn't just a technical decision. FOSS is common in the software
|
||||
world, but in the telecommunications and aerospace industries, this
|
||||
approach is highly unusual. However, for FemtoStar to succeed, we
|
||||
believe it to be critical.
|
||||
</p>
|
||||
<p>
|
||||
Releasing our designs as free and open-source allows for FemtoStar to be
|
||||
effective as a piece of open infrastructure - you can build on top of
|
||||
it, or integrate it into your own products and services. It's what gives
|
||||
FemtoStar the flexibility to work just as well as an internal backup
|
||||
network for a business as it does as a portable mobile internet
|
||||
terminal.
|
||||
</p>
|
||||
<p>
|
||||
It also allows our users to verify our claims about privacy and
|
||||
security. We do not believe that simply promising the user that their
|
||||
privacy will be preserved is adequate. Free and open-source software
|
||||
allows users to inspect and verify that features such as end-to-end
|
||||
encryption and low-level geolocation mitigations are operating as
|
||||
intended, allowing users to be sure that FemtoStar meets its privacy
|
||||
claims without the need to simply trust its developers.
|
||||
</p>
|
||||
<p>
|
||||
FemtoStar is developed and maintained by a global community of
|
||||
developers collaborating online. If you're interested in helping out,
|
||||
don't hesitate to <a rel="prefetch" href="./about-contact"
|
||||
>contact us →</a
|
||||
>.
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.site {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-top: 0;
|
||||
padding-bottom: 3em;
|
||||
max-width: 1024px;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
:global(.site a) {
|
||||
color: #72bbd9;
|
||||
}
|
||||
</style>
|
61
src/routes/global-open-infrastructure/+page.svelte
Normal file
|
@ -0,0 +1,61 @@
|
|||
<script>
|
||||
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
|
||||
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
|
||||
import TalkingPointName from "../../components/TalkingPointName.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>FemtoStar - Global Open Infrastructure</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="site">
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Global Open Infrastructure" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
Like any satellite communications system, FemtoStar uses a network of
|
||||
satellites to allow communications between terminals on earth.
|
||||
Traditional communications satellites - both those that act as simple
|
||||
repeaters, and those with onboard routing - fundamentally work by
|
||||
shuffling data to and from user terminals via a separate,
|
||||
non-user-accessible feeder link connecting them to a large, official
|
||||
ground station.
|
||||
</p>
|
||||
<p>
|
||||
FemtoStar breaks this distinction. All user hardware can be used both to
|
||||
connect to and to operate services, directly via the satellites. There
|
||||
are no special "feeder" links, and no prior arrangement with FemtoStar
|
||||
is required to operate a service. Credit processing takes place
|
||||
on-satellite, and works even when no official ground station is
|
||||
available.
|
||||
</p>
|
||||
<p>
|
||||
FemtoStar is also developing FemtoStar Real-Time Core Services (RTCS),
|
||||
an open standard for basic communications services such as internet
|
||||
access over the FemtoStar network. RTCS is intended to provide a global
|
||||
baseline in FemtoStar-based service, and will be supported by all of our
|
||||
own ground stations. We encourage RTCS adoption at third-party ground
|
||||
stations
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It's not just services either - the FemtoStar terminal will be released
|
||||
as an open standard, with an open-hardware reference design, and
|
||||
FemtoStar will work with third-party terminal manufacturers to license
|
||||
third-party terminals for use on the FemtoStar network.
|
||||
</p>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.site {
|
||||
padding-top: 0;
|
||||
padding-bottom: 3em;
|
||||
max-width: 1024px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
</style>
|
81
src/routes/privacy-by-design/+page.svelte
Normal file
|
@ -0,0 +1,81 @@
|
|||
<script>
|
||||
import TalkingPointContainer from "../../components/TalkingPointContainer.svelte";
|
||||
import TalkingPointContent from "../../components/TalkingPointContent.svelte";
|
||||
import TalkingPointName from "../../components/TalkingPointName.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>FemtoStar - Privacy by Design, not promise</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="site">
|
||||
<TalkingPointContainer>
|
||||
<TalkingPointName text="Privacy by design, not just by promise" />
|
||||
<TalkingPointContent>
|
||||
<p>
|
||||
Today, many products and services advertise user privacy as a selling
|
||||
point. Very few can be proven to live up to their claims. At FemtoStar,
|
||||
privacy isn't just a marketing promise the user is required to trust we
|
||||
will keep. It's baked into the network at every level - from
|
||||
physical-layer mitigations of low-level attacks, to end-to-end
|
||||
encryption on all connections, to anonymous payment via our credit token
|
||||
system. Don't believe us? FemtoStar's hardware and software are
|
||||
completely free and open-source, and therefore completely open to
|
||||
third-party inspection and testing.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>Verifiable anonymity</b> - In the FemtoStar network, neither users nor
|
||||
their hardware are identifiable to the network. When a user terminal connects
|
||||
to a FemtoStar satellite, it opens an anonymous, short-lived routing session,
|
||||
which is not tied to any identity, location, or other user information.
|
||||
Users don't need any form of user account to use FemtoStar - we don't even
|
||||
offer them.
|
||||
</li>
|
||||
<li>
|
||||
<b>Geolocation-resistant by design</b> - Traditional communications systems,
|
||||
such as cellular networks or existing mobile satellite systems, rely on
|
||||
tracking the user's location for basic network functions, such as setting
|
||||
up the connection or handling a moving user. FemtoStar takes advantage
|
||||
of a unique combination of cautious protocol design, low-level terminal-side
|
||||
mitigations, and the inherent properties of satellites to ensure that the
|
||||
location of terminals cannot be determined accurately.
|
||||
</li>
|
||||
<li>
|
||||
<b>End-to-end encrypted</b> - While most modern communications systems
|
||||
encrypt traffic over the air, FemtoStar goes a step further. FemtoStar
|
||||
user traffic is end-to-end encrypted, meaning not even the satellite itself
|
||||
can decrypt it. What's more, connections are direct - from user, to satellite,
|
||||
to service. Unless you're connecting to a service we provide, our ground
|
||||
infrastructure never handles your data even in an encrypted form. This
|
||||
also makes FemtoStar inherently net-neutral - after all, if we can't even
|
||||
decrypt your traffic, we can't selectively limit or throttle it either.
|
||||
</li>
|
||||
<li>
|
||||
<b>Private payments</b> - An anonymous system isn't truly anonymous if
|
||||
users must still provide identifying information in order to pay for service.
|
||||
FemtoStar's payment system is simple, flexible, and above all, private.
|
||||
User terminals provide service tokens as they consume service. These tokens
|
||||
can be bought, stored, sold, used, or transferred freely by the user. They
|
||||
are not tied to any account or identity, they do not need to be purchased
|
||||
directly from FemtoStar, and they never expire. Service is priced by satellite
|
||||
resources consumed, not by time or data usage, so you won't be charged
|
||||
more for staying connected for longer or for connecting with a faster terminal.
|
||||
</li>
|
||||
</ul>
|
||||
</TalkingPointContent>
|
||||
</TalkingPointContainer>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.site {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-top: 0;
|
||||
padding-bottom: 3em;
|
||||
max-width: 1024px;
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
</style>
|
BIN
static/Jost.ttf
Normal file
BIN
static/ais-logo.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
static/favicon.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
static/femtostar_logo.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
static/fossa-logo.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
40
static/global.css
Normal file
|
@ -0,0 +1,40 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: Roboto, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0 0 0.5em 0;
|
||||
font-weight: 400;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: menlo, inconsolata, monospace;
|
||||
font-size: calc(1em - 2px);
|
||||
color: #555;
|
||||
background-color: #f0f0f0;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.navlogo{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 400px) {
|
||||
body {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
BIN
static/logo-192.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
static/logo-512.png
Normal file
After Width: | Height: | Size: 14 KiB |
20
static/manifest.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#333333",
|
||||
"name": "TODO",
|
||||
"short_name": "TODO",
|
||||
"display": "minimal-ui",
|
||||
"start_url": "/",
|
||||
"icons": [
|
||||
{
|
||||
"src": "logo-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "logo-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
BIN
static/nlnet-logo.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
static/pine-logo.png
Normal file
After Width: | Height: | Size: 14 KiB |
3
static/robots.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
96
static/tle.js
Normal file
|
@ -0,0 +1,96 @@
|
|||
export default `1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 000.0000 0000000 000.0000 000.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 000.0000 0000000 000.0000 090.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 000.0000 0000000 000.0000 180.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 000.0000 0000000 000.0000 270.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 030.0000 0000000 000.0000 307.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 030.0000 0000000 000.0000 037.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 030.0000 0000000 000.0000 127.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 030.0000 0000000 000.0000 217.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 060.0000 0000000 000.0000 255.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 060.0000 0000000 000.0000 345.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 060.0000 0000000 000.0000 075.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 060.0000 0000000 000.0000 165.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 090.0000 0000000 000.0000 202.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 090.0000 0000000 000.0000 292.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 090.0000 0000000 000.0000 022.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 090.0000 0000000 000.0000 112.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 120.0000 0000000 000.0000 150.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 120.0000 0000000 000.0000 240.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 120.0000 0000000 000.0000 330.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 120.0000 0000000 000.0000 060.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 150.0000 0000000 000.0000 097.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 150.0000 0000000 000.0000 187.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 150.0000 0000000 000.0000 277.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 150.0000 0000000 000.0000 007.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 180.0000 0000000 000.0000 045.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 180.0000 0000000 000.0000 135.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 180.0000 0000000 000.0000 225.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 180.0000 0000000 000.0000 315.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 210.0000 0000000 000.0000 352.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 210.0000 0000000 000.0000 082.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 210.0000 0000000 000.0000 172.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 210.0000 0000000 000.0000 262.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 240.0000 0000000 000.0000 300.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 240.0000 0000000 000.0000 030.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 240.0000 0000000 000.0000 120.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 240.0000 0000000 000.0000 210.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 270.0000 0000000 000.0000 247.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 270.0000 0000000 000.0000 337.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 270.0000 0000000 000.0000 067.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 270.0000 0000000 000.0000 157.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 300.0000 0000000 000.0000 195.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 300.0000 0000000 000.0000 285.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 300.0000 0000000 000.0000 015.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 300.0000 0000000 000.0000 105.0000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 330.0000 0000000 000.0000 142.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 330.0000 0000000 000.0000 232.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 330.0000 0000000 000.0000 322.5000 14.12748000000000
|
||||
1 00000U 00000A 00000.00000000 .00000000 00000-0 00000-0 0 0000
|
||||
2 00000 53.0000 330.0000 0000000 000.0000 052.5000 14.12748000000000`
|
1
static/world-110m.js
Normal file
13
svelte.config.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import adapter from '@sveltejs/adapter-auto';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter()
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
17
vite.config.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig, searchForWorkspaceRoot } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
|
||||
server: {
|
||||
fs: {
|
||||
allow: [
|
||||
// search up for workspace root
|
||||
searchForWorkspaceRoot(process.cwd()),
|
||||
// your custom rules
|
||||
'static/',
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|