add missing files
This commit is contained in:
7
package-lock.json
generated
7
package-lock.json
generated
@@ -9,10 +9,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.5.4",
|
"version": "5.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||||
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
// how? do "perfect negotiation" with bootstrap peer. All logic here moves to BP.
|
// how? do "perfect negotiation" with bootstrap peer. All logic here moves to BP.
|
||||||
|
|
||||||
import { generateID } from "IDUtils";
|
import { generateID } from "IDUtils";
|
||||||
import { log } from "log";
|
import { log, logID } from "log";
|
||||||
|
|
||||||
// Use a broadcast channel to only have one peer manager for multiple tabs,
|
// Use a broadcast channel to only have one peer manager for multiple tabs,
|
||||||
// then we won't need to have a session ID as all queries for a peerID will be coming from the same peer manager
|
// then we won't need to have a session ID as all queries for a peerID will be coming from the same peer manager
|
||||||
@@ -29,6 +29,15 @@ export class PeerManager {
|
|||||||
connectPromise: { resolve: Function, reject: Function } | null = null;
|
connectPromise: { resolve: Function, reject: Function } | null = null;
|
||||||
|
|
||||||
pingPeers: RTCPeerConnection[] = [];
|
pingPeers: RTCPeerConnection[] = [];
|
||||||
|
watchdogPeriodSeconds: number = 10;
|
||||||
|
|
||||||
|
// async watchdog() {
|
||||||
|
// // Check that we're connected to at least N peers. If not, reconnect to the bootstrap server.
|
||||||
|
|
||||||
|
// if (this.peers.size === 0) {
|
||||||
|
// await this.sendHello2();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
websocketSend(message: any) {
|
websocketSend(message: any) {
|
||||||
if (!this.websocket) {
|
if (!this.websocket) {
|
||||||
@@ -168,18 +177,55 @@ export class PeerManager {
|
|||||||
this.routingTable = new Map();
|
this.routingTable = new Map();
|
||||||
this.userID = userID;
|
this.userID = userID;
|
||||||
this.peerID = peerID;
|
this.peerID = peerID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnect() {
|
||||||
|
this.websocket?.close();
|
||||||
|
for (let peer of this.peers.values()) {
|
||||||
|
peer.disconnect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
|
// setInterval(this.watchdog.bind(this), this.watchdogPeriodSeconds * 1000);
|
||||||
|
|
||||||
|
setInterval(()=>{
|
||||||
|
|
||||||
|
|
||||||
|
if (!this.isBootstrapPeer && this.peers.size === 0) {
|
||||||
|
console.log.apply(null, log("No peers connected :("));
|
||||||
|
if (this.websocket?.readyState === WebSocket.OPEN) {
|
||||||
|
this.sendHello2();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let output = `local peerID:${logID(this.peerID)}` + "\n";
|
||||||
|
for (let [peerID, peer] of this.peers) {
|
||||||
|
output += `${logID(peerID)}: ${peer.rtcPeer?.connectionState}` + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log.apply(null, log(output));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
let connectPromise = new Promise((resolve, reject) => {
|
let connectPromise = new Promise((resolve, reject) => {
|
||||||
this.connectPromise = { resolve, reject };
|
this.connectPromise = { resolve, reject };
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.websocket = new WebSocket(
|
let hostname = globalThis?.location?.hostname ?? 'ddln.app';
|
||||||
`wss://${window.location.hostname}:${window.location.port}/ws`,
|
|
||||||
);
|
let port = globalThis?.location?.port ?? '443';
|
||||||
|
|
||||||
|
let wsURL = `wss://${hostname}:${port}/ws`;
|
||||||
|
|
||||||
|
console.log(`wsURL: ${wsURL}`);
|
||||||
|
|
||||||
|
this.websocket = new WebSocket(wsURL);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
throw new Error(error.message);
|
throw new Error(error.message);
|
||||||
}
|
}
|
||||||
@@ -237,14 +283,15 @@ export class PeerManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async disconnect(remotePeerID: string) {
|
async disconnectFromPeer(remotePeerID: string) {
|
||||||
let peer = this.peers.get(remotePeerID);
|
let peer = this.peers.get(remotePeerID);
|
||||||
|
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
console.log.apply(null, log(`PeerManager.disconnect: couln't find peer ${remotePeerID}`));
|
console.log.apply(null, log(`PeerManager.disconnect: couldn't find peer ${remotePeerID}`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log.apply(null, log(`PeerManager.disconnect: disconnecting peer ${remotePeerID}`));
|
||||||
await peer.disconnect();
|
await peer.disconnect();
|
||||||
this.peers.delete(remotePeerID);
|
this.peers.delete(remotePeerID);
|
||||||
}
|
}
|
||||||
@@ -295,8 +342,6 @@ export class PeerManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
type: string;
|
type: string;
|
||||||
from_peer: string;
|
from_peer: string;
|
||||||
@@ -306,98 +351,6 @@ interface Message {
|
|||||||
peer_message: any;
|
peer_message: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Initially this wil be the bootstrap peer, We'll keep a connection to it and it will keep a list of all connected peers.
|
|
||||||
// // Eventually we will replace this with connecting via other peers.
|
|
||||||
// class Signaler {
|
|
||||||
// websocket: WebSocket;
|
|
||||||
|
|
||||||
// sessionID: string;
|
|
||||||
// userID: string;
|
|
||||||
// peerID: string;
|
|
||||||
// bootstrapPeerID: string = "";
|
|
||||||
// private isBootstrapPeer: boolean = false;
|
|
||||||
// private onConnected: Function;
|
|
||||||
// peerRoutes: Map<string, PeerConnection> = new Map();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// constructor(userID: string, peerID: string, isBootstrapPeer: boolean, onConnected: Function) {
|
|
||||||
// this.onConnected = onConnected;
|
|
||||||
// this.isBootstrapPeer = isBootstrapPeer;
|
|
||||||
// this.sessionID = generateID();
|
|
||||||
// this.userID = userID;
|
|
||||||
// this.peerID = peerID;
|
|
||||||
|
|
||||||
|
|
||||||
// try {
|
|
||||||
// this.websocket = new WebSocket(
|
|
||||||
// `wss://${window.location.hostname}:${window.location.port}/ws`,
|
|
||||||
// );
|
|
||||||
// } catch (error: any) {
|
|
||||||
// throw new Error(error.message);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this.websocket.onopen = async (event) => {
|
|
||||||
// console.log.apply(null, log("signaler:ws:onopen");
|
|
||||||
// await this.sendHello2();
|
|
||||||
// };
|
|
||||||
|
|
||||||
// this.websocket.onmessage = this.onMessage.bind(this);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// connect() {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// onMessage(event: MessageEvent) {
|
|
||||||
// let messageJSON = event.data;
|
|
||||||
// let message: any = null;
|
|
||||||
|
|
||||||
// try {
|
|
||||||
// message = JSON.parse(messageJSON);
|
|
||||||
// } catch (e) {
|
|
||||||
// console.log.apply(null, log(e);
|
|
||||||
// throw new Error();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log.apply(null, log("->signaler:", message);
|
|
||||||
|
|
||||||
// if (message.type === "hello2") {
|
|
||||||
|
|
||||||
// if (!this.isBootstrapPeer) {
|
|
||||||
// this.bootstrapPeerID = message.bootstrapPeers[0];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this.onConnected(this.bootstrapPeerID);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (message.type == "peer_message") {
|
|
||||||
|
|
||||||
// if (message.message.type = "rtc_connect") {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let connection = this.peerRoutes.get(message.from_peer);
|
|
||||||
// if (!connection) {
|
|
||||||
// console.log.apply(null, log("Can't find peer for peer message:", message);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// connection.onSignalerMessage(message);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// route(remotePeerID:string, peerConnection:PeerConnection) {
|
|
||||||
// this.peerRoutes.set(remotePeerID, peerConnection)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // sendPeerMessage
|
|
||||||
// }
|
|
||||||
|
|
||||||
class PeerConnection {
|
class PeerConnection {
|
||||||
private remotePeerID: string;
|
private remotePeerID: string;
|
||||||
// private signaler: Signaler;
|
// private signaler: Signaler;
|
||||||
@@ -462,7 +415,7 @@ class PeerConnection {
|
|||||||
if (!this.dataChannel) {
|
if (!this.dataChannel) {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
console.log.apply(null, log("data channel is open!"));
|
console.log.apply(null, log("data channel is open to: ", this.remotePeerID, " from: ", this.peerManager.peerID));
|
||||||
this.send({ type: "hello datachannel", from: this.peerManager.peerID, to: this.remotePeerID});
|
this.send({ type: "hello datachannel", from: this.peerManager.peerID, to: this.remotePeerID});
|
||||||
// this.dataChannel?.send(`{typeHello datachannel from: ${this.peerManager.peerID}`);
|
// this.dataChannel?.send(`{typeHello datachannel from: ${this.peerManager.peerID}`);
|
||||||
|
|
||||||
@@ -480,6 +433,11 @@ class PeerConnection {
|
|||||||
console.log.apply(null, log("->datachannel: ", e.data))
|
console.log.apply(null, log("->datachannel: ", e.data))
|
||||||
this.onMessage(e.data);
|
this.onMessage(e.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.dataChannel.onclose = (e: Event) => {
|
||||||
|
console.log.apply(null, log(`datachannel from peer ${this.remotePeerID} closed, disconnecting peer.`));
|
||||||
|
this.peerManager.disconnectFromPeer(this.remotePeerID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect() {
|
async connect() {
|
||||||
@@ -494,10 +452,10 @@ class PeerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When the connection is closed, tell the peer manager that this connection has gone away
|
// When the connection is closed, tell the peer manager that this connection has gone away
|
||||||
if (this.rtcPeer.connectionState === "disconnected") {
|
if (this.rtcPeer.connectionState === "failed") {
|
||||||
this.peerManager.onPeerDisconnected(this.remotePeerID);
|
this.peerManager.onPeerDisconnected(this.remotePeerID);
|
||||||
|
|
||||||
// window.setTimeout(async () => { await this.peerManager.connectToPeer(this.remotePeerID) }, 10_000);
|
// globalThis.setTimeout(async () => { await this.peerManager.connectToPeer(this.remotePeerID) }, 10_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.rtcPeer.connectionState === "connected") {
|
if (this.rtcPeer.connectionState === "connected") {
|
||||||
@@ -640,8 +598,9 @@ class PeerConnection {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async disconnect() {
|
disconnect() {
|
||||||
this.rtcPeer?.close();
|
this.rtcPeer?.close();
|
||||||
|
this.rtcPeer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
send(message: any) {
|
send(message: any) {
|
||||||
@@ -714,167 +673,4 @@ class PeerConnection {
|
|||||||
|
|
||||||
// this.peerManger.onMessage(this.remotePeerID, message);
|
// this.peerManger.onMessage(this.remotePeerID, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// export class PeerConnection2 {
|
|
||||||
|
|
||||||
// id: string;
|
|
||||||
|
|
||||||
// private makingOffer:boolean = false;
|
|
||||||
// private ignoreOffer:boolean = false;
|
|
||||||
|
|
||||||
// rtcPeer: RTCPeerConnection;
|
|
||||||
|
|
||||||
// signaler:WebSocket;
|
|
||||||
|
|
||||||
// static config = {
|
|
||||||
// iceServers: [
|
|
||||||
// { urls: "stun:stun.l.google.com" },
|
|
||||||
// { urls: "stun:stun1.l.google.com" },
|
|
||||||
// { urls: "stun:stun2.l.google.com" },
|
|
||||||
// { urls: "stun:stun3.l.google.com" },
|
|
||||||
// { urls: "stun:stun4.l.google.com" },
|
|
||||||
// ],
|
|
||||||
// };
|
|
||||||
|
|
||||||
// constructor(remotePeerID: string, signaler:WebSocket) {
|
|
||||||
// this.id = remotePeerID;
|
|
||||||
|
|
||||||
// this.rtcPeer = new RTCPeerConnection(PeerConnection2.config);
|
|
||||||
|
|
||||||
// this.signaler = signaler;;
|
|
||||||
|
|
||||||
// this.rtcPeer.onnegotiationneeded = async () => {
|
|
||||||
// try {
|
|
||||||
// this.makingOffer = true;
|
|
||||||
// await this.rtcPeer.setLocalDescription();
|
|
||||||
// signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription }));
|
|
||||||
// } catch (err) {
|
|
||||||
// console.error(err);
|
|
||||||
// } finally {
|
|
||||||
// this.makingOffer = false;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// this.rtcPeer.onicecandidate = ({ candidate }) => signaler.send(JSON.stringify({ candidate }));
|
|
||||||
|
|
||||||
// this.ignoreOffer = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// onSignallerMessage = async ({ data: { description, candidate } }: MessageEvent) => {
|
|
||||||
// try {
|
|
||||||
// if (description) {
|
|
||||||
// // const offerCollision =
|
|
||||||
// // description.type === "offer" &&
|
|
||||||
// // (this.makingOffer || this.rtcPeer.signalingState !== "stable");
|
|
||||||
|
|
||||||
// // this.ignoreOffer = !polite && offerCollision;
|
|
||||||
// if (this.ignoreOffer) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// await this.rtcPeer.setRemoteDescription(description);
|
|
||||||
// if (description.type === "offer") {
|
|
||||||
// await this.rtcPeer.setLocalDescription();
|
|
||||||
// this.signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription }));
|
|
||||||
// }
|
|
||||||
// } else if (candidate) {
|
|
||||||
// try {
|
|
||||||
// await this.rtcPeer.addIceCandidate(candidate);
|
|
||||||
// } catch (err) {
|
|
||||||
// if (!this.ignoreOffer) {
|
|
||||||
// throw err;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// console.error(err);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // const config = {
|
|
||||||
// // iceServers: [{ urls: "stun:stun.mystunserver.tld" }],
|
|
||||||
// // };
|
|
||||||
|
|
||||||
// // let polite = true;
|
|
||||||
|
|
||||||
// // const signaler = new SignalingChannel();
|
|
||||||
// // const signaler: any = {}
|
|
||||||
// // const rtcPeer = new RTCPeerConnection(config);
|
|
||||||
|
|
||||||
// // // const constraints = { audio: true, video: true };
|
|
||||||
// // const selfVideo = document.querySelector("video.selfview");
|
|
||||||
// // const remoteVideo = document.querySelector("video.remoteview");
|
|
||||||
|
|
||||||
// // async function start() {
|
|
||||||
// // try {
|
|
||||||
// // const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
||||||
|
|
||||||
// // for (const track of stream.getTracks()) {
|
|
||||||
// // pc.addTrack(track, stream);
|
|
||||||
// // }
|
|
||||||
// // selfVideo.srcObject = stream;
|
|
||||||
// // } catch (err) {
|
|
||||||
// // console.error(err);
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // rtcPeer.ontrack = ({ track, streams }) => {
|
|
||||||
// // track.onunmute = () => {
|
|
||||||
// // if (remoteVideo.srcObject) {
|
|
||||||
// // return;
|
|
||||||
// // }
|
|
||||||
// // remoteVideo.srcObject = streams[0];
|
|
||||||
// // };
|
|
||||||
// // };
|
|
||||||
|
|
||||||
// // makingOffer = false;
|
|
||||||
|
|
||||||
// // rtcPeer.onnegotiationneeded = async () => {
|
|
||||||
// // try {
|
|
||||||
// // // makingOffer = true;
|
|
||||||
// // await rtcPeer.setLocalDescription();
|
|
||||||
// // signaler.send({ description: rtcPeer.localDescription });
|
|
||||||
// // } catch (err) {
|
|
||||||
// // console.error(err);
|
|
||||||
// // } finally {
|
|
||||||
// // makingOffer = false;
|
|
||||||
// // }
|
|
||||||
// // };
|
|
||||||
|
|
||||||
// // rtcPeer.onicecandidate = ({ candidate }) => signaler.send({ candidate });
|
|
||||||
|
|
||||||
// // let ignoreOffer = false;
|
|
||||||
|
|
||||||
// // signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => {
|
|
||||||
// // try {
|
|
||||||
// // if (description) {
|
|
||||||
// // const offerCollision =
|
|
||||||
// // description.type === "offer" &&
|
|
||||||
// // // (makingOffer || rtcPeer.signalingState !== "stable");
|
|
||||||
|
|
||||||
// // ignoreOffer = !polite && offerCollision;
|
|
||||||
// // if (ignoreOffer) {
|
|
||||||
// // return;
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // await rtcPeer.setRemoteDescription(description);
|
|
||||||
// // if (description.type === "offer") {
|
|
||||||
// // await rtcPeer.setLocalDescription();
|
|
||||||
// // signaler.send({ description: rtcPeer.localDescription });
|
|
||||||
// // }
|
|
||||||
// // } else if (candidate) {
|
|
||||||
// // try {
|
|
||||||
// // await rtcPeer.addIceCandidate(candidate);
|
|
||||||
// // } catch (err) {
|
|
||||||
// // if (!ignoreOffer) {
|
|
||||||
// // throw err;
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // } catch (err) {
|
|
||||||
// // console.error(err);
|
|
||||||
// // }
|
|
||||||
// // };
|
|
||||||
2157
src/bootstrap_main.ts
Normal file
2157
src/bootstrap_main.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,10 @@ let logLines: string[] = [];
|
|||||||
let logLength = 100;
|
let logLength = 100;
|
||||||
let logVisible = false;
|
let logVisible = false;
|
||||||
|
|
||||||
|
export function logID(ID: string) {
|
||||||
|
return ID.substring(0, 5);
|
||||||
|
}
|
||||||
|
|
||||||
export function setLogVisibility(visible:boolean) {
|
export function setLogVisibility(visible:boolean) {
|
||||||
logVisible = visible;
|
logVisible = visible;
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/main2.ts
12
src/main2.ts
@@ -35,7 +35,7 @@ import { openDatabase, getData, addData, addDataArray, clearData, deleteData, me
|
|||||||
import { generateID } from "IDUtils";
|
import { generateID } from "IDUtils";
|
||||||
import { PeerManager } from "PeerManager";
|
import { PeerManager } from "PeerManager";
|
||||||
|
|
||||||
import {log, renderLog, setLogVisibility} from "log"
|
import {log, logID, renderLog, setLogVisibility} from "log"
|
||||||
|
|
||||||
// import {PeerConnection} from "webRTC";
|
// import {PeerConnection} from "webRTC";
|
||||||
|
|
||||||
@@ -109,12 +109,6 @@ function uuidToBase58(uuid: string): string {
|
|||||||
return encodeBase58(bytes);
|
return encodeBase58(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function logID(ID: string) {
|
|
||||||
return ID.substring(0, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// function log(message:string) {
|
// function log(message:string) {
|
||||||
// console.log.apply(null, log(message);
|
// console.log.apply(null, log(message);
|
||||||
// let log = document.getElementById("log");
|
// let log = document.getElementById("log");
|
||||||
@@ -175,8 +169,8 @@ window.addEventListener('scroll', () => {
|
|||||||
|
|
||||||
// Check if scrolled to bottom
|
// Check if scrolled to bottom
|
||||||
if (scrollPoint >= totalPageHeight) {
|
if (scrollPoint >= totalPageHeight) {
|
||||||
console.log.apply(null, log('Scrolled to the bottom!'));
|
// console.log.apply(null, log('Scrolled to the bottom!'));
|
||||||
console.log.apply(null, log(scrollPoint, totalPageHeight));
|
// console.log.apply(null, log(scrollPoint, totalPageHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
1
static/main2.d.ts
vendored
Normal file
1
static/main2.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
1623
static/main2.js
Normal file
1623
static/main2.js
Normal file
File diff suppressed because it is too large
Load Diff
1
static/main2.js.map
Normal file
1
static/main2.js.map
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user