1.3.0
This commit is contained in:
parent
4c42195989
commit
05a40748c4
14
package.json
14
package.json
@ -3,7 +3,7 @@
|
|||||||
"productName": "cyb3r-youtube-downloader",
|
"productName": "cyb3r-youtube-downloader",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "My Electron application description",
|
"description": "My Electron application description",
|
||||||
"main": "src/index.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron-forge start",
|
"start": "electron-forge start",
|
||||||
"package": "electron-forge package",
|
"package": "electron-forge package",
|
||||||
@ -31,13 +31,14 @@
|
|||||||
"packageManager": "npm"
|
"packageManager": "npm"
|
||||||
},
|
},
|
||||||
"electronWinstallerConfig": {
|
"electronWinstallerConfig": {
|
||||||
"name": "cyb3r_youtube_downloader"
|
"name": "cyb3r_youtube_downloader",
|
||||||
|
"icon": "app.ico"
|
||||||
},
|
},
|
||||||
"electronInstallerDebian": {},
|
"electronInstallerDebian": {},
|
||||||
"electronInstallerRedhat": {},
|
"electronInstallerRedhat": {},
|
||||||
"github_repository": {
|
"github_repository": {
|
||||||
"owner": "",
|
"owner": "Theenoro",
|
||||||
"name": ""
|
"name": "https://git.tooru.thee.moe/theenoro/electron-simple-youtube-downloader"
|
||||||
},
|
},
|
||||||
"windowsStoreConfig": {
|
"windowsStoreConfig": {
|
||||||
"packageName": "",
|
"packageName": "",
|
||||||
@ -46,10 +47,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"electron-compile": "^6.4.1",
|
|
||||||
"electron": "^1.6.11",
|
"electron": "^1.6.11",
|
||||||
|
"electron-compile": "^6.4.1",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"request": "^2.81.0"
|
"request": "^2.81.0",
|
||||||
|
"unzip": "^0.1.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-plugin-transform-async-to-generator": "^6.24.1",
|
"babel-plugin-transform-async-to-generator": "^6.24.1",
|
||||||
|
205
src/app/view/init.html
Normal file
205
src/app/view/init.html
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
if (typeof module === 'object') {
|
||||||
|
window.module = module;
|
||||||
|
module = undefined;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="./../libs/jquery/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="./../libs/bootstrap/js/bootstrap.js"></script>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title></title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes arrow-spin {
|
||||||
|
100% {
|
||||||
|
transform: rotate(179deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes arrow-spin {
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(179deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload,
|
||||||
|
.psoload *,
|
||||||
|
.psoload *:before,
|
||||||
|
.psoload *:after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: all 0.3s;
|
||||||
|
-webkit-transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload {
|
||||||
|
position: relative;
|
||||||
|
margin: 30px auto;
|
||||||
|
height: 150px;
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .straight,
|
||||||
|
.psoload .curve {
|
||||||
|
position: absolute;
|
||||||
|
top: 17.5%;
|
||||||
|
left: 17.5%;
|
||||||
|
width: 65%;
|
||||||
|
height: 65%;
|
||||||
|
border-radius: 100%;
|
||||||
|
animation: arrow-spin 0.85s cubic-bezier(0.2, 0.8, 0.9, 0.1) infinite;
|
||||||
|
-webkit-animation: arrow-spin 0.85s cubic-bezier(0.2, 0.8, 0.9, 0.1) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .straight:before,
|
||||||
|
.psoload .straight:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 15%;
|
||||||
|
border-bottom: 3px solid #eee;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .straight:before {
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .straight:after {
|
||||||
|
bottom: 5px;
|
||||||
|
right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .curve:before,
|
||||||
|
.psoload .curve:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 45px;
|
||||||
|
height: 10px;
|
||||||
|
border: solid 3px transparent;
|
||||||
|
border-top-color: #eee;
|
||||||
|
border-radius: 50%/10px 10px 0 0;
|
||||||
|
z-index: 90001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .curve:before {
|
||||||
|
transform: rotate(-63deg) translateX(-27px) translateY(-4px);
|
||||||
|
-webkit-transform: rotate(-63deg) translateX(-27px) translateY(-4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .curve:after {
|
||||||
|
bottom: 5px;
|
||||||
|
right: 5px;
|
||||||
|
transform: rotate(115deg) translateX(-26px) translateY(-12px);
|
||||||
|
-webkit-transform: rotate(115deg) translateX(-26px) translateY(-12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .center {
|
||||||
|
position: absolute;
|
||||||
|
top: 20%;
|
||||||
|
left: 20%;
|
||||||
|
width: 60%;
|
||||||
|
height: 60%;
|
||||||
|
border-radius: 100%;
|
||||||
|
border: 3px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .inner {
|
||||||
|
position: absolute;
|
||||||
|
top: 25%;
|
||||||
|
left: 25%;
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
border-radius: 100%;
|
||||||
|
animation: arrow-spin 0.85s cubic-bezier(0.2, 0.8, 0.9, 0.1) infinite reverse;
|
||||||
|
-webkit-animation: arrow-spin 0.85s cubic-bezier(0.2, 0.8, 0.9, 0.1) infinite reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .inner:before,
|
||||||
|
.psoload .inner:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border: 6px solid transparent;
|
||||||
|
border-bottom-width: 11px;
|
||||||
|
border-bottom-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .inner:before {
|
||||||
|
top: 12px;
|
||||||
|
left: 12px;
|
||||||
|
transform: rotate(128deg);
|
||||||
|
-webkit-transform: rotate(128deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.psoload .inner:after {
|
||||||
|
bottom: 12px;
|
||||||
|
right: 12px;
|
||||||
|
transform: rotate(-48deg);
|
||||||
|
-webkit-transform: rotate(-48deg);
|
||||||
|
}
|
||||||
|
.progress{
|
||||||
|
height:10px;
|
||||||
|
}
|
||||||
|
.progress .progress-bar{
|
||||||
|
height:5px;
|
||||||
|
width:30px;
|
||||||
|
background-color:#FFF;
|
||||||
|
content:"";
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="psoload">
|
||||||
|
<div class="straight"></div>
|
||||||
|
<div class="curve"></div>
|
||||||
|
<div class="center"></div>
|
||||||
|
<div class="inner"></div>
|
||||||
|
</div>
|
||||||
|
<iframe id="coub" src="https://coub.com/embed/ulak9?muted=false&autostart=true&originalSize=false&startWithHD=false" allowfullscreen="true" frameborder="0" width="320" height="180"></iframe><script async src="https://c-cdn.coub.com/embed-runner.js"></script>
|
||||||
|
<hr/>
|
||||||
|
<div class="progress">
|
||||||
|
<div class="progress-bar" id="main"></div>
|
||||||
|
<div class="progress-bar" id="single"></div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$(function(){
|
||||||
|
var start = [
|
||||||
|
"whbex",
|
||||||
|
"wf0jb",
|
||||||
|
"ulak9",
|
||||||
|
"wcmxa",
|
||||||
|
"wc5e2"
|
||||||
|
];
|
||||||
|
var x = Math.floor(Math.random()*start.length)
|
||||||
|
$('#coub').attr('src','https://coub.com/embed/'+start[x]+'?muted=false&autostart=true&originalSize=false&startWithHD=false')
|
||||||
|
const ipcRenderer = require('electron').ipcRenderer;
|
||||||
|
ipcRenderer.send('download-lib', {});
|
||||||
|
ipcRenderer.on('progress', function(event, arg) {
|
||||||
|
console.log(arg); // prints "pong"
|
||||||
|
$('#single').css("width",arg.percent+"%");
|
||||||
|
}).on('fin-loading',function(event,arg){
|
||||||
|
$('#main').css("width","100%");
|
||||||
|
setTimeout(function(){
|
||||||
|
ipcRenderer.send('start-full', {});
|
||||||
|
},1000)
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
126
src/controller/download.js
Normal file
126
src/controller/download.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
const request = require('request');
|
||||||
|
const fs = require('fs')
|
||||||
|
const ipcMain = require('electron').ipcMain;
|
||||||
|
const unzip = require('unzip')
|
||||||
|
|
||||||
|
|
||||||
|
var libsx = {
|
||||||
|
"ffmpeg":"ffmpeg",
|
||||||
|
"ffplay":"ffplay",
|
||||||
|
"ffprobe":"ffprobe",
|
||||||
|
"youtube-dl":"youtube-dl"
|
||||||
|
}
|
||||||
|
var libs = {};
|
||||||
|
|
||||||
|
libs.listen = null;
|
||||||
|
libs.libs = null;
|
||||||
|
ipcMain
|
||||||
|
.on('download-lib', (event, arg)=>{
|
||||||
|
console.log('TEST')
|
||||||
|
libs.listen = event;
|
||||||
|
console.log(`This platform is ${process.platform}`);
|
||||||
|
switch (process.platform) {
|
||||||
|
case "win32":
|
||||||
|
for (var lib in libsx) {
|
||||||
|
libsx[lib] = libsx[lib]+'.exe';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
for (var lib in libsx) {
|
||||||
|
if (fs.existsSync(global.dir+"/lib/"+libsx[lib])) {
|
||||||
|
|
||||||
|
}else{
|
||||||
|
libsx[lib] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
libs.libs = libsx;
|
||||||
|
if(libsx['ffmpeg'] === null || libsx['ffplay'] === null || libsx['ffprobe'] === null ){
|
||||||
|
var z = 0;
|
||||||
|
libs.download(libs.ff(process.platform),"ffmpeg",function(data,file){
|
||||||
|
fs.createReadStream(file)
|
||||||
|
.pipe(unzip.Parse())
|
||||||
|
.on('entry', function (entry) {
|
||||||
|
var fileName = entry.path;
|
||||||
|
var type = entry.type; // 'Directory' or 'File'
|
||||||
|
var size = entry.size;
|
||||||
|
console.log(fileName)
|
||||||
|
if (fileName === "ffmpeg-latest-win32-static/bin/ffmpeg.exe" || fileName === "ffmpeg-latest-win32-static/bin/ffprobe.exe" || fileName === "ffmpeg-latest-win32-static/bin/ffplay.exe") {
|
||||||
|
entry.pipe(fs.createWriteStream(global.dir+'/lib/'+fileName.split('/')[2]));
|
||||||
|
console.log('TEST')
|
||||||
|
z++;
|
||||||
|
if(z == 3){
|
||||||
|
libs.checkNext('youtube-dl');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entry.autodrain();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
libs.checkNext('youtube-dl');
|
||||||
|
}
|
||||||
|
console.dir(libsx);
|
||||||
|
})
|
||||||
|
libs.checkNext = (nxt)=>{
|
||||||
|
if( libs.libs['youtube-dl'] === null ){
|
||||||
|
libs.yt_dl(process.platform,function(){
|
||||||
|
libs.startFull();
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
libs.startFull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
libs.startFull = ()=>{
|
||||||
|
libs.listen.sender.send('fin-loading',{});
|
||||||
|
}
|
||||||
|
libs.ff = (os)=>{
|
||||||
|
var url = "";
|
||||||
|
switch (os) {
|
||||||
|
case "win32":
|
||||||
|
url = 'http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-latest-win32-static.zip';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
libs.yt_dl = (os,cb)=>{
|
||||||
|
var url = "";
|
||||||
|
switch (os) {
|
||||||
|
case "win32":
|
||||||
|
url = 'https://yt-dl.org/downloads/2017.08.13/youtube-dl.exe'
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
}
|
||||||
|
libs.download(url,"youtube-dl",function(data,file){
|
||||||
|
fs.renameSync(file,global.dir+'/lib/youtube-dl.exe');
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
libs.download = (url,data,cb)=>{
|
||||||
|
var r = request(url);
|
||||||
|
var actual = 1;
|
||||||
|
var full = 100;
|
||||||
|
var perc = 0;
|
||||||
|
r.on('data', function (chunk) {
|
||||||
|
actual += chunk.length;
|
||||||
|
perc = actual / full * 100;
|
||||||
|
console.log(perc);
|
||||||
|
libs.listen.sender.send('progress',{percent :Math.floor(perc)});
|
||||||
|
});
|
||||||
|
|
||||||
|
r.on('response', function (res) {
|
||||||
|
res.pipe(fs.createWriteStream(global.dir+'/tmp/' + data + '.' + res.headers['content-type'].split('/')[1]));
|
||||||
|
full = res.headers[ 'content-length' ] ;
|
||||||
|
res.on('end', function () {
|
||||||
|
cb(data,global.dir+'/tmp/' + data + '.' + res.headers['content-type'].split('/')[1]);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = libs;
|
129
src/index.js
129
src/index.js
@ -9,45 +9,100 @@ const {
|
|||||||
} = require('electron');
|
} = require('electron');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const yt_dl = require('./controller/youtube-dl')
|
const yt_dl = require('./controller/youtube-dl')
|
||||||
|
const dl = require('./controller/download');
|
||||||
|
|
||||||
var win ;
|
if (!fs.existsSync(global.dir+'/tmp/inst')) {
|
||||||
|
fs.writeFileSync(global.dir+'/tmp/inst',"out");
|
||||||
|
var win;
|
||||||
|
const createWindow = () =>{
|
||||||
|
win = new BrowserWindow({
|
||||||
|
width: 320,
|
||||||
|
height: 500,
|
||||||
|
show: false,
|
||||||
|
frame: false
|
||||||
|
})
|
||||||
|
win.once('ready-to-show', () => {
|
||||||
|
})
|
||||||
|
|
||||||
app.getPath('documents')
|
win.on('closed', () => {
|
||||||
const createWindow = () =>{
|
win = null;
|
||||||
win = new BrowserWindow({
|
});
|
||||||
width: 1010,
|
}
|
||||||
height: 800,
|
app.on('ready', createWindow);
|
||||||
minWidth: 1010,
|
app.on('window-all-closed', () => {
|
||||||
minHeight: 565,
|
if (process.platform !== 'darwin') {
|
||||||
show: false,
|
app.quit();
|
||||||
frame: true
|
}
|
||||||
})
|
});
|
||||||
win.loadURL(`file://${__dirname}/app/view/layout.html`)
|
}else{
|
||||||
win.once('ready-to-show', () => {
|
var win ;
|
||||||
win.show()
|
|
||||||
//var x = new yt_dl("https://www.youtube.com/watch?v=UbQgXeY_zi4")
|
|
||||||
//x.download();
|
|
||||||
})
|
|
||||||
|
|
||||||
win.on('closed', () => {
|
|
||||||
// Dereference the window object, usually you would store windows
|
app.getPath('documents')
|
||||||
// in an array if your app supports multi windows, this is the time
|
const createWindow = () =>{
|
||||||
// when you should delete the corresponding element.
|
|
||||||
win = null;
|
//dl.download(dl.ff(process.platform));
|
||||||
|
/*
|
||||||
|
|
||||||
|
win = new BrowserWindow({
|
||||||
|
width: 1010,
|
||||||
|
height: 800,
|
||||||
|
minWidth: 1010,
|
||||||
|
minHeight: 565,
|
||||||
|
show: false,
|
||||||
|
frame: true
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
win = new BrowserWindow({
|
||||||
|
width: 320,
|
||||||
|
height: 500,
|
||||||
|
show: false,
|
||||||
|
frame: false
|
||||||
|
})
|
||||||
|
ipcMain
|
||||||
|
.on('start-full', (event, arg)=>{
|
||||||
|
|
||||||
|
var win2 = new BrowserWindow({
|
||||||
|
width: 1010,
|
||||||
|
height: 800,
|
||||||
|
minWidth: 1010,
|
||||||
|
minHeight: 565,
|
||||||
|
show: true,
|
||||||
|
frame: true
|
||||||
|
})
|
||||||
|
win.close();
|
||||||
|
win2.loadURL(`file://${__dirname}/app/view/layout.html`)
|
||||||
|
win = win2;
|
||||||
|
});
|
||||||
|
win.loadURL(`file://${__dirname}/app/view/init.html`)
|
||||||
|
win.once('ready-to-show', () => {
|
||||||
|
win.show()
|
||||||
|
//var x = new yt_dl("https://www.youtube.com/watch?v=UbQgXeY_zi4")
|
||||||
|
//x.download();
|
||||||
|
})
|
||||||
|
|
||||||
|
win.on('closed', () => {
|
||||||
|
// Dereference the window object, usually you would store windows
|
||||||
|
// in an array if your app supports multi windows, this is the time
|
||||||
|
// when you should delete the corresponding element.
|
||||||
|
win = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.on('ready', createWindow);
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
// On OS X it is common for applications and their menu bar
|
||||||
|
// to stay active until the user quits explicitly with Cmd + Q
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
app.on('activate', () => {
|
||||||
|
// On OS X it's common to re-create a window in the app when the
|
||||||
|
// dock icon is clicked and there are no other windows open.
|
||||||
|
if (mainWindow === null) {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
app.on('ready', createWindow);
|
|
||||||
app.on('window-all-closed', () => {
|
module.exports = app;
|
||||||
// On OS X it is common for applications and their menu bar
|
|
||||||
// to stay active until the user quits explicitly with Cmd + Q
|
|
||||||
if (process.platform !== 'darwin') {
|
|
||||||
app.quit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
app.on('activate', () => {
|
|
||||||
// On OS X it's common to re-create a window in the app when the
|
|
||||||
// dock icon is clicked and there are no other windows open.
|
|
||||||
if (mainWindow === null) {
|
|
||||||
createWindow();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
46
src/main.js
Normal file
46
src/main.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
var app = require('./index');
|
||||||
|
|
||||||
|
var handleStartupEvent = function() {
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var squirrelCommand = process.argv[1];
|
||||||
|
console.log(squirrelCommand);
|
||||||
|
switch (squirrelCommand) {
|
||||||
|
case '--squirrel-install':
|
||||||
|
target = path.basename(process.execPath);
|
||||||
|
updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe');
|
||||||
|
var createShortcut = updateDotExe + ' --createShortcut=' + target + ' --shortcut-locations=Desktop,StartMenu' ;
|
||||||
|
console.log (createShortcut);
|
||||||
|
exec(createShortcut);
|
||||||
|
// Always quit when done
|
||||||
|
app.quit();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case '--squirrel-uninstall':
|
||||||
|
// Undo anything you did in the --squirrel-install and
|
||||||
|
// --squirrel-updated handlers
|
||||||
|
target = path.basename(process.execPath);
|
||||||
|
updateDotExe = path.resolve(path.dirname(process.execPath), '..', 'update.exe');
|
||||||
|
var createShortcut = updateDotExe + ' --removeShortcut=' + target ;
|
||||||
|
console.log (createShortcut);
|
||||||
|
exec(createShortcut);
|
||||||
|
// Always quit when done
|
||||||
|
app.quit();
|
||||||
|
return true;
|
||||||
|
case '--squirrel-obsolete':
|
||||||
|
// This is called on the outgoing version of your app before
|
||||||
|
// we update to the new version - it's the opposite of
|
||||||
|
// --squirrel-updated
|
||||||
|
app.quit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
if (handleStartupEvent()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
0
src/tmp/dummy
Normal file
0
src/tmp/dummy
Normal file
Loading…
Reference in New Issue
Block a user