Removed GopherJS, basic frontend completed, need backend changes for

torrent storage
This commit is contained in:
2017-11-30 18:12:11 -05:00
parent 67fdef16b1
commit e98ad2cc88
69321 changed files with 5498914 additions and 337 deletions

5
.gitignore vendored
View File

@@ -10,3 +10,8 @@ output.json
configtest.toml configtest.toml
.idea/workspace.xml .idea/workspace.xml
.idea/vcs.xml .idea/vcs.xml
1905POD014.mp3.torrent
bolter.exe
mythbuntu-16.04.3-desktop-i386.iso.torrent
ubuntu-17.04-desktop-amd64.iso (1).torrent
ubuntu.torrent

23
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,23 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"taskName": "Run Program",
"type": "shell",
"command": "go run main.go storage.go settings.go",
"problemMatcher": [
"$go"
]
},
{
"taskName": "Build GopherJS",
"type": "shell",
"command": "C:/Users/deranjer/go/bin/gopherjs.exe build C:/Users/deranjer/GoglandProjects/torrent-project/public/static/js/frontend-websocket.go",
"problemMatcher": [
"$go"
]
}
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# goTorrent
Torrent server with web client written in Go and React

153
main.go
View File

@@ -3,19 +3,22 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"html/template" "html/template"
"io"
"log" "log"
"net/http" "net/http"
"os" "os"
"strings" "strings"
"time" "time"
"github.com/anacrolix/torrent" "github.com/anacrolix/torrent"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
//"github.com/anacrolix/dht" //"github.com/anacrolix/dht"
"encoding/json"
"github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/metainfo"
"github.com/boltdb/bolt" "github.com/boltdb/bolt"
"encoding/json"
) )
var ( var (
@@ -31,71 +34,115 @@ var upgrader = websocket.Upgrader{
WriteBufferSize: 1024, WriteBufferSize: 1024,
} }
type torrentList struct { //helps create the JSON structure that vuetable expects to recieve type torrentList struct { //helps create the JSON structure that react expects to recieve
Totaltorrents int `json:"total"` Totaltorrents int `json:"total"`
ClientDBstruct []clientDB `json:"data"` ClientDBstruct []clientDB `json:"data"`
} }
type clientDB struct { type clientDB struct {
TorrentName string `json:"TorrentName"` TorrentName string `json:"TorrentName"`
ChunksWritten int64 DownloadedSize int64 `json:"DownloadedSize"`
ChunksRead int64 Size int64 `json:"Size"`
BytesWritten int64 DownloadSpeed float32 `json:"DownloadSpeed"`
BytesRead int64 UploadSpeed float32 `json:"UploadSpeed"`
DataBytesWritten int64 DataBytesWritten int64
DataBytesRead int64 DataBytesRead int64
ActivePeers int ActivePeers int `json:"ActivePeers"`
TotalPeers int `json:"TotalPeers"` TotalPeers int `json:"TotalPeers"`
TorrentHashString string TorrentHashString string `json:"TorrentHashString"`
PercentDone int64 `json:"Done"`
TorrentHash metainfo.Hash TorrentHash metainfo.Hash
StoragePath string `json:"StorageLocation"` StoragePath string `json:"StorageLocation"`
DateAdded string DateAdded string
KnownSwarm []torrent.Peer
Status string `json:"Status"`
BytesCompleted int64
UpdatedAt time.Time
} }
func calculateTorrentSpeed(t *torrent.Torrent, c *clientDB) {
now := time.Now()
bytes := t.BytesCompleted()
if !c.UpdatedAt.IsZero() {
dt := float32(now.Sub(c.UpdatedAt))
db := float32(bytes - c.BytesCompleted)
rate := db * (float32(time.Second) / dt)
if rate >= 0 {
c.DownloadSpeed = rate
}
}
c.UpdatedAt = now
}
func calculateTorrentStatus(t *torrent.Torrent, c *clientDB) {
if t.Seeding() {
c.Status = "Seeding"
} else if t.Stats().ActivePeers > 0 && t.BytesMissing() > 0 {
c.Status = "Downloading"
} else if t.Stats().ActivePeers == 0 {
c.Status = "Awaiting Peers"
} else {
c.Status = "Unknown"
}
}
func serveHome(w http.ResponseWriter, r *http.Request) { func serveHome(w http.ResponseWriter, r *http.Request) {
s1, _ := template.ParseFiles("templates/home.tmpl") s1, _ := template.ParseFiles("templates/home.tmpl")
s1.ExecuteTemplate(w, "base", map[string]string{"APP_ID": APP_ID}) s1.ExecuteTemplate(w, "base", map[string]string{"APP_ID": APP_ID})
} }
func startTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage *TorrentLocal, Config torrent.Config, torrentDbStorage *bolt.DB){ func startTorrent(clientTorrent *torrent.Torrent, torrentLocalStorage *TorrentLocal, Config torrent.Config, torrentDbStorage *bolt.DB, torrentLocal []*TorrentLocal, tclient *torrent.Client) {
<-clientTorrent.GotInfo() //waiting for all of the torrent info to be downloaded <-clientTorrent.GotInfo() //waiting for all of the torrent info to be downloaded
var TempHash metainfo.Hash
torrentLocalStorage.Hash = clientTorrent.InfoHash() // we will store the infohash to add it back later on client restart (if needed) TempHash = clientTorrent.InfoHash()
fmt.Println(clientTorrent.Info().Source)
torrentLocalStorage.Hash = TempHash.String() // we will store the infohash to add it back later on client restart (if needed)
torrentLocalStorage.DateAdded = time.Now().Format("Jan _2 2006") torrentLocalStorage.DateAdded = time.Now().Format("Jan _2 2006")
torrentLocalStorage.StoragePath = Config.DataDir //TODO check full path information for torrent storage torrentLocalStorage.StoragePath = Config.DataDir //TODO check full path information for torrent storage
torrentLocalStorage.TorrentName = clientTorrent.Name() torrentLocalStorage.TorrentName = clientTorrent.Name()
torrentLocalStorage.TorrentStatus = "downloading" //by default start all the torrents as downloading.
fmt.Printf("%+v\n", torrentLocalStorage) fmt.Printf("%+v\n", torrentLocalStorage)
addTorrentLocalStorage(torrentDbStorage, torrentLocalStorage) //writing all of the data to the database addTorrentLocalStorage(torrentDbStorage, torrentLocalStorage) //writing all of the data to the database
clientTorrent.DownloadAll() //starting the download clientTorrent.DownloadAll() //starting the download
createRunningTorrentArray(tclient, torrentLocal)
} }
func createRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*TorrentLocal) (RunningTorrentArray []clientDB) { func createRunningTorrentArray(tclient *torrent.Client, TorrentLocalArray []*TorrentLocal) (RunningTorrentArray []clientDB) {
for _, element := range TorrentLocalArray { //re-adding all the torrents we had stored from last shutdown for _, element := range TorrentLocalArray { //re-adding all the torrents we had stored from last shutdown
singleTorrent, _ := tclient.AddTorrentInfoHash(element.Hash) //adding back in the torrents by hash elementMagnet := "magnet:?xt=urn:btih:" + element.Hash
singleTorrent, _ := tclient.AddMagnet(elementMagnet) //adding back in the torrents by hash
fmt.Println("Here...", elementMagnet)
//<-singleTorrent.GotInfo()
//singleTorrent.DownloadAll()
fmt.Println("Past...")
fullClientDB := new(clientDB) fullClientDB := new(clientDB)
fullStruct := singleTorrent.Stats() fullStruct := singleTorrent.Stats()
fullClientDB.TorrentHash = element.Hash //bytesMissing := singleTorrent.BytesMissing()
fullClientDB.ChunksWritten = fullStruct.ConnStats.ChunksWritten //bytesTotal := singleTorrent.Length()
fullClientDB.ChunksRead = fullStruct.ConnStats.ChunksRead //bytesCompleted := singleTorrent.BytesCompleted()
fullClientDB.BytesWritten = fullStruct.ConnStats.BytesWritten //
fullClientDB.BytesRead = fullStruct.ConnStats.BytesRead calculateTorrentSpeed(singleTorrent, fullClientDB) //Setting the downloadSpeed for the torrent
fullClientDB.DataBytesWritten = fullStruct.ConnStats.DataBytesWritten var TempHash metainfo.Hash
fullClientDB.DataBytesRead = fullStruct.ConnStats.DataBytesRead TempHash = singleTorrent.InfoHash()
//fullClientDB.DownloadedSize = singleTorrent.BytesCompleted()
//fullClientDB.Size = bytesTotal
fullClientDB.TorrentHash = TempHash
//fullClientDB.PercentDone = 1 - (bytesMissing / bytesTotal)
//fullClientDB.DataBytesRead = fullStruct.ConnStats.DataBytesRead
//fullClientDB.DataBytesWritten = fullStruct.ConnStats.DataBytesWritten
fullClientDB.ActivePeers = fullStruct.ActivePeers fullClientDB.ActivePeers = fullStruct.ActivePeers
fullClientDB.TotalPeers = fullStruct.TotalPeers fullClientDB.TotalPeers = fullStruct.TotalPeers
fullClientDB.TorrentHashString = element.Hash.String() fullClientDB.TorrentHashString = TempHash.AsString()
fullClientDB.StoragePath = element.StoragePath fullClientDB.StoragePath = element.StoragePath
fullClientDB.TorrentName = element.TorrentName fullClientDB.TorrentName = element.TorrentName
fullClientDB.DateAdded = element.DateAdded fullClientDB.DateAdded = element.DateAdded
calculateTorrentStatus(singleTorrent, fullClientDB) //calculate the status of the torrent
RunningTorrentArray = append(RunningTorrentArray, *fullClientDB) RunningTorrentArray = append(RunningTorrentArray, *fullClientDB)
@@ -107,10 +154,8 @@ func updateClient(torrentstats []clientDB, conn *websocket.Conn){ //get the tor
//first get the list of torrents in the client //first get the list of torrents in the client
conn.WriteJSON(torrentstats) //converting to JSON and writing to the client conn.WriteJSON(torrentstats) //converting to JSON and writing to the client
} }
func main() { func main() {
//setting up the torrent client //setting up the torrent client
Config := fullClientSettingsNew() //grabbing from settings.go Config := fullClientSettingsNew() //grabbing from settings.go
@@ -124,21 +169,15 @@ func main() {
log.Fatalf("error creating client: %s", err) log.Fatalf("error creating client: %s", err)
} }
//torrentDbStorage := initializeStorage //initializing the boltDB store that contains all the added torrents
db, err := bolt.Open("storage.db", 0600, nil) //initializing the boltDB store that contains all the added torrents db, err := bolt.Open("storage.db", 0600, nil) //initializing the boltDB store that contains all the added torrents
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer db.Close() //defering closing the database until the program closes defer db.Close() //defering closing the database until the program closes
//defer torrentDbStorage().Close() //defering closing the database until the program closes
var TorrentLocalArray = []*TorrentLocal{} //this is an array of ALL of the local storage torrents, they will be added back in via hash var TorrentLocalArray = []*TorrentLocal{} //this is an array of ALL of the local storage torrents, they will be added back in via hash
var RunningTorrentArray = []clientDB{} //this stores ALL of the torrents that are running, used for client update pushes combines Local Storage and Running tclient info var RunningTorrentArray = []clientDB{} //this stores ALL of the torrents that are running, used for client update pushes combines Local Storage and Running tclient info
TorrentLocalArray = readInTorrents(db) //pulling in all the already added torrents TorrentLocalArray = readInTorrents(db) //pulling in all the already added torrents
if TorrentLocalArray != nil { if TorrentLocalArray != nil {
@@ -147,25 +186,44 @@ func main() {
fmt.Println("Database is empty!") fmt.Println("Database is empty!")
} }
router := mux.NewRouter() //setting up the handler for the web backend
router.HandleFunc("/", serveHome) //Serving the main page for our SPA
r := mux.NewRouter() //setting up the handler for the web backend
r.HandleFunc("/", serveHome)
http.Handle("/static/", http.FileServer(http.Dir("public"))) http.Handle("/static/", http.FileServer(http.Dir("public")))
http.Handle("/", r) http.Handle("/", router)
http.HandleFunc("/uploadTorrent", func(w http.ResponseWriter, r *http.Request) { //grabbing the uploaded Torrent File and adding it to the client
defer http.Redirect(w, r, "/", 301)
file, header, err := r.FormFile("fileTest")
if err != nil {
fmt.Println("Error with fetching file or request issue", file)
}
defer file.Close() //defer closing the file until we are done manipulating it
fileName, err := os.OpenFile(header.Filename, os.O_WRONLY|os.O_CREATE, 0666) //generating the fileName
if err != nil {
panic(err)
}
io.Copy(fileName, file) //Dumping our recieved file into the filename
clientTorrent, err := tclient.AddTorrentFromFile(fileName.Name()) //Adding the torrent into the client
if err != nil {
fmt.Println("Error adding Torrent from file: ", fileName.Name())
} else {
fmt.Println("Adding Torrent via file", fileName)
startTorrent(clientTorrent, torrentLocalStorage, Config.Config, db, TorrentLocalArray, tclient)
}
})
http.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) { //exposing the data to the http.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) { //exposing the data to the
if len(RunningTorrentArray) > 0 { if len(RunningTorrentArray) > 0 {
RunningTorrentArray = createRunningTorrentArray(tclient, TorrentLocalArray) //Updates the RunningTorrentArray with the current client data as well RunningTorrentArray = createRunningTorrentArray(tclient, TorrentLocalArray) //Updates the RunningTorrentArray with the current client data as well
var torrentlistArray = new(torrentList) var torrentlistArray = new(torrentList)
torrentlistArray.ClientDBstruct = RunningTorrentArray torrentlistArray.ClientDBstruct = RunningTorrentArray
torrentlistArray.Totaltorrents = len(RunningTorrentArray) torrentlistArray.Totaltorrents = len(RunningTorrentArray)
torrentlistArrayJson, _:= json.Marshal(torrentlistArray) torrentlistArrayJSON, _ := json.Marshal(torrentlistArray)
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write(torrentlistArrayJson) w.Write(torrentlistArrayJSON)
//updateClient(RunningTorrentArray, conn) // sending the client update information over the websocket //updateClient(RunningTorrentArray, conn) // sending the client update information over the websocket
} }
}) })
http.HandleFunc("/websocket", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/websocket", func(w http.ResponseWriter, r *http.Request) { //websocket is the main data pipe to the frontend
conn, err := upgrader.Upgrade(w, r, nil) conn, err := upgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {
@@ -176,15 +234,15 @@ func main() {
for { for {
msgType, msg, err := conn.ReadMessage() msgType, msg, err := conn.ReadMessage()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println("Read Message Error", err)
return return
} }
if string(msg) == "ping" { //6 second update ping if string(msg) == "clientUpdateRequest" { //6 second update ping
fmt.Println("ping") fmt.Println("client Requested Update")
time.Sleep(6 * time.Second) time.Sleep(6 * time.Second)
err = conn.WriteMessage(msgType, []byte("pong")) err = conn.WriteMessage(msgType, []byte("clientUpdate"))
if err != nil { if err != nil {
fmt.Println("Websocket err", err) fmt.Println("Websocket Write err", err)
return return
} }
@@ -198,7 +256,6 @@ func main() {
//updateClient(RunningTorrentArray, conn) // sending the client update information over the websocket //updateClient(RunningTorrentArray, conn) // sending the client update information over the websocket
} }
} else if strings.HasPrefix(string(msg), "magnet:") { } else if strings.HasPrefix(string(msg), "magnet:") {
fmt.Println(string(msg)) fmt.Println(string(msg))
clientTorrent, err := tclient.AddMagnet(string(msg)) clientTorrent, err := tclient.AddMagnet(string(msg))
@@ -208,7 +265,7 @@ func main() {
fmt.Println(clientTorrent) fmt.Println(clientTorrent)
fmt.Printf("Adding") fmt.Printf("Adding")
startTorrent(clientTorrent, torrentLocalStorage, Config.Config, db) //starting the torrent and creating local DB entry startTorrent(clientTorrent, torrentLocalStorage, Config.Config, db, TorrentLocalArray, tclient) //starting the torrent and creating local DB entry
} else { } else {
conn.Close() conn.Close()
@@ -220,6 +277,4 @@ func main() {
if err := http.ListenAndServe(*httpAddr, nil); err != nil { if err := http.ListenAndServe(*httpAddr, nil); err != nil {
log.Fatalf("Error listening, %v", err) log.Fatalf("Error listening, %v", err)
} }
//
} }

View File

@@ -38,8 +38,6 @@
.navsettings { .navsettings {
grid-column: 1 / span 2; grid-column: 1 / span 2;
grid-row: 1; grid-row: 1;
border-style: double;
max-height: 80px;
} }
.imagezoom { .imagezoom {
@@ -71,11 +69,6 @@ ul.none {
padding: 0 2% 0 0; padding: 0 2% 0 0;
} }
ul.navsettingsUl {
list-style-type: none;
margin: 0;
padding-left: 0;
}
li.top { li.top {
display: inline; display: inline;
@@ -87,25 +80,6 @@ hr {
padding: 0; padding: 0;
} }
.verticalLine {
border-left: solid grey;
}
table {
width: 100%;
border-collapse: collapse;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
background-color: #3B83CB;
}
tr:nth-child(even) {
background-color: #dddddd;
}
.activeButton { .activeButton {
background-color: red; background-color: red;
@@ -118,57 +92,3 @@ tr:nth-child(even) {
.defaultTab { .defaultTab {
display: initial; display: initial;
} }
.addTorrentModal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.addTorrentModalContent {
background-color: #fefefe;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
/* The Close Button */
.addTorrentModalClose {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.addTorrentModalClose:hover,
.addTorrentModalClose:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.addTorrentFileModalClose {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.addTorrentFileModalClose:hover,
.addTorrentFileModalClose:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

124436
public/static/js/bundle.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,74 @@
package main
import (
"honnef.co/go/js/dom"
"github.com/gopherjs/websocket/websocketjs"
"github.com/gopherjs/gopherjs/js"
"github.com/johanbrandhorst/gopherjs-json"
"time"
//"honnef.co/go/js/dom"
)
var (
//d = dom.GetWindow().Document() //getting the dom to manipulate it
document = dom.GetWindow().Document().(dom.HTMLDocument)
//conn = func(){websocketjs.New("ws://192.168.1.141:8000/websocket")}//creating a global JS websocket connection
)
func main(){
document.AddEventListener("DOMContentLoaded", false, func(_ dom.Event){
println("DOMLoaded...")
go ready()
})
}
func ready(){
//conn := conn()
conn, err := websocketjs.New("ws://192.168.1.141:8000/websocket") // Blocks until connection is established.
if err != nil {
println("Error creating client websocket connection") // handle error
}
onOpen := func(ev *js.Object){
err := conn.Send("ping!") //on startup send the ping message
if err != nil {
println("Cannot send ping message")
}
}
onMessage := func(ev *js.Object){
messageData := ev.Get("data").String()
if messageData == "pong"{ //if the server says a pong, send a ping back
time.Sleep(6 * time.Second)
conn.Send("ping")
} else {
clientData, err := json.Unmarshal(messageData)
if err != nil {
println("Error unmarshalling server message")
}
println(clientData.String())
}
}
onClose := func(ev *js.Object){
println("Closing Connection....")
}
onError := func(ev *js.Object){
println("Error....")
}
conn.AddEventListener("open", false, onOpen)
conn.AddEventListener("message", false, onMessage)
conn.AddEventListener("close", false, onClose)
conn.AddEventListener("error", false, onError)
err = conn.Close()
}

View File

@@ -1,31 +0,0 @@
Vue.use(Vuetable);
var demo = new Vue({
delimiters: ['((', '))'],
el: '#torrentlist',
components:{
'vuetable-pagination': Vuetable.VuetablePagination
},
data: {
fields: ['Torrent Name', 'Status','Percent Complete','Size','Total Peers','Storage Location']
},
computed:{
/*httpOptions(){
return {headers: {'Authorization': "my-token"}} //table props -> :http-options="httpOptions"
},*/
},
methods: {
onPaginationData (paginationData) {
this.$refs.pagination.setPaginationData(paginationData)
},
onChangePage (page) {
this.$refs.vuetable.changePage(page)
},
editRow(rowData){
alert("You clicked edit on"+ JSON.stringify(rowData))
},
deleteRow(rowData){
alert("You clicked delete on"+ JSON.stringify(rowData))
}
}
})

View File

@@ -0,0 +1,102 @@
d := dom.GetWindow().Document() //getting the dom to manipulate it
logTextArea := d.GetElementByID("loggerData")
torrentLinkSubmit := d.GetElementByID("torrentLinkSubmit")
magnetLink := d.GetElementByID("magnetLink")
addTorrentModal := d.GetElementByID("addTorrentModal")
addTorrentLinkBtn := d.GetElementByID("addTorrentLink") // Get the button that opens the modal
addTorrentFileModal := d.GetElementByID("addTorrentFile")
addTorrentFileModalClose := d.GetElementsByClassName("addTorrentFileModalClose")
addTorrentModalClose := d.GetElementsByClassName("addTorrentModalClose") // Get the <span> element that closes the modal
//add magnet link modal
addTorrentLinkBtn.AddEventListener("click", false, func(event dom.Event){
addTorrentModal.SetAttribute("display", "block")
})
//close torrent link modal
addTorrentModalClose[0].AddEventListener("click", false, func(event dom.Event){
addTorrentModal.SetAttribute("display", "none")
})
//show torrent file modal
addTorrentFileModal.AddEventListener("click", false, func(event dom.Event){
addTorrentFileModal.SetAttribute("display", "block")
})
//hide torrent file modal
addTorrentFileModalClose[0].AddEventListener("click", false, func(event dom.Event){
addTorrentFileModal.SetAttribute("display", "none")
})
// When the user clicks anywhere outside of the modal, close it
d.AddEventListener("click", false, func(event dom.Event){
addTorrentModal.SetAttribute("display", "none")
addTorrentLinkBtn.SetAttribute("display", "none")
})
//websocket logic
conn, err := websocketjs.New("ws://192.168.1.141:8000/websocket") // Blocks until connection is established.
if err != nil {
println("Error creating client websocket connection") // handle error
}
onOpen := func(ev *js.Object){
err := conn.Send("ping!") //on startup send the ping message
if err != nil {
println("Cannot send ping message")
}
}
onMessage := func(ev *js.Object){
messageData := ev.Get("data").String()
if messageData == "pong"{ //if the server says a pong, send a ping back
time.Sleep(6 * time.Second)
conn.Send("ping")
} else {
clientData, err := json.Unmarshal(messageData)
if err != nil {
println("Error unmarshalling server message")
}
logTextArea.SetInnerHTML(logTextArea.InnerHTML() + "</br>" + "Client Update Event....")
logTextArea.SetInnerHTML(logTextArea.InnerHTML() + "</br>" + clientData.String())
}
}
onClose := func(ev *js.Object){
logTextArea.SetInnerHTML(logTextArea.InnerHTML() + "</br>" + "Connection closed")
}
onError := func(ev *js.Object){
logTextArea.SetInnerHTML(logTextArea.InnerHTML() + "</br>" + "Error opening websocket")
}
conn.AddEventListener("open", false, onOpen)
conn.AddEventListener("message", false, onMessage)
conn.AddEventListener("close", false, onClose)
conn.AddEventListener("error", false, onError)
err = conn.Close()
torrentLinkSubmit.AddEventListener("click", false, func(event dom.Event){ //listening to the submit button for magnet link
conn.Send(magnetLink.TextContent())
logTextArea.SetInnerHTML(logTextArea.InnerHTML() + "</br>" + "Adding Magnet Link: " + magnetLink.TextContent()) //adding the magnet link to the log
addTorrentModal.SetAttribute("display", "none")
magnetLink.SetTextContent("")
})
}

View File

@@ -0,0 +1,7 @@
var ws = new WebSocket("ws://192.168.1.141:8000/websocket"); //creating websocket
ws.onopen = function()
{
ws.send("clientUpdateRequest"); //sending out the first ping
console.log("Kicking off websocket to server on 192.168.1.141.....")
};

View File

@@ -3,12 +3,12 @@ function myWebsocketStart()
var torrentLinkSubmit = document.getElementById('torrentLinkSubmit'); var torrentLinkSubmit = document.getElementById('torrentLinkSubmit');
var magnetLink = document.getElementById('magnetLink'); var magnetLink = document.getElementById('magnetLink');
var modal = document.getElementById('addTorrentModal'); var addTorrentModal = document.getElementById('addTorrentModal');
var myTextArea = document.getElementById("loggerData"); var myTextArea = document.getElementById("loggerData");
var torrentHash = document.getElementById("hash"); var torrentHash = document.getElementById("hash");
var ws = new WebSocket("ws://192.168.1.141:8000/websocket"); var ws = new WebSocket("ws://192.168.1.141:8000/websocket"); //creating websocket
ws.onopen = function() ws.onopen = function()
{ {
@@ -52,7 +52,7 @@ function myWebsocketStart()
ws.send(magnetLinkjs); ws.send(magnetLinkjs);
myTextArea.innerHTML = myTextArea.innerHTML + "</br> Send:" + magnetLinkjs myTextArea.innerHTML = myTextArea.innerHTML + "</br> Send:" + magnetLinkjs
modal.style.display = "none"; addTorrentModal.style.display = "none";
magnetLink.value = ''; magnetLink.value = '';
} }

View File

@@ -1,22 +1,21 @@
package main package main
import ( import (
"github.com/boltdb/bolt"
"fmt" "fmt"
"github.com/anacrolix/torrent/metainfo"
"time" "time"
"github.com/boltdb/bolt"
) )
type TorrentLocal struct { type TorrentLocal struct { //local storage of the torrents for readd on server restart
Hash metainfo.Hash Hash string
DateAdded string DateAdded string
StoragePath string StoragePath string
TorrentName string TorrentName string
TorrentStatus string
TorrentType string //magnet or .torrent file
} }
func readInTorrents(torrentStorage *bolt.DB) (TorrentLocalArray []*TorrentLocal) { func readInTorrents(torrentStorage *bolt.DB) (TorrentLocalArray []*TorrentLocal) {
TorrentLocalArray = []*TorrentLocal{} TorrentLocalArray = []*TorrentLocal{}
@@ -29,6 +28,7 @@ func readInTorrents (torrentStorage *bolt.DB) (TorrentLocalArray []*TorrentLocal
var StoragePath []byte var StoragePath []byte
var Hash []byte var Hash []byte
var TorrentName []byte var TorrentName []byte
var TorrentStatus []byte
Dateadded = b.Get([]byte("Date")) Dateadded = b.Get([]byte("Date"))
if Dateadded == nil { if Dateadded == nil {
fmt.Println("Date added error!") fmt.Println("Date added error!")
@@ -48,11 +48,17 @@ func readInTorrents (torrentStorage *bolt.DB) (TorrentLocalArray []*TorrentLocal
fmt.Println("Torrent Name not found") fmt.Println("Torrent Name not found")
TorrentName = []byte("Not Found!") TorrentName = []byte("Not Found!")
} }
TorrentStatus = b.Get([]byte("TorrentStatus"))
if TorrentStatus == nil {
fmt.Println("Torrent Status not found in local storage")
TorrentStatus = []byte("")
}
torrentLocal.DateAdded = string(Dateadded) torrentLocal.DateAdded = string(Dateadded)
torrentLocal.StoragePath = string(StoragePath) torrentLocal.StoragePath = string(StoragePath)
torrentLocal.Hash = metainfo.HashBytes(Hash) //Converting the byte slice back into the full hash torrentLocal.Hash = string(Hash) //Converting the byte slice back into the full hash
torrentLocal.TorrentName = string(TorrentName) torrentLocal.TorrentName = string(TorrentName)
torrentLocal.TorrentStatus = string(TorrentStatus)
fmt.Println("Torrentlocal list: ", torrentLocal) fmt.Println("Torrentlocal list: ", torrentLocal)
TorrentLocalArray = append(TorrentLocalArray, torrentLocal) //dumping it into the array TorrentLocalArray = append(TorrentLocalArray, torrentLocal) //dumping it into the array
@@ -64,12 +70,11 @@ func readInTorrents (torrentStorage *bolt.DB) (TorrentLocalArray []*TorrentLocal
return TorrentLocalArray //all done, return the entire Array to add to the torrent client return TorrentLocalArray //all done, return the entire Array to add to the torrent client
} }
func addTorrentLocalStorage(torrentStorage *bolt.DB, local *TorrentLocal) { func addTorrentLocalStorage(torrentStorage *bolt.DB, local *TorrentLocal) {
println("Adding Local storage information") println("Adding Local storage information")
torrentStorage.Update(func(tx *bolt.Tx) error { torrentStorage.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucketIfNotExists([]byte(local.Hash.Bytes()))//translating hash into bytes for storage b, err := tx.CreateBucketIfNotExists([]byte(local.Hash)) //translating hash into bytes for storage
if err != nil { if err != nil {
return fmt.Errorf("create bucket %s", err) return fmt.Errorf("create bucket %s", err)
} }
@@ -81,7 +86,7 @@ func addTorrentLocalStorage (torrentStorage *bolt.DB, local *TorrentLocal){
if err != nil { if err != nil {
return err return err
} }
err = b.Put([]byte("InfoHash"), []byte(local.Hash.Bytes())) err = b.Put([]byte("InfoHash"), []byte(local.Hash))
if err != nil { if err != nil {
return err return err
} }

124
templates/home.1.tmpl Normal file
View File

@@ -0,0 +1,124 @@
{{define "base"}}
<!DOCTYPE html>
<html lang="en">
<head>
<title>torrent-project</title>
<link rel="stylesheet" href="/static/css/gridbase.css" type="text/css" />
<script type="text/javascript" src="/static/js/tabControl.js"></script>
<script type="text/javascript" src="/static/js/kickwebsocket.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
</head>
<body>
<!-- The addlink Modal -->
<div id="addTorrentLinkModal">
</div>
<!-- The addTorrent Modal -->
<div id="addTorrentFileModal" class="addTorrentModal">
<!-- Modal content -->
<div class="addTorrentModalContent">
<span class="addTorrentFileModalClose">&times;</span>
Input Torrent File: <input type="file" name="torrentFile">
<button id="torrentFileSubmit">Submit</button>
</div>
</div>
<div class="wrapper">
<div class="box navcolumn">
<hr>
<ul class="none">
<li class="liNavcolumn" id="allTorrents"><img class="navcolumnImage" src="/static/images/iconTorrent.png" alt="All Torrents">All Torrents</li>
<li class="liNavcolumn" id="downloading"><img class="navcolumnImage" src="/static/images/iconDownload.png" alt="Downloading Torrents">Downloading</li>
<li class="liNavcolumn" id="uploading"><img class="navcolumnImage" src="/static/images/iconUpload.png" alt="Uploading Torrents">Uploading</li>
<li class="liNavcolumn" id="active"><img class="navcolumnImage" src="/static/images/iconActiveTorrents.png" alt="Active Torrents">Active</li>
<li class="liNavcolumn" id="inactive"><img class="navcolumnImage" src="/static/images/iconInactiveTorrents.png" alt="Inactive Torrents">Inactive</li>
</ul>
<hr>
</div>
<div id="navSettingsID" class="box navsettings">
</div>
<div id="torrentlist" class="box">
</div>
<div class="box torrentdetails">
<div>
<button class="tablink activeButton" onclick="openTab(event, 'General')">General</button>
<button class="tablink" onclick="openTab(event, 'Peers')">Peers</button>
<button class="tablink" onclick="openTab(event, 'Files')">Files</button>
<button class="tablink" onclick="openTab(event, 'Speed')">Speed</button>
<button class="tablink" onclick="openTab(event, 'Logger')">Logger</button>
</div>
<div id="General" class="tab defaultTab">
<h2>General</h2>
<p id="hash"></p>
<p>General Information</p>
</div>
<div id="Peers" class="tab">
<h2>Peers</h2>
<table>
<tr>
<th>IP</th>
<th>Client</th>
<th>Flags</th>
<th>Percent</th>
<th>Down Speed</th>
<th>Up Speed</th>
<th>Reqs</th>
<th>Uploaded</th>
<th>Downloaded</th>
<th>Peer dl.</th>
</tr>
</table>
</div>
<div id="Files" class="tab">
<h2>Files</h2>
<table>
<tr>
<th>Name</th>
<th>Size</th>
<th>Done</th>
<th>Percent</th>
<th>Priority</th>
</tr>
</table>
</div>
<div id="Speed" class="tab">
<h2>Speed</h2>
<p>Speed Graph Here</p>
</div>
<div id="Logger" class="tab">
<h2>Logger</h2>
<p id="loggerData">Logger lines here</p>
</div>
</div>
</div>
<script type="text/javascript" src="/static/js/bundle.js"></script>
<script type="text/javascript">console.log('Here');</script>
<footer>Icons by <a href="https://icons8.com">icons8</a></footer>
</body>
</html>
{{end}}

View File

@@ -4,148 +4,21 @@
<head> <head>
<title>torrent-project</title> <title>torrent-project</title>
<link rel="stylesheet" href="/static/css/gridbase.css" type="text/css" /> <script type="text/javascript" src="/static/js/kickwebsocket.js"></script>
<script type="text/javascript" src="/static/js/websocket.js"></script> <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> -->
<script type="text/javascript" src="/static/js/tabControl.js"></script> <!-- <script src="http://code.jquery.com/jquery-2.1.3.min.js"></script> -->
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
</head> </head>
<body onload="javascript:myWebsocketStart()"> <body>
<div id=app></div>
<!-- The addlink Modal -->
<div id="addTorrentModal" class="addTorrentModal">
<!-- Modal content -->
<div class="addTorrentModalContent">
<span class="addTorrentModalClose">&times;</span>
<form id="torrentLinkForm" action="#" method="post">
Input Magnet Link: <input type="text" id="magnetLink">
<button id="torrentLinkSubmit">Submit</button>
</form>
</div>
</div>
<!-- The addTorrent Modal -->
<div id="addTorrentFileModal" class="addTorrentModal">
<!-- Modal content -->
<div class="addTorrentModalContent">
<span class="addTorrentFileModalClose">&times;</span>
Input Torrent File: <input type="file" name="torrentFile">
<button id="torrentFileSubmit">Submit</button>
</div>
</div>
<div class="wrapper">
<div class="box navcolumn">
<hr>
<ul class="none">
<li class="liNavcolumn" id="allTorrents"><img class="navcolumnImage" src="/static/images/iconTorrent.png" alt="All Torrents">All Torrents</li>
<li class="liNavcolumn" id="downloading"><img class="navcolumnImage" src="/static/images/iconDownload.png" alt="Downloading Torrents">Downloading</li>
<li class="liNavcolumn" id="uploading"><img class="navcolumnImage" src="/static/images/iconUpload.png" alt="Uploading Torrents">Uploading</li>
<li class="liNavcolumn" id="active"><img class="navcolumnImage" src="/static/images/iconActiveTorrents.png" alt="Active Torrents">Active</li>
<li class="liNavcolumn" id="inactive"><img class="navcolumnImage" src="/static/images/iconInactiveTorrents.png" alt="Inactive Torrents">Inactive</li>
</ul>
<hr>
</div>
<div class="box navsettings">
<ul class="navsettingsUl">
<li class="top" id="addTorrentFile"><img class="imagezoom" src="/static/images/iconAddTorrent.png" alt="Upload Torrent File"></li>
<li class="top" id="addTorrentLink"><img class="imagezoom" src="/static/images/iconAddTorrentLink.png" alt="Add Magnet Links"></li>
<li class="top verticalLine" id="deleteTorrent"><img class="imagezoom" src="/static/images/iconDelete.png" alt="Delete Torrent"></li>
<li class="top verticalLine" id="startTorrent"><img class="imagezoom" src="/static/images/iconStart.png" alt="Start Torrent"></li>
<li class="top" id="pauseTorrent"><img class="imagezoom" src="/static/images/iconPause.png" alt="Pause Torrent"></li>
<li class="top" id="stopTorrent"><img class="imagezoom" src="/static/images/iconStop.png" alt="Stop Torrent"></li>
<li class="top verticalLine" id="upTorrent"><img class="imagezoom" src="/static/images/iconScrollUp.png" alt="Move Torrent Up"></li>
<li class="top" id="downTorrent"><img class="imagezoom" src="/static/images/iconScrollDown.png" alt="Down Torrent"></li>
<li class="top verticalLine" id="rssTorrent"><img class="imagezoom" src="/static/images/iconRss.png" alt="RSS Torrent"></li>
<li class="top verticalLine" id="settingsIcon"><img class="imagezoom" src="/static/images/iconSettings.png" alt="Settings"></li>
</ul>
</div>
<div id="torrentlist" class="box torrentlist">
<div class="ui container">
<vuetable ref="vuetable"
api-url="http://192.168.1.141:8000/api"
:fields="fields"
data-path="data"
pagination-path=""
>
</vuetable>
</div>
<div class="box torrentdetails">
<div>
<button class="tablink activeButton" onclick="openTab(event, 'General')">General</button>
<button class="tablink" onclick="openTab(event, 'Peers')">Peers</button>
<button class="tablink" onclick="openTab(event, 'Files')">Files</button>
<button class="tablink" onclick="openTab(event, 'Speed')">Speed</button>
<button class="tablink" onclick="openTab(event, 'Logger')">Logger</button>
</div>
<div id="General" class="tab defaultTab">
<h2>General</h2>
<p id="hash"></p>
<p>General Information</p>
</div>
<div id="Peers" class="tab"> <script type="text/javascript" src="/static/js/bundle.js"></script>
<h2>Peers</h2>
<table>
<tr>
<th>IP</th>
<th>Client</th>
<th>Flags</th>
<th>Percent</th>
<th>Down Speed</th>
<th>Up Speed</th>
<th>Reqs</th>
<th>Uploaded</th>
<th>Downloaded</th>
<th>Peer dl.</th>
</tr>
</table>
</div>
<div id="Files" class="tab">
<h2>Files</h2>
<table>
<tr>
<th>Name</th>
<th>Size</th>
<th>Done</th>
<th>Percent</th>
<th>Priority</th>
</tr>
</table>
</div>
<div id="Speed" class="tab">
<h2>Speed</h2>
<p>Speed Graph Here</p>
</div>
<div id="Logger" class="tab">
<h2>Logger</h2>
<p id="loggerData">Logger lines here</p>
</div>
</div>
</div>
<script src="https://unpkg.com/vuetable-2@1.6.0"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.min.js"></script>
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<script type="text/javascript" src="/static/js/addTorrents.js"></script>
<script type="text/javascript" src="/static/js/grid.js"></script>
<footer>Icons by <a href="https://icons8.com">icons8</a></footer>
</body> </body>
</html> </html>
{{end}} {{end}}

12
templates/test.tmpl Normal file
View File

@@ -0,0 +1,12 @@
{{define "base"}}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div id=app></div>
</body>
<footer><script type="text/javascript" src="/static/js/bundle.js"></script></footer>
</html>
{{end}}

9
torrent-project/.babelrc Normal file
View File

@@ -0,0 +1,9 @@
{
"presets": [
"react",
"env"
],
"plugins": ["transform-class-properties"]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

15
torrent-project/babel Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/babel-cli/bin/babel.js" "$@"
ret=$?
else
node "$basedir/node_modules/babel-cli/bin/babel.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/babel-cli/bin/babel-doctor.js" "$@"
ret=$?
else
node "$basedir/node_modules/babel-cli/bin/babel-doctor.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\babel-cli\bin\babel-doctor.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\babel-cli\bin\babel-doctor.js" %*
)

View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/babel-cli/bin/babel-external-helpers.js" "$@"
ret=$?
else
node "$basedir/node_modules/babel-cli/bin/babel-external-helpers.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\babel-cli\bin\babel-external-helpers.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\babel-cli\bin\babel-external-helpers.js" %*
)

View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/babel-cli/bin/babel-node.js" "$@"
ret=$?
else
node "$basedir/node_modules/babel-cli/bin/babel-node.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\babel-cli\bin\babel-node.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\babel-cli\bin\babel-node.js" %*
)

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\babel-cli\bin\babel.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\babel-cli\bin\babel.js" %*
)

15
torrent-project/babylon Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/babylon/bin/babylon.js" "$@"
ret=$?
else
node "$basedir/node_modules/babylon/bin/babylon.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\babylon\bin\babylon.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\babylon\bin\babylon.js" %*
)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,113 @@
* {
font-family: Roboto, sans-serif;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-Regular-webfont.eot');
src: url('Roboto-Regular-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-Regular-webfont.woff') format('woff'),
url('Roboto-Regular-webfont.ttf') format('truetype'),
url('Roboto-Regular-webfont.svg#RobotoRegular') format('svg');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-Italic-webfont.eot');
src: url('Roboto-Italic-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-Italic-webfont.woff') format('woff'),
url('Roboto-Italic-webfont.ttf') format('truetype'),
url('Roboto-Italic-webfont.svg#RobotoItalic') format('svg');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-Bold-webfont.eot');
src: url('Roboto-Bold-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-Bold-webfont.woff') format('woff'),
url('Roboto-Bold-webfont.ttf') format('truetype'),
url('Roboto-Bold-webfont.svg#RobotoBold') format('svg');
font-weight: bold;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-BoldItalic-webfont.eot');
src: url('Roboto-BoldItalic-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-BoldItalic-webfont.woff') format('woff'),
url('Roboto-BoldItalic-webfont.ttf') format('truetype'),
url('Roboto-BoldItalic-webfont.svg#RobotoBoldItalic') format('svg');
font-weight: bold;
font-style: italic;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-Thin-webfont.eot');
src: url('Roboto-Thin-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-Thin-webfont.woff') format('woff'),
url('Roboto-Thin-webfont.ttf') format('truetype'),
url('Roboto-Thin-webfont.svg#RobotoThin') format('svg');
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-ThinItalic-webfont.eot');
src: url('Roboto-ThinItalic-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-ThinItalic-webfont.woff') format('woff'),
url('Roboto-ThinItalic-webfont.ttf') format('truetype'),
url('Roboto-ThinItalic-webfont.svg#RobotoThinItalic') format('svg'); (under the Apache Software License).
font-weight: 200;
font-style: italic;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-Light-webfont.eot');
src: url('Roboto-Light-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-Light-webfont.woff') format('woff'),
url('Roboto-Light-webfont.ttf') format('truetype'),
url('Roboto-Light-webfont.svg#RobotoLight') format('svg');
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-LightItalic-webfont.eot');
src: url('Roboto-LightItalic-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-LightItalic-webfont.woff') format('woff'),
url('Roboto-LightItalic-webfont.ttf') format('truetype'),
url('Roboto-LightItalic-webfont.svg#RobotoLightItalic') format('svg');
font-weight: 100;
font-style: italic;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-Medium-webfont.eot');
src: url('Roboto-Medium-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-Medium-webfont.woff') format('woff'),
url('Roboto-Medium-webfont.ttf') format('truetype'),
url('Roboto-Medium-webfont.svg#RobotoMedium') format('svg');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('Roboto-MediumItalic-webfont.eot');
src: url('Roboto-MediumItalic-webfont.eot?#iefix') format('embedded-opentype'),
url('Roboto-MediumItalic-webfont.woff') format('woff'),
url('Roboto-MediumItalic-webfont.ttf') format('truetype'),
url('Roboto-MediumItalic-webfont.svg#RobotoMediumItalic') format('svg');
font-weight: 300;
font-style: italic;
}

15
torrent-project/jsesc Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/jsesc/bin/jsesc" "$@"
ret=$?
else
node "$basedir/node_modules/jsesc/bin/jsesc" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\jsesc\bin\jsesc" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\jsesc\bin\jsesc" %*
)

15
torrent-project/json5 Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/json5/lib/cli.js" "$@"
ret=$?
else
node "$basedir/node_modules/json5/lib/cli.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\json5\lib\cli.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\json5\lib\cli.js" %*
)

View File

@@ -0,0 +1,6 @@
<html>
<head>
<script type="text/javascript" src="modals.js"</script>
<head>
<div id="app"></div>
</html>

View File

@@ -0,0 +1,21 @@
'use strict';
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _reactPopup = require('react-popup');
var _reactPopup2 = _interopRequireDefault(_reactPopup);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_reactDom2.default.render(_react2.default.createElement(
'h1',
null,
'Hello, world!'
), _react2.default.createElement(_reactPopup2.default, null), document.getElementById('app'));

View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/loose-envify/cli.js" "$@"
ret=$?
else
node "$basedir/node_modules/loose-envify/cli.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\loose-envify\cli.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\loose-envify\cli.js" %*
)

15
torrent-project/mkdirp Normal file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/mkdirp/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/node_modules/mkdirp/bin/cmd.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\mkdirp\bin\cmd.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\mkdirp\bin\cmd.js" %*
)

View File

@@ -0,0 +1,7 @@
# DevExtreme Reactive Core
Core library for DevExtreme Reactive Components.
## License
[DevExtreme licensing](https://js.devexpress.com/licensing/).

View File

@@ -0,0 +1,442 @@
/**
* Bundle of @devexpress/dx-core
* Generated: 2017-11-10
* Version: 1.0.0-beta.1
* License: https://js.devexpress.com/Licensing
*/
var compare = function compare(a, b) {
var aPosition = a.position();
var bPosition = b.position();
for (var i = 0; i < Math.min(aPosition.length, bPosition.length); i += 1) {
if (aPosition[i] < bPosition[i]) return -1;
if (aPosition[i] > bPosition[i]) return 1;
}
return aPosition.length - bPosition.length;
};
var insertPlugin = function insertPlugin(array, newItem) {
var result = array.slice();
var targetIndex = array.findIndex(function (item) {
return compare(newItem, item) < 0;
});
result.splice(targetIndex < 0 ? array.length : targetIndex, 0, newItem);
return result;
};
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var getDependencyError = function getDependencyError(pluginName, dependencyName) {
return new Error('The \'' + pluginName + '\' plugin requires \'' + dependencyName + '\' to be defined before it.');
};
var PluginHost = function () {
function PluginHost() {
classCallCheck(this, PluginHost);
this.plugins = [];
this.subscriptions = [];
this.gettersCache = {};
}
createClass(PluginHost, [{
key: 'ensureDependencies',
value: function ensureDependencies() {
var defined = new Set();
var knownOptionals = new Map();
this.plugins.filter(function (plugin) {
return plugin.container;
}).forEach(function (plugin) {
if (knownOptionals.has(plugin.pluginName)) {
throw getDependencyError(knownOptionals.get(plugin.pluginName), plugin.pluginName);
}
plugin.dependencies.forEach(function (dependency) {
if (defined.has(dependency.pluginName)) return;
if (dependency.optional) {
if (!knownOptionals.has(dependency.pluginName)) {
knownOptionals.set(dependency.pluginName, plugin.pluginName);
}
return;
}
throw getDependencyError(plugin.pluginName, dependency.pluginName);
});
defined.add(plugin.pluginName);
});
}
}, {
key: 'registerPlugin',
value: function registerPlugin(plugin) {
this.plugins = insertPlugin(this.plugins, plugin);
this.cleanPluginsCache();
}
}, {
key: 'unregisterPlugin',
value: function unregisterPlugin(plugin) {
this.plugins.splice(this.plugins.indexOf(plugin), 1);
this.cleanPluginsCache();
}
}, {
key: 'cleanPluginsCache',
value: function cleanPluginsCache() {
this.validationRequired = true;
this.gettersCache = {};
this.knownKeysCache = {};
}
}, {
key: 'knownKeys',
value: function knownKeys(postfix) {
if (!this.knownKeysCache[postfix]) {
this.knownKeysCache[postfix] = Array.from(this.plugins.map(function (plugin) {
return Object.keys(plugin);
}).map(function (keys) {
return keys.filter(function (key) {
return key.endsWith(postfix);
})[0];
}).filter(function (key) {
return !!key;
}).reduce(function (acc, key) {
return acc.add(key);
}, new Set())).map(function (key) {
return key.replace(postfix, '');
});
}
return this.knownKeysCache[postfix];
}
}, {
key: 'collect',
value: function collect(key, upTo) {
var _this = this;
if (this.validationRequired) {
this.ensureDependencies();
this.validationRequired = false;
}
if (!this.gettersCache[key]) {
this.gettersCache[key] = this.plugins.map(function (plugin) {
return plugin[key];
}).filter(function (plugin) {
return !!plugin;
});
}
if (!upTo) return this.gettersCache[key];
var upToIndex = this.plugins.indexOf(upTo);
return this.gettersCache[key].filter(function (getter) {
var pluginIndex = _this.plugins.findIndex(function (plugin) {
return plugin[key] === getter;
});
return pluginIndex < upToIndex;
});
}
}, {
key: 'get',
value: function get$$1(key, upTo) {
var plugins = this.collect(key, upTo);
if (!plugins.length) return undefined;
var result = plugins[0]();
plugins.slice(1).forEach(function (plugin) {
result = plugin(result);
});
return result;
}
}, {
key: 'registerSubscription',
value: function registerSubscription(subscription) {
var index = this.subscriptions.indexOf(subscription);
if (index === -1) {
this.subscriptions.push(subscription);
}
}
}, {
key: 'unregisterSubscription',
value: function unregisterSubscription(subscription) {
var index = this.subscriptions.indexOf(subscription);
if (index !== -1) {
this.subscriptions.splice(this.subscriptions.indexOf(subscription), 1);
}
}
}, {
key: 'broadcast',
value: function broadcast(event, message) {
this.subscriptions.forEach(function (subscription) {
return subscription[event] && subscription[event](message);
});
}
}]);
return PluginHost;
}();
var EventEmitter = function () {
function EventEmitter() {
classCallCheck(this, EventEmitter);
this.handlers = [];
}
createClass(EventEmitter, [{
key: "emit",
value: function emit(e) {
this.handlers.forEach(function (handler) {
return handler(e);
});
}
}, {
key: "subscribe",
value: function subscribe(handler) {
this.handlers.push(handler);
}
}, {
key: "unsubscribe",
value: function unsubscribe(handler) {
this.handlers.splice(this.handlers.indexOf(handler), 1);
}
}]);
return EventEmitter;
}();
function shallowEqual(objA, objB) {
if (objA === objB) {
return true;
}
var keysA = Object.keys(objA);
var keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Test for A's keys different from B.
var hasOwn = Object.prototype.hasOwnProperty;
for (var i = 0; i < keysA.length; i += 1) {
if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
return false;
}
var valA = objA[keysA[i]];
var valB = objB[keysA[i]];
if (valA !== valB) {
return false;
}
}
return true;
}
function argumentsShallowEqual(prev, next) {
if (prev === null || next === null || prev.length !== next.length) {
return false;
}
for (var i = 0; i < prev.length; i += 1) {
if (prev[i] !== next[i]) {
return false;
}
}
return true;
}
var memoize = function memoize(func) {
var lastArgs = null;
var lastResult = null;
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (lastArgs === null || !argumentsShallowEqual(lastArgs, args)) {
lastResult = func.apply(undefined, args);
}
lastArgs = args;
return lastResult;
};
};
var easeInQuad = function easeInQuad(t) {
return t * t;
};
var easeOutQuad = function easeOutQuad(t) {
return t * (2 - t);
};
var easeInOutQuad = function easeInOutQuad(t) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
};
var easeInCubic = function easeInCubic(t) {
return t * t * t;
};
var easeOutCubic = function easeOutCubic(t) {
return (t - 1) * (t - 1) * (t - 1) + 1;
};
var easeInOutCubic = function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
};
var easeInQuart = function easeInQuart(t) {
return t * t * t * t;
};
var easeOutQuart = function easeOutQuart(t) {
return 1 - (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
var easeInOutQuart = function easeInOutQuart(t) {
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
var easeInQuint = function easeInQuint(t) {
return t * t * t * t * t;
};
var easeOutQuint = function easeOutQuint(t) {
return 1 + (t - 1) * (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
var easeInOutQuint = function easeInOutQuint(t) {
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (t - 1) * (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
export { PluginHost, EventEmitter, memoize, shallowEqual, argumentsShallowEqual, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint };
//# sourceMappingURL=dx-core.es.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,468 @@
/**
* Bundle of @devexpress/dx-core
* Generated: 2017-11-10
* Version: 1.0.0-beta.1
* License: https://js.devexpress.com/Licensing
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.DevExpress = global.DevExpress || {}, global.DevExpress.DXCore = {})));
}(this, (function (exports) { 'use strict';
var compare = function compare(a, b) {
var aPosition = a.position();
var bPosition = b.position();
for (var i = 0; i < Math.min(aPosition.length, bPosition.length); i += 1) {
if (aPosition[i] < bPosition[i]) return -1;
if (aPosition[i] > bPosition[i]) return 1;
}
return aPosition.length - bPosition.length;
};
var insertPlugin = function insertPlugin(array, newItem) {
var result = array.slice();
var targetIndex = array.findIndex(function (item) {
return compare(newItem, item) < 0;
});
result.splice(targetIndex < 0 ? array.length : targetIndex, 0, newItem);
return result;
};
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var getDependencyError = function getDependencyError(pluginName, dependencyName) {
return new Error('The \'' + pluginName + '\' plugin requires \'' + dependencyName + '\' to be defined before it.');
};
var PluginHost = function () {
function PluginHost() {
classCallCheck(this, PluginHost);
this.plugins = [];
this.subscriptions = [];
this.gettersCache = {};
}
createClass(PluginHost, [{
key: 'ensureDependencies',
value: function ensureDependencies() {
var defined = new Set();
var knownOptionals = new Map();
this.plugins.filter(function (plugin) {
return plugin.container;
}).forEach(function (plugin) {
if (knownOptionals.has(plugin.pluginName)) {
throw getDependencyError(knownOptionals.get(plugin.pluginName), plugin.pluginName);
}
plugin.dependencies.forEach(function (dependency) {
if (defined.has(dependency.pluginName)) return;
if (dependency.optional) {
if (!knownOptionals.has(dependency.pluginName)) {
knownOptionals.set(dependency.pluginName, plugin.pluginName);
}
return;
}
throw getDependencyError(plugin.pluginName, dependency.pluginName);
});
defined.add(plugin.pluginName);
});
}
}, {
key: 'registerPlugin',
value: function registerPlugin(plugin) {
this.plugins = insertPlugin(this.plugins, plugin);
this.cleanPluginsCache();
}
}, {
key: 'unregisterPlugin',
value: function unregisterPlugin(plugin) {
this.plugins.splice(this.plugins.indexOf(plugin), 1);
this.cleanPluginsCache();
}
}, {
key: 'cleanPluginsCache',
value: function cleanPluginsCache() {
this.validationRequired = true;
this.gettersCache = {};
this.knownKeysCache = {};
}
}, {
key: 'knownKeys',
value: function knownKeys(postfix) {
if (!this.knownKeysCache[postfix]) {
this.knownKeysCache[postfix] = Array.from(this.plugins.map(function (plugin) {
return Object.keys(plugin);
}).map(function (keys) {
return keys.filter(function (key) {
return key.endsWith(postfix);
})[0];
}).filter(function (key) {
return !!key;
}).reduce(function (acc, key) {
return acc.add(key);
}, new Set())).map(function (key) {
return key.replace(postfix, '');
});
}
return this.knownKeysCache[postfix];
}
}, {
key: 'collect',
value: function collect(key, upTo) {
var _this = this;
if (this.validationRequired) {
this.ensureDependencies();
this.validationRequired = false;
}
if (!this.gettersCache[key]) {
this.gettersCache[key] = this.plugins.map(function (plugin) {
return plugin[key];
}).filter(function (plugin) {
return !!plugin;
});
}
if (!upTo) return this.gettersCache[key];
var upToIndex = this.plugins.indexOf(upTo);
return this.gettersCache[key].filter(function (getter) {
var pluginIndex = _this.plugins.findIndex(function (plugin) {
return plugin[key] === getter;
});
return pluginIndex < upToIndex;
});
}
}, {
key: 'get',
value: function get$$1(key, upTo) {
var plugins = this.collect(key, upTo);
if (!plugins.length) return undefined;
var result = plugins[0]();
plugins.slice(1).forEach(function (plugin) {
result = plugin(result);
});
return result;
}
}, {
key: 'registerSubscription',
value: function registerSubscription(subscription) {
var index = this.subscriptions.indexOf(subscription);
if (index === -1) {
this.subscriptions.push(subscription);
}
}
}, {
key: 'unregisterSubscription',
value: function unregisterSubscription(subscription) {
var index = this.subscriptions.indexOf(subscription);
if (index !== -1) {
this.subscriptions.splice(this.subscriptions.indexOf(subscription), 1);
}
}
}, {
key: 'broadcast',
value: function broadcast(event, message) {
this.subscriptions.forEach(function (subscription) {
return subscription[event] && subscription[event](message);
});
}
}]);
return PluginHost;
}();
var EventEmitter = function () {
function EventEmitter() {
classCallCheck(this, EventEmitter);
this.handlers = [];
}
createClass(EventEmitter, [{
key: "emit",
value: function emit(e) {
this.handlers.forEach(function (handler) {
return handler(e);
});
}
}, {
key: "subscribe",
value: function subscribe(handler) {
this.handlers.push(handler);
}
}, {
key: "unsubscribe",
value: function unsubscribe(handler) {
this.handlers.splice(this.handlers.indexOf(handler), 1);
}
}]);
return EventEmitter;
}();
function shallowEqual(objA, objB) {
if (objA === objB) {
return true;
}
var keysA = Object.keys(objA);
var keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Test for A's keys different from B.
var hasOwn = Object.prototype.hasOwnProperty;
for (var i = 0; i < keysA.length; i += 1) {
if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
return false;
}
var valA = objA[keysA[i]];
var valB = objB[keysA[i]];
if (valA !== valB) {
return false;
}
}
return true;
}
function argumentsShallowEqual(prev, next) {
if (prev === null || next === null || prev.length !== next.length) {
return false;
}
for (var i = 0; i < prev.length; i += 1) {
if (prev[i] !== next[i]) {
return false;
}
}
return true;
}
var memoize = function memoize(func) {
var lastArgs = null;
var lastResult = null;
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (lastArgs === null || !argumentsShallowEqual(lastArgs, args)) {
lastResult = func.apply(undefined, args);
}
lastArgs = args;
return lastResult;
};
};
var easeInQuad = function easeInQuad(t) {
return t * t;
};
var easeOutQuad = function easeOutQuad(t) {
return t * (2 - t);
};
var easeInOutQuad = function easeInOutQuad(t) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
};
var easeInCubic = function easeInCubic(t) {
return t * t * t;
};
var easeOutCubic = function easeOutCubic(t) {
return (t - 1) * (t - 1) * (t - 1) + 1;
};
var easeInOutCubic = function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
};
var easeInQuart = function easeInQuart(t) {
return t * t * t * t;
};
var easeOutQuart = function easeOutQuart(t) {
return 1 - (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
var easeInOutQuart = function easeInOutQuart(t) {
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
var easeInQuint = function easeInQuint(t) {
return t * t * t * t * t;
};
var easeOutQuint = function easeOutQuint(t) {
return 1 + (t - 1) * (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
var easeInOutQuint = function easeInOutQuint(t) {
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (t - 1) * (t - 1) * (t - 1) * (t - 1) * (t - 1);
};
exports.PluginHost = PluginHost;
exports.EventEmitter = EventEmitter;
exports.memoize = memoize;
exports.shallowEqual = shallowEqual;
exports.argumentsShallowEqual = argumentsShallowEqual;
exports.easeInQuad = easeInQuad;
exports.easeOutQuad = easeOutQuad;
exports.easeInOutQuad = easeInOutQuad;
exports.easeInCubic = easeInCubic;
exports.easeOutCubic = easeOutCubic;
exports.easeInOutCubic = easeInOutCubic;
exports.easeInQuart = easeInQuart;
exports.easeOutQuart = easeOutQuart;
exports.easeInOutQuart = easeInOutQuart;
exports.easeInQuint = easeInQuint;
exports.easeOutQuint = easeOutQuint;
exports.easeInOutQuint = easeInOutQuint;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=dx-core.umd.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
{
"_from": "@devexpress/dx-core",
"_id": "@devexpress/dx-core@1.0.0-beta.1",
"_inBundle": false,
"_integrity": "sha512-4Kv5RTlmlK7o2DF5BB5r2yWgshvFrUSHWzJzdSyBtFxsQzvI3vJqS0Z0mAplZCyYfRk4xh9SRp6I9DML66v0EQ==",
"_location": "/@devexpress/dx-core",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "@devexpress/dx-core",
"name": "@devexpress/dx-core",
"escapedName": "@devexpress%2fdx-core",
"scope": "@devexpress",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/@devexpress/dx-core/-/dx-core-1.0.0-beta.1.tgz",
"_shasum": "63383ec2bd3903d9a163c1316706cde32227d6b4",
"_spec": "@devexpress/dx-core",
"_where": "C:\\Users\\deranjer\\GoglandProjects\\torrent-project\\torrent-project",
"author": {
"name": "Developer Express Inc.",
"url": "https://www.devexpress.com/"
},
"bugs": {
"url": "https://github.com/DevExpress/devextreme-reactive/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Core library for DevExtreme Reactive Components",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-jest": "^21.2.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"core-js": "^2.5.1",
"eslint": "^4.10.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-filenames": "^1.2.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jest": "^21.3.0",
"jest": "^21.2.1",
"rollup": "0.50.0",
"rollup-plugin-babel": "^3.0.2",
"rollup-plugin-license": "^0.5.0"
},
"files": [
"dist"
],
"globalName": "DevExpress.DXCore",
"homepage": "https://devexpress.github.io/devextreme-reactive/",
"keywords": [
"pluggable",
"reactive",
"components"
],
"license": "SEE LICENSE IN README.md",
"main": "dist/dx-core.umd.js",
"module": "dist/dx-core.es.js",
"name": "@devexpress/dx-core",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/DevExpress/devextreme-reactive.git"
},
"scripts": {
"build": "rollup -c rollup.config.js",
"build:watch": "rollup -c rollup.config.js -w",
"lint": "eslint \"src/**\"",
"lint:fix": "yarn run lint -- --fix",
"test": "jest",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch"
},
"version": "1.0.0-beta.1"
}

View File

@@ -0,0 +1,7 @@
# DevExtreme Grid Core
Core library for the DevExtreme Reactive Grid component.
## License
[DevExtreme licensing](https://js.devexpress.com/licensing/).

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,90 @@
{
"_from": "@devexpress/dx-grid-core",
"_id": "@devexpress/dx-grid-core@1.0.0-beta.1",
"_inBundle": false,
"_integrity": "sha512-3hKM7JUKKHJGJ8C/B20SDfCbkxr7R6ADhKb/IfkWrepJQ78uPDce9wWxwkjl8EqSd8r1jKMWbg5dgXMU6zQwWw==",
"_location": "/@devexpress/dx-grid-core",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "@devexpress/dx-grid-core",
"name": "@devexpress/dx-grid-core",
"escapedName": "@devexpress%2fdx-grid-core",
"scope": "@devexpress",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/@devexpress/dx-grid-core/-/dx-grid-core-1.0.0-beta.1.tgz",
"_shasum": "48f76255c7192e7727f2c9b97efb2bf70774471d",
"_spec": "@devexpress/dx-grid-core",
"_where": "C:\\Users\\deranjer\\GoglandProjects\\torrent-project\\torrent-project",
"author": {
"name": "Developer Express Inc.",
"url": "https://www.devexpress.com/"
},
"bugs": {
"url": "https://github.com/DevExpress/devextreme-reactive/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Core library for the DevExtreme Reactive Grid component",
"devDependencies": {
"@devexpress/dx-core": "1.0.0-beta.1",
"babel-core": "^6.26.0",
"babel-jest": "^21.2.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"core-js": "^2.5.1",
"eslint": "^4.10.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-plugin-filenames": "^1.2.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jest": "^21.3.0",
"jest": "^21.2.1",
"rollup": "0.50.0",
"rollup-plugin-babel": "^3.0.2",
"rollup-plugin-license": "^0.5.0",
"seamless-immutable": "^7.1.2"
},
"files": [
"dist"
],
"globalName": "DevExpress.DXGridCore",
"homepage": "https://devexpress.github.io/devextreme-reactive/",
"keywords": [
"data",
"grid",
"table"
],
"license": "SEE LICENSE IN README.md",
"main": "dist/dx-grid-core.umd.js",
"module": "dist/dx-grid-core.es.js",
"name": "@devexpress/dx-grid-core",
"peerDependencies": {
"@devexpress/dx-core": "1.0.0-beta.1"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/DevExpress/devextreme-reactive.git"
},
"scripts": {
"build": "rollup -c rollup.config.js",
"build:watch": "rollup -c rollup.config.js -w",
"lint": "eslint \"src/**\"",
"lint:fix": "yarn run lint -- --fix",
"test": "jest",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch"
},
"version": "1.0.0-beta.1"
}

View File

@@ -0,0 +1,7 @@
# DevExtreme React Core
Core library for DevExtreme React Components.
## License
[DevExtreme licensing](https://js.devexpress.com/licensing/).

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../loose-envify/cli.js" "$@"
ret=$?
else
node "$basedir/../loose-envify/cli.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\loose-envify\cli.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\loose-envify\cli.js" %*
)

View File

@@ -0,0 +1,7 @@
# DevExtreme Reactive Core
Core library for DevExtreme Reactive Components.
## License
[DevExtreme licensing](https://js.devexpress.com/licensing/).

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