diff --git a/package/jsda/luci-app-filebrowser/Makefile b/package/jsda/luci-app-filebrowser/Makefile
deleted file mode 100755
index 63cc39d4a4..0000000000
--- a/package/jsda/luci-app-filebrowser/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-include $(TOPDIR)/rules.mk
-
-LUCI_TITLE:=LuCI page for filebrowser
-LUCI_DEPENDS:=
-
-include $(TOPDIR)/feeds/luci/luci.mk
-
-# call BuildPackage - OpenWrt buildroot signature
diff --git a/package/jsda/luci-app-filebrowser/README.md b/package/jsda/luci-app-filebrowser/README.md
deleted file mode 100755
index 648c2a7c79..0000000000
--- a/package/jsda/luci-app-filebrowser/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# luci-app-filebrowser -- web文件管理
-
-File browser app for OpenWrt/LEDE Luci backend
-
-main features
-
-- spa page with back and forward support
-- ajax file upload
-- symbolic link jump
-- rename and delete
-
-quick install or upgrade
-
->1. ssh to lede
->2. download the zipball and unzip it
->3. run `sh quick_install`
-
-[luci-material-theme](https://github.com/LuttyYang/luci-theme-material) recommended
-
-
diff --git a/package/jsda/luci-app-filebrowser/control b/package/jsda/luci-app-filebrowser/control
deleted file mode 100755
index bea82c07c6..0000000000
--- a/package/jsda/luci-app-filebrowser/control
+++ /dev/null
@@ -1,12 +0,0 @@
-Package: luci-app-filebrowser
-Version: 1.0
-Description: File browser app for OpenWrt Luci backend.
-Section: extras
-Priority: optional
-Maintainer: giaulo
-License: CLOSED
-Architecture: all
-OE: luci-app-filebrowser
-Homepage: unknown
-Depends: luci-base
-Source: N/A
diff --git a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/fb.css b/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/fb.css
deleted file mode 100755
index 96cbbb3fc5..0000000000
--- a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/fb.css
+++ /dev/null
@@ -1,68 +0,0 @@
-.fb-container {
- margin-top: 1rem;
-}
-.fb-container .cbi-button {
- height: 1.8rem;
-}
-.fb-container .cbi-input-text {
- margin-bottom: 1rem;
- width: 100%;
-}
-.fb-container .panel-title {
- padding-bottom: 0;
- width: 50%;
- border-bottom: none;
-}
-.fb-container .panel-container {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding-bottom: 1rem;
- border-bottom: 1px solid #eee;
-}
-.fb-container .upload-container {
- display: none;
- margin: 1rem 0;
-}
-.fb-container .upload-file {
- margin-right: 2rem;
-}
-.fb-container .cbi-value-field {
- text-align: left;
-}
-.fb-container .parent-icon strong {
- margin-left: 1rem;
-}
-.fb-container td[class$="-icon"] {
- cursor: pointer;
-}
-.fb-container .file-icon, .fb-container .folder-icon, .fb-container .link-icon {
- position: relative;
-}
-.fb-container .file-icon:before, .fb-container .folder-icon:before, .fb-container .link-icon:before {
- display: inline-block;
- width: 1.5rem;
- height: 1.5rem;
- content: '';
- background-size: contain;
- margin: 0 0.5rem 0 1rem;
- vertical-align: middle;
-}
-.fb-container .file-icon:before {
- background-image: url(file-icon.png);
-}
-.fb-container .folder-icon:before {
- background-image: url(folder-icon.png);
-}
-.fb-container .link-icon:before {
- background-image: url(link-icon.png);
-}
-@media screen and (max-width: 480px) {
- .fb-container .upload-file {
- width: 14.6rem;
- }
- .fb-container .cbi-value-owner,
- .fb-container .cbi-value-perm {
- display: none;
- }
-}
diff --git a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/fb.js b/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/fb.js
deleted file mode 100755
index 504e11157c..0000000000
--- a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/fb.js
+++ /dev/null
@@ -1,234 +0,0 @@
-String.prototype.replaceAll = function(search, replacement) {
- var target = this;
- return target.replace(new RegExp(search, 'g'), replacement);
-};
-(function () {
- var iwxhr = new XHR();
- var listElem = document.getElementById("list-content");
- listElem.onclick = handleClick;
- var currentPath;
- var pathElem = document.getElementById("current-path");
- pathElem.onblur = function () {
- update_list(this.value.trim());
- };
- pathElem.onkeyup = function (evt) {
- if (evt.keyCode == 13) {
- this.blur();
- }
- };
- function removePath(filename, isdir) {
- var c = confirm('确认删除 ' + filename + ' ?');
- if (c) {
- iwxhr.get('/cgi-bin/luci/admin/system/filebrowser_delete',
- {
- path: concatPath(currentPath, filename),
- isdir: isdir
- },
- function (x, res) {
- if (res.ec === 0) {
- refresh_list(res.data, currentPath);
- }
- });
- }
- }
- function renamePath(filename) {
- var newname = prompt('输入新名字:', filename);
- if (newname) {
- newname = newname.trim();
- if (newname != filename) {
- var newpath = concatPath(currentPath, newname);
- iwxhr.get('/cgi-bin/luci/admin/system/filebrowser_rename',
- {
- filepath: concatPath(currentPath, filename),
- newpath: newpath
- },
- function (x, res) {
- if (res.ec === 0) {
- refresh_list(res.data, currentPath);
- }
- }
- );
- }
- }
- }
-
- function openpath(filename, dirname) {
- dirname = dirname || currentPath;
- window.open('/cgi-bin/luci/admin/system/filebrowser_open?path='
- + encodeURIComponent(dirname) + '&filename='
- + encodeURIComponent(filename));
- }
-
- function getFileElem(elem) {
- if (elem.className.indexOf('-icon') > -1) {
- return elem;
- }
- else if (elem.parentNode.className.indexOf('-icon') > -1) {
- return elem.parentNode;
- }
- }
-
- function concatPath(path, filename) {
- if (path === '/') {
- return path + filename;
- }
- else {
- return path.replace(/\/$/, '') + '/' + filename;
- }
- }
-
- function handleClick(evt) {
- var targetElem = evt.target;
- var infoElem;
- if (targetElem.className.indexOf('cbi-button-remove') > -1) {
- infoElem = targetElem.parentNode.parentNode;
- removePath(infoElem.dataset['filename'] , infoElem.dataset['isdir'])
- }
- else if (targetElem.className.indexOf('cbi-button-edit') > -1) {
- renamePath(targetElem.parentNode.parentNode.dataset['filename']);
- }
- else if (targetElem = getFileElem(targetElem)) {
- if (targetElem.className.indexOf('parent-icon') > -1) {
- update_list(currentPath.replace(/\/[^/]+($|\/$)/, ''));
- }
- else if (targetElem.className.indexOf('file-icon') > -1) {
- openpath(targetElem.parentNode.dataset['filename']);
- }
- else if (targetElem.className.indexOf('link-icon') > -1) {
- infoElem = targetElem.parentNode;
- var filepath = infoElem.dataset['linktarget'];
- if (filepath) {
- if (infoElem.dataset['isdir'] === "1") {
- update_list(filepath);
- }
- else {
- var lastSlash = filepath.lastIndexOf('/');
- openpath(filepath.substring(lastSlash + 1), filepath.substring(0, lastSlash));
- }
- }
- }
- else if (targetElem.className.indexOf('folder-icon') > -1) {
- update_list(concatPath(currentPath, targetElem.parentNode.dataset['filename']))
- }
- }
- }
- function refresh_list(filenames, path) {
- var listHtml = '
';
- if (path !== '/') {
- listHtml += '| .. |
';
- }
- if (filenames) {
- for (var i = 0; i < filenames.length; i++) {
- var line = filenames[i];
- if (line) {
- var f = line.match(/(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+([\S\s]+)/);
- var isLink = f[1][0] === 'z' || f[1][0] === 'l' || f[1][0] === 'x';
- var o = {
- displayname: f[9],
- filename: isLink ? f[9].split(' -> ')[0] : f[9],
- perms: f[1],
- date: f[7] + ' ' + f[6] + ' ' + f[8],
- size: f[5],
- owner: f[3],
- icon: (f[1][0] === 'd') ? "folder-icon" : (isLink ? "link-icon" : "file-icon")
- };
- listHtml += ''
- + '| '
- + '' + o.displayname + ''
- + ' | '
- + ''+o.owner+' | '
- + ''+o.date+' | '
- + ''+o.size+' | '
- + ''+o.perms+' | '
- + '\
- | '
- + '
';
- }
- }
- }
- listHtml += "
";
- listElem.innerHTML = listHtml;
- }
- function update_list(path, opt) {
- opt = opt || {};
- path = concatPath(path, '');
- if (currentPath != path) {
- iwxhr.get('/cgi-bin/luci/admin/system/filebrowser_list',
- {path: path},
- function (x, res) {
- if (res.ec === 0) {
- refresh_list(res.data, path);
- }
- else {
- refresh_list([], path);
- }
- }
- );
- if (!opt.popState) {
- history.pushState({path: path}, null, '?path=' + path);
- }
- currentPath = path;
- pathElem.value = currentPath;
- }
- };
-
- var uploadToggle = document.getElementById('upload-toggle');
- var uploadContainer = document.getElementById('upload-container');
- var isUploadHide = true;
- uploadToggle.onclick = function() {
- if (isUploadHide) {
- uploadContainer.style.display = 'inline-flex';
- }
- else {
- uploadContainer.style.display = 'none';
- }
- isUploadHide = !isUploadHide;
- };
- var uploadBtn = uploadContainer.getElementsByClassName('cbi-input-apply')[0];
- uploadBtn.onclick = function (evt) {
- var uploadinput = document.getElementById('upload-file');
- var fullPath = uploadinput.value;
- if (!fullPath) {
- evt.preventDefault();
- }
- else {
- var formData = new FormData();
- var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
- formData.append('upload-filename', fullPath.substring(startIndex + 1));
- formData.append('upload-dir', concatPath(currentPath, ''));
- formData.append('upload-file', uploadinput.files[0]);
- var xhr = new XMLHttpRequest();
- xhr.open("POST", "/cgi-bin/luci/admin/system/filebrowser_upload", true);
- xhr.onload = function() {
- if (xhr.status == 200) {
- var res = JSON.parse(xhr.responseText);
- refresh_list(res.data, currentPath);
- uploadinput.value = '';
- }
- else {
- alert('上传失败');
- }
- };
- xhr.send(formData);
- }
- };
-
- document.addEventListener('DOMContentLoaded', function(evt) {
- var initPath = '/';
- if (/path=([/\w]+)/.test(location.search)) {
- initPath = RegExp.$1;
- }
- update_list(initPath, {popState: true});
- });
- window.addEventListener('popstate', function (evt) {
- var path = '/';
- if (evt.state && evt.state.path) {
- path = evt.state.path;
- }
- update_list(path, {popState: true});
- });
-
-})();
\ No newline at end of file
diff --git a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/file-icon.png b/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/file-icon.png
deleted file mode 100755
index f156dc1c7c..0000000000
Binary files a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/file-icon.png and /dev/null differ
diff --git a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/folder-icon.png b/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/folder-icon.png
deleted file mode 100755
index 1370df3ad5..0000000000
Binary files a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/folder-icon.png and /dev/null differ
diff --git a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/link-icon.png b/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/link-icon.png
deleted file mode 100755
index 03cc82cdfa..0000000000
Binary files a/package/jsda/luci-app-filebrowser/htdocs/luci-static/resources/fb/link-icon.png and /dev/null differ
diff --git a/package/jsda/luci-app-filebrowser/luasrc/controller/filebrowser.lua b/package/jsda/luci-app-filebrowser/luasrc/controller/filebrowser.lua
deleted file mode 100755
index f561233ebf..0000000000
--- a/package/jsda/luci-app-filebrowser/luasrc/controller/filebrowser.lua
+++ /dev/null
@@ -1,201 +0,0 @@
-module("luci.controller.filebrowser", package.seeall)
-
-function index()
-
- page = entry({"admin", "system", "filebrowser"}, template("filebrowser"), _("文件管理"), 60)
- page.i18n = "base"
- page.dependent = true
-
- page = entry({"admin", "system", "filebrowser_list"}, call("filebrowser_list"), nil)
- page.leaf = true
-
- page = entry({"admin", "system", "filebrowser_open"}, call("filebrowser_open"), nil)
- page.leaf = true
-
- page = entry({"admin", "system", "filebrowser_delete"}, call("filebrowser_delete"), nil)
- page.leaf = true
-
- page = entry({"admin", "system", "filebrowser_rename"}, call("filebrowser_rename"), nil)
- page.leaf = true
-
- page = entry({"admin", "system", "filebrowser_upload"}, call("filebrowser_upload"), nil)
- page.leaf = true
-
-end
-
-function list_response(path, success)
- luci.http.prepare_content("application/json")
- local result
- if success then
- local rv = scandir(path)
- result = {
- ec = 0,
- data = rv
- }
- else
- result = {
- ec = 1
- }
- end
- luci.http.write_json(result)
-end
-
-function filebrowser_list()
- local path = luci.http.formvalue("path")
- list_response(path, true)
-end
-
-function filebrowser_open()
- local path = luci.http.formvalue("path")
- local filename = luci.http.formvalue("filename")
- local io = require "io"
- local mime = to_mime(filename)
-
- file = path..filename
-
- local download_fpi = io.open(file, "r")
- luci.http.header('Content-Disposition', 'inline; filename="'..filename..'"' )
- luci.http.prepare_content(mime)
- luci.ltn12.pump.all(luci.ltn12.source.file(download_fpi), luci.http.write)
-end
-
-function filebrowser_delete()
- local path = luci.http.formvalue("path")
- local isdir = luci.http.formvalue("isdir")
- path = path:gsub("<>", "/")
- path = path:gsub(" ", "\ ")
- local success
- if isdir then
- success = os.execute('rm -r "'..path..'"')
- else
- success = os.remove(path)
- end
- list_response(nixio.fs.dirname(path), success)
-end
-
-function filebrowser_rename()
- local filepath = luci.http.formvalue("filepath")
- local newpath = luci.http.formvalue("newpath")
- local success = os.execute('mv "'..filepath..'" "'..newpath..'"')
- list_response(nixio.fs.dirname(filepath), success)
-end
-
-function filebrowser_upload()
- local filecontent = luci.http.formvalue("upload-file")
- local filename = luci.http.formvalue("upload-filename")
- local uploaddir = luci.http.formvalue("upload-dir")
- local filepath = uploaddir..filename
-
- local fp
- luci.http.setfilehandler(
- function(meta, chunk, eof)
- if not fp and meta and meta.name == "upload-file" then
- fp = io.open(filepath, "w")
- end
- if fp and chunk then
- fp:write(chunk)
- end
- if fp and eof then
- fp:close()
- end
- end
- )
-
- list_response(uploaddir, true)
-end
-
-function scandir(directory)
- local i, t, popen = 0, {}, io.popen
-
- local pfile = popen("ls -lh \""..directory.."\" | egrep '^d' ; ls -lh \""..directory.."\" | egrep -v '^d|^l'")
- for fileinfo in pfile:lines() do
- i = i + 1
- t[i] = fileinfo
- end
- pfile:close()
- pfile = popen("ls -lh \""..directory.."\" | egrep '^l' ;")
- for fileinfo in pfile:lines() do
- i = i + 1
- linkindex, _, linkpath = string.find(fileinfo, "->%s+(.+)$")
- local finalpath;
- if string.sub(linkpath, 1, 1) == "/" then
- finalpath = linkpath
- else
- finalpath = nixio.fs.realpath(directory..linkpath)
- end
- local linktype;
- if not finalpath then
- finalpath = linkpath;
- linktype = 'x'
- elseif nixio.fs.stat(finalpath, "type") == "dir" then
- linktype = 'z'
- else
- linktype = 'l'
- end
- fileinfo = string.sub(fileinfo, 2, linkindex - 1)
- fileinfo = linktype..fileinfo.."-> "..finalpath
- t[i] = fileinfo
- end
- pfile:close()
- return t
-end
-
-MIME_TYPES = {
- ["txt"] = "text/plain";
- ["conf"] = "text/plain";
- ["ovpn"] = "text/plain";
- ["log"] = "text/plain";
- ["js"] = "text/javascript";
- ["json"] = "application/json";
- ["css"] = "text/css";
- ["htm"] = "text/html";
- ["html"] = "text/html";
- ["patch"] = "text/x-patch";
- ["c"] = "text/x-csrc";
- ["h"] = "text/x-chdr";
- ["o"] = "text/x-object";
- ["ko"] = "text/x-object";
-
- ["bmp"] = "image/bmp";
- ["gif"] = "image/gif";
- ["png"] = "image/png";
- ["jpg"] = "image/jpeg";
- ["jpeg"] = "image/jpeg";
- ["svg"] = "image/svg+xml";
-
- ["zip"] = "application/zip";
- ["pdf"] = "application/pdf";
- ["xml"] = "application/xml";
- ["xsl"] = "application/xml";
- ["doc"] = "application/msword";
- ["ppt"] = "application/vnd.ms-powerpoint";
- ["xls"] = "application/vnd.ms-excel";
- ["odt"] = "application/vnd.oasis.opendocument.text";
- ["odp"] = "application/vnd.oasis.opendocument.presentation";
- ["pl"] = "application/x-perl";
- ["sh"] = "application/x-shellscript";
- ["php"] = "application/x-php";
- ["deb"] = "application/x-deb";
- ["iso"] = "application/x-cd-image";
- ["tgz"] = "application/x-compressed-tar";
-
- ["mp3"] = "audio/mpeg";
- ["ogg"] = "audio/x-vorbis+ogg";
- ["wav"] = "audio/x-wav";
-
- ["mpg"] = "video/mpeg";
- ["mpeg"] = "video/mpeg";
- ["avi"] = "video/x-msvideo";
-}
-
-function to_mime(filename)
- if type(filename) == "string" then
- local ext = filename:match("[^%.]+$")
-
- if ext and MIME_TYPES[ext:lower()] then
- return MIME_TYPES[ext:lower()]
- end
- end
-
- return "application/octet-stream"
-end
diff --git a/package/jsda/luci-app-filebrowser/luasrc/view/filebrowser.htm b/package/jsda/luci-app-filebrowser/luasrc/view/filebrowser.htm
deleted file mode 100755
index 6e0e038dfe..0000000000
--- a/package/jsda/luci-app-filebrowser/luasrc/view/filebrowser.htm
+++ /dev/null
@@ -1,20 +0,0 @@
-<%+header%>
-
-
-文件管理
-
-
-
-
-<%+footer%>
diff --git a/package/jsda/luci-app-filebrowser/quick_install b/package/jsda/luci-app-filebrowser/quick_install
deleted file mode 100755
index 00ea3aaab9..0000000000
--- a/package/jsda/luci-app-filebrowser/quick_install
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-cp -R htdocs/luci-static/resources/* /www/luci-static/resources/
-cp -R luasrc/* /usr/lib/lua/luci/
-
-if [ -z "$1" ]; then
- ver=$(date +%s)
-else
- ver=$1
-fi
-sed -i "s/@ver/$ver/g" /usr/lib/lua/luci/view/filebrowser.htm
-
-rm -rf /tmp/luci*
diff --git a/package/jsda/luci-app-filebrowser/screenshot.png b/package/jsda/luci-app-filebrowser/screenshot.png
deleted file mode 100755
index 424a167581..0000000000
Binary files a/package/jsda/luci-app-filebrowser/screenshot.png and /dev/null differ