Full Code of Mintimate/OneindexM for AI

master ee9c63a9681d cached
87 files
471.0 KB
140.7k tokens
387 symbols
1 requests
Download .txt
Showing preview only (510K chars total). Download the full file or copy to clipboard to get everything.
Repository: Mintimate/OneindexM
Branch: master
Commit: ee9c63a9681d
Files: 87
Total size: 471.0 KB

Directory structure:
gitextract_zkw3fajl/

├── .gitignore
├── README.md
├── cache/
│   └── abc
├── config/
│   └── README.md
├── controller/
│   ├── AdminController.php
│   ├── CommonController.php
│   ├── ImagesController.php
│   ├── IndexController.php
│   └── UploadController.php
├── index.php
├── init.php
├── lib/
│   ├── Parsedown.php
│   ├── cache/
│   │   ├── filecache_.php
│   │   ├── memcache_.php
│   │   ├── redis_.php
│   │   └── secache_.php
│   ├── cache.php
│   ├── fetch.php
│   ├── onedrive.php
│   ├── oneindex.php
│   ├── route.php
│   ├── sqlite.php
│   └── view.php
├── one.php
├── statics/
│   ├── common/
│   │   ├── offline/
│   │   │   ├── css/
│   │   │   │   └── main.css
│   │   │   └── js/
│   │   │       ├── aria2.js
│   │   │       ├── jquery.Storage.js
│   │   │       ├── jquery.jsonrpc.js
│   │   │       ├── mustache.js
│   │   │       ├── peerid.js
│   │   │       └── yaaw-1.1.js
│   │   └── search/
│   │       └── js/
│   │           └── search.js
│   └── themes/
│       └── nexmoe/
│           ├── css/
│           │   └── forkGh.css
│           └── js/
│               ├── nexmoe.js
│               └── personjs.js
├── view/
│   ├── admin/
│   │   ├── cache.php
│   │   ├── images.php
│   │   ├── install/
│   │   │   ├── install_0.php
│   │   │   ├── install_1.php
│   │   │   ├── install_2.php
│   │   │   ├── install_3.php
│   │   │   └── layout.php
│   │   ├── layout.php
│   │   ├── login.php
│   │   ├── offline.php
│   │   ├── setpass.php
│   │   ├── settings.php
│   │   ├── show.php
│   │   └── upload.php
│   ├── common/
│   │   ├── offline.php
│   │   ├── search.php
│   │   └── tips.php
│   └── themes/
│       ├── classic/
│       │   ├── 404.php
│       │   ├── layout.php
│       │   └── list.php
│       ├── material/
│       │   ├── 404.php
│       │   ├── images/
│       │   │   ├── index.php
│       │   │   └── layout.php
│       │   ├── layout.php
│       │   ├── list.php
│       │   ├── password.php
│       │   └── show/
│       │       ├── audio.php
│       │       ├── code.php
│       │       ├── doc.php
│       │       ├── image.php
│       │       ├── pdf.php
│       │       ├── stream.php
│       │       ├── video.php
│       │       ├── video2.php
│       │       └── video5.php
│       └── nexmoe/
│           ├── 404.php
│           ├── images/
│           │   ├── index.php
│           │   └── layout.php
│           ├── layout.php
│           ├── list.php
│           ├── password.php
│           ├── readme.html
│           └── show/
│               ├── audio.php
│               ├── code.php
│               ├── doc.php
│               ├── image.php
│               ├── pdf.php
│               ├── stream.php
│               ├── video.php
│               ├── video2.php
│               └── video5.php
└── 使用及免责协议.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
**/.DS_Store


================================================
FILE: README.md
================================================
## 简介

本项目是基于:

- Oneindex

- OneindexN项目地址:https://github.com/xieqifei/OneindexN

详细安装教程:
- [基于Onedrive和Server搭建下载站/网盘](https://www.mintimate.cn/2020/09/22/oneindex)

教程视频:
- [8分钟利用OneDrive搭建不限速的OneIndex分享网盘](https://www.bilibili.com/video/BV1ph41197aa)


打赏
- 爱发电:[Mintimate的电圈](https://www.afdian.net/@mintimate/plan)

![](https://cdn.jsdelivr.net/gh/Mintimate/OneindexM/demo/demo.png)

### 特别注意
OneindexM的默认密码为:**MintimateBlog**

## 修改功能:

### 后台:

- 选择安装世纪互联/国际版(如需修改版本,需要删除config文件夹里的文件后重新进入安装程序)
- 指定文件夹/全部文件夹,关闭Readme.md、index.html、head.md渲染(如果开启游客离线上传,可以关闭此路径的渲染,避免游客上传会被渲染的文件。)

### 前台

以下功能仅支持nexmoe主题
- 搜索功能:全局搜索/当前页过滤
- 文件操作:删除/新建/重命名/剪切/复制/分享等。仅管理员可用
- 文件上传:4M以下的文件在线上传。url远程上传,仅onedrive个人版支持。aria2离线上传,需自行安装在vps上安装aria2并完成相关配置。
- 外部视频播放器播放接口。需要安装对应播放器。
- 管理员登陆后,查看加密文件夹无需密码。

## 更新日志
- 2021.12.03:修复PHP7.x查询函数警告问题;修复文件过滤、查询出错问题;修复排序不可用问题;移除Jq、Bootstrap;调整部分UI
- 2021.08.03:修复Cookies循环问题、修复世纪互联版本部分情况不可用问题。
- 2021.07.01:修复因为Onedrive接口更换,而导致的无法部署。
- 2021.06.25:更换重写URL服务器。

## 部署网站

网站环境尽量使用Nginx或Apache,配合PHP5.7+版本。

建议参考文章:
![基于Onedrive和Server搭建下载站/网盘](https://www.mintimate.cn/2020/09/22/oneindex)

<hr/>

**以下是上游Readme.md内容**

## 功能

不占用服务器空间,不走服务器流量,  

直接列出 OneDrive 目录,文件直链下载。  

## 使用及免责协议

[使用及免责协议](./使用及免责协议.md)

## 安装运行

### 需求:

1、PHP空间,PHP 5.6+ 需打开curl支持  
2、OneDrive 账号 (个人、企业版或教育版/工作或学校帐户)  
3、OneIndex 程序   

### 计划任务  

[可选]**推荐配置**,非必需。后台定时刷新缓存,可增加前台访问的速度。  

```
# 每小时刷新一次token
0 * * * * /具体路径/php /程序具体路径/one.php token:refresh

# 每十分钟后台刷新一遍缓存
*/10 * * * * /具体路径/php /程序具体路径/one.php cache:refresh
```

### Docker 安装运行

- 请参考[TimeBye/oneindex](https://github.com/TimeBye/oneindex)

## 特殊文件实现功能  

` README.md `、`HEAD.md` 、 `.password`特殊文件使用  

可以参考[https://github.com/donwa/oneindex/tree/files](https://github.com/donwa/oneindex/tree/files)  

**在文件夹底部添加说明:**  

>在 OneDrive 的文件夹中添加` README.md `文件,使用 Markdown 语法。  

**在文件夹头部添加说明:**  

>在 OneDrive 的文件夹中添加`HEAD.md` 文件,使用 Markdown 语法。  

**加密文件夹:**  

>在 OneDrive 的文件夹中添加`.password`文件,填入密码,密码不能为空。  

**直接输出网页:**  

>在 OneDrive 的文件夹中添加`index.html` 文件,程序会直接输出网页而不列目录。  
>配合 文件展示设置-直接输出 效果更佳。  

## 命令行功能  

仅能在PHP CLI模式下运行  

**清除缓存:**  

```
php one.php cache:clear
```

**刷新缓存:**  

```
php one.php cache:refresh
```

**刷新令牌:**  

```
php one.php token:refresh
```

**上传文件:**  

```
php one.php upload:file 本地文件 [OneDrive文件]
```

**上传文件夹:**  

```
php one.php upload:folder 本地文件夹 [OneDrive文件夹]
```

例如:  

```
//上传demo.zip 到OneDrive 根目录  
php one.php upload:file demo.zip  

//上传demo.zip 到OneDrive /test/目录  
php one.php upload:file demo.zip /test/  

//上传demo.zip 到OneDrive /test/目录并将其命名为 d.zip  
php one.php upload:file demo.zip /test/d.zip  

//上传up/ 到OneDrive /test/ 目录  
php one.php upload:file up/ /test/
```

## 使用Aria2

Nginx添加反向代理

```
location /jsonrpc {
        proxy_pass http://localhost:6800/jsonrpc;
        proxy_redirect off;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For
        $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
	}
```

nginx会监听发送给`http://yoursite/jsonrpc`的消息,然后将他转发给`http:localhost:6800/jsonrpc`,相当于你在yaaw中设置rpc时,只需要将其设置为`http://yoursite/jsonrpc`或者`https://yoursite/jsonrpc`,省略的端口信息为http对应80,https对应443,这些端口浏览器会自动转发,不用在设置中指定。如果你设置了反向代理,那么使用前台yaaw时,就不用在做rpc设置了。否则你需要去重新设置。

![](https://i.loli.net/2020/06/25/9cY2PiBr6usqXen.png)

**关闭aria2远程RPC**

仅vps本地也就是nginx转发的请求能到达6800。其他主机不能访问6800端口。

```shell
vim /root/.aria2c/aria2.conf
```

修改aria2配置内容

```
# 启用RPC, 默认:false
enable-rpc=true
# 接受所有远程请求, 默认:false
rpc-allow-origin-all=false
# 允许外部访问, 默认:false
rpc-listen-all=false
# RPC监听端口, 端口被占用时可以修改, 默认:6800
rpc-listen-port=6800
```

> 请注意,关闭远程请求并不能阻止其他主机向aria2发送请求,在不设置token时,任何人都可以通过直接向`http://yoursite/jsonrpc`这个地址发送请求连接aria2。如果你开启游客离线下载可以这么设置。如果你不希望有人通过其他aria2前端连接你的aria2,请你务必设置token,但是这样做,你也必须在使用的时候修改rpc设置,好在,第一次修改设置后,之后浏览器都会记住这个设置。

> 博客:https://sci.ci
>
> 如果应用有bug,或者你有好的修改建议,可以通过邮箱联系我:im@xieqifei.com

## 参考资料

《[github YAAW项目](https://github.com/binux/yaaw)》

《[Issue:一旦使用HTTPS协议就无法连接](https://github.com/mayswind/AriaNg/issues/62)》

《[Nginx 反向代理 Aria2 JSONRPC](https://kenvix.com/post/nginx-proxy-aria2/)》


================================================
FILE: cache/abc
================================================



================================================
FILE: config/README.md
================================================
# oneindex
OneDrive Directory Index


================================================
FILE: controller/AdminController.php
================================================
<?php
define('VIEW_PATH', ROOT.'view/admin/');
class AdminController{
    static $default_config = array(
      'site_name' =>'OneIndex',
      'site_name_small' =>'',
      'password' => 'MintimateBlog',
      'style'=>'nexmoe',
      'onedrive_root' =>'',
      'except_path' =>'',
      'cache_type'=>'secache',
      'cache_expire_time' => 10,
      'cache_refresh_time' => 600,
      'root_path' => '?',
      'show'=> array (
          'stream'=>['txt'],
        'image' => ['bmp','jpg','jpeg','png','gif'],
        'video5'=>['mp4','webm','mkv'],
        'video'=>[],
        'video2'=>['avi','mpg', 'mpeg', 'rm', 'rmvb', 'mov', 'wmv', 'asf', 'ts', 'flv'],
        'audio'=>['ogg','mp3','wav'],
        'code'=>['html','htm','php', 'css', 'go','java','js','json','txt','sh','md'],
        'doc'=>['csv','doc','docx','odp','ods','odt','pot','potm','potx','pps','ppsx','ppsxm','ppt','pptm','pptx','rtf','xls','xlsx']
      ),
      'images'=>['home'=>false,'public'=>false, 'exts'=>['jpg','png','gif','bmp']],
      'offline'=>array(
          'offline'=>false,
          'online'=>false,
          'upload_path'=>'/upload/'
        )
    );
    
    function __construct(){
    }

    function login(){
        if(!empty($_POST['password']) && $_POST['password'] == config('password')){
            setcookie('admin', md5(config('password').config('refresh_token')) );
            return view::direct(get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).'?/admin/');
        }
        return view::load('login')->with('title', '系统管理');
    }

    function logout(){
        setcookie('admin', '' );
        return view::direct(get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).'?/login');
    }

    function settings(){
        $message = false;

        if($_POST){
            
            if ($this->cache_exists($_POST['cache_type'])) {
                $message = '保存成功';
                config('cache_type', $_POST['cache_type']);
            } else {
                $message = '缓存类型不可用,请确认已经安装了该拓展。';
                config('cache_type', 'secache');
            }
            //判断不渲染目录是否为全部不渲染
            if($_POST['except_path']){
                $except_path=(strcmp($_POST['except_path'],'all')==0?'all':get_absolute_path($_POST['except_path']));
            }else{
                $except_path='';
            }
            config('site_name', $_POST['site_name']);
            config('style', $_POST['style']);
            config('onedrive_root', get_absolute_path($_POST['onedrive_root']));
            config('except_path',$except_path);
            config('onedrive_hide', $_POST['onedrive_hide']);
            config('onedrive_hotlink', $_POST['onedrive_hotlink']);
            config('cache_expire_time', intval($_POST['cache_expire_time']));
            $_POST['root_path'] = empty($_POST['root_path'])?'?':'';
            config('root_path', $_POST['root_path']);
        }

        $config = config('@base');

        return view::load('settings')->with('config', $config)->with('message', $message);
    }
    
    function offline(){
        if($_POST){
            $config['offline'] = empty($_POST['offline'])?false:true;
            $config['online'] = empty($_POST['online'])?false:true;
            $config['upload_path'] = empty($_POST['upload_path']) ? '/' : get_absolute_path($_POST['upload_path']);
            config('offline@base',$config);
        }
        $config = config('offline@base');
        return view::load('offline')->with('config',$config);
    }
    
    /**
     * 判断缓存类型
     *
     * @param string $cache_type 缓存类型
     * @return void
     */
    function cache_exists($cache_type){
        // 需要判断环境的缓存类型
        $_cache_type = [
            'redis',
            'memcache',
        ];

        if (in_array($cache_type, $_cache_type)) {
            return class_exists(ucfirst($cache_type));
        }

        return true;
    }

    function cache(){
        if(!is_null($_POST['clear'])){
            cache::clear();
            $message = "清除缓存成功";
        }elseif ( !is_null($_POST['refresh']) ){
            oneindex::refresh_cache(get_absolute_path(config('onedrive_root')));
            $message = "重建缓存成功";
        }
        return view::load('cache')->with('message', $message);
    }

    function images(){
        if($_POST){
            $config['home'] = empty($_POST['home'])?false:true;
            $config['public'] = empty($_POST['public'])?false:true;
            $config['exts'] = explode(" ", $_POST['exts']);
            config('images@base',$config);
        }
        $config = config('images@base');
        return view::load('images')->with('config', $config);;
    }


    function show(){
        if(!empty($_POST) ){
            foreach($_POST as $n=>$ext){
                $show[$n] = explode(' ', $ext);
            }
            config('show', $show);
        }
        $names = [
            'stream'=>'直接输出(<5M),走本服务器流量(stream)',
            'image' =>'图片(image)',
            'video'=>'Dplayer 视频(video)',
            'video2'=>'Dplayer DASH 视频(video2)/个人版账户不支持',
            'video5'=>'html5视频(video5)',
            'audio'=>'音频播放(audio)',
            'code'=>'文本/代码(code)',
            'doc'=>'文档(doc)'
        ];
        $show = config('show');
        return view::load('show')->with('names', $names)->with('show', $show);
    }

    function setpass(){
        if($_SERVER['REQUEST_METHOD'] == 'POST'){
            if($_POST['old_pass'] == config('password')){
                if($_POST['password'] == $_POST['password2']){
                    config('password', $_POST['password']);
                    $message = "修改成功";
                }else{
                    $message = "两次密码不一致,修改失败";
                }
            }else{
                $message = "原密码错误,修改失败";
            }
        }
        return view::load('setpass')->with('message', $message);
    }
    
    function install(){
        if(!empty($_GET['code'])){
            return $this->install_3();
        }
        switch ( intval($_GET['step']) ){
            case 1:
                return $this->install_1();
            case 2:
                return $this->install_2();
            default:
                return $this->install_0();
        }
    }

    function install_0(){
        $check['php'] = version_compare(PHP_VERSION,'5.5.0','ge');
        $check['curl'] = function_exists('curl_init');
        $check['config'] = is_writable(ROOT.'config/');
        $check['cache'] = is_writable(ROOT.'cache/');

        return view::load('install/install_0')->with('title','系统安装')
                        ->with('check', $check);
    }

    function install_1(){
        if(!empty($_POST['client_secret']) && !empty($_POST['client_id']) && !empty($_POST['redirect_uri']) && !empty($_POST['area'])){
            config('@base', self::$default_config);
            config('client_secret',$_POST['client_secret']);
            config('client_id',$_POST['client_id']);
            config('redirect_uri',$_POST['redirect_uri']);
            config('area',$_POST['area']);
            return view::direct('?step=2');
        }
        if($_SERVER['HTTP_HOST'] == 'localhost'){
            $redirect_uri = 'http://'.$_SERVER['HTTP_HOST'].get_absolute_path(dirname($_SERVER['PHP_SELF']));
        }else{
            // 非https,调用ju.tn中转
            $redirect_uri = 'https://tool.mintimate.cn/oneindexM/';
        }
        
        $ru = "https://developer.microsoft.com/en-us/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl={$redirect_uri}&platform=option-php";
        $deepLink = "/quickstart/graphIO?publicClientSupport=false&appName=oneindex&redirectUrl={$redirect_uri}&allowImplicitFlow=false&ru=".urlencode($ru);
        $app_url = "https://apps.dev.microsoft.com/?deepLink=".urlencode($deepLink);
        return view::load('install/install_1')->with('title','系统安装')
                        ->with('redirect_uri', $redirect_uri)
                        ->with('app_url', $app_url);
    }

    function install_2(){
        return view::load('install/install_2')->with('title','系统安装');
    }

    function install_3(){
        $data = onedrive::authorize($_GET['code']);
        if(!empty($data['refresh_token'])){
            config('refresh_token',$data['refresh_token']);
            config('@token', $data);
        }
        return view::load('install/install_3')->with('refresh_token',$data['refresh_token']);
        
    }
}


================================================
FILE: controller/CommonController.php
================================================
<?php 
define('VIEW_PATH', ROOT.'view/');
class CommonController{
	
	function __construct(){
	}
	//aria2
	function offline(){
		if(config('offline')['offline']||is_login()){
			return view::load('common/offline');
		}
		else{
			return view::load('common/tips')->with('tip','管理员未授权使用');
		}
	}

	//搜索
	function search(){
		if(is_login()){
			if($_POST['keyword']){
				$keyword=$_POST['keyword'];
				$items = onedrive::search($keyword);
				if(!$items){
					return view::load('common/tips')->with('tip','没有找到与“'.$_POST['keyword'].'”有关的内容');
				}
				$searchinfo['keyword']=$keyword;
				$searchinfo['count']=count($items);
				return view::load('common/search')->with('items',$items)->with('searchinfo',$searchinfo);
			}else{
				return '参数错误';
			}
		}
		else{
			return '请登陆后尝试';
		}
	}
	//新建文件夹
	//post参数:uploadurl,当前url的路径
	function create_folder(){
		if(is_login()){
			$urlinfo=parse_url($_POST['uploadurl']);
			if(stristr($_POST['uploadurl'],'?')){
				$paths = explode('/', rawurldecode($urlinfo['query']));
			}else{
				$paths = explode('/', rawurldecode($urlinfo['path']));
			}
			$paths=array_values($paths);
			$remotepath = get_absolute_path(join('/', $paths));
			$data = onedrive::create_folder(str_replace('//','/',config('onedrive_root').$remotepath),$_POST['foldername']);
			oneindex::refresh_cache(get_absolute_path(config('onedrive_root')));
			return $data;
		}
		else{
			return '未登录无法新建文件夹';
		}
	}
	//重命名
	//post参数:name:新名称;itemid:itemid
	function rename(){
		if(is_login()){
			$newname=$_POST['name'];
			$itemid=$_POST['itemid'];
			$resp=onedrive::rename($itemid,$newname);
			oneindex::refresh_cache(get_absolute_path(config('onedrive_root')));
			return $resp;
		}
		else{
			return '未登录无法重命名';
		}
	}
	//删除
	//传入一个stringfy后的itemid的数组
	function deleteitems(){
		if(is_login()){
			$data = file_get_contents( "php://input" );
			$items = json_decode( $data );
			$resp=onedrive::delete($items);
			oneindex::refresh_cache(get_absolute_path(config('onedrive_root')));
			return $resp;
		}
		else{
			return '未登录无法删除';
		}
	}
	//url上传
	function upload_url(){
		if(is_login()){
			if($_POST['file_url']&&$_POST['path_url']){
				$file_url=$_POST['file_url'];
				$path_url=$_POST['path_url'];
				if($_POST['file_name']){
					$file_name = $_POST['file_name'];
				}
				else{
					$file_name = pathinfo(parse_url($file_url,PHP_URL_PATH),PATHINFO_BASENAME);
				}
				$path = str_replace('//','/',$this->url2path($path_url).'/'.$file_name);
				$process_url = onedrive::upload_url($path , $file_url);
				if($process_url){
					return $process_url;
				}
				else{
					return 0;
				}
			}else{
				return '参数错误';
			}
		}else{
			return '未登录';
		}
	}

	//在线上传,大小限制在4M
	//post参数:onlinefile:一个文件;uploadurl:当前url路径
	function onlinefileupload()
	{
		
		if($this->uploadcondition($_FILES["onlinefile"]) ){
			$filename = $_FILES["onlinefile"]['name'];
			$content = file_get_contents( $_FILES["onlinefile"]['tmp_name']);
			//管理员不受上传目录限制
			if(is_login()){
				//获取路径
				$paths = explode('/', rawurldecode($_POST['uploadurl']));
				if(strcmp($paths[1],'?')==0){
					array_shift($paths);
					array_shift($paths);
				}
				//$paths=array_shift($paths);
				$remotepath = get_absolute_path(join('/', $paths));
			}
			//游客只能上传到指定目录
			else{
				$remotepath =  config('offline')['upload_path'];
			}
			$remotefile = $remotepath.$filename;
			$result = onedrive::upload(str_replace('//','/',config('onedrive_root').$remotefile), $content);
			
			if($result){
				$root = get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).config('root_path');
				$http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
				$url = $_SERVER['HTTP_HOST'].$root.'/'.$remotepath.rawurldecode($filename).((config('root_path') == '?')?'&s':'?s');
				$url = $http_type.str_replace('//','/', $url);
				$result['path']=$url;
				// view::direct($url);
				return json_encode($result);
			}
		}else{
			return '未登录或文件过大';
		}
		
	}
	//上传文件的条件判断
	function uploadcondition($file){
		
		if($file['size'] > 4485760 || $file['size'] == 0){
			return false;
		}
		if(config('offline')['online']==false&&!is_login()){
			return false;
		}

		return true;
	}
	//粘贴
	function paste(){
		if(is_login()){
			$data = file_get_contents( "php://input" );
			$jsondata = json_decode($data);//字符串转对象。
			if($jsondata->cutitems){
				$cutitems=$jsondata->cutitems;
				$url=$jsondata->url;
				return $this->cut($cutitems,$url);
			}
			if($jsondata->copyitems){
				$copyitems=$jsondata->copyitems;
				$url=$jsondata->url;
				return $this->copy($copyitems,$url);
			}
			return '操作失误,请重新尝试!';
		}
		else{
			return '未登录无法重命名';
		}
	}
	//移动或剪切
	function cut($cutitems,$url){
		$itemid=$this->url2id($url);
		$resp=onedrive::move($cutitems,$itemid);
		oneindex::refresh_cache(get_absolute_path(config('onedrive_root')));
		return json_encode(json_decode(json_encode($resp)));//decode去掉字符串中的转义字符再
	}
	//复制
	function copy($copyitems,$url){
		$itemid=$this->url2id($url);
		$resp=onedrive::copy($copyitems,$itemid);
		oneindex::refresh_cache(get_absolute_path(config('onedrive_root')));
		return $resp;
	}
	//url转路径
	function url2path($url){
		$paths=array();
		$urlinfo=parse_url($url);
		if(stristr($url,'?')){
			$paths = explode('/', rawurldecode($urlinfo['query']));
		}else{
			$paths = explode('/', rawurldecode($urlinfo['path']));
		}
		if(strcmp($paths[1],'?')==0){
			array_shift($paths);
			array_shift($paths);
		}
		$remotepath = get_absolute_path(join('/', $paths));
		$path = str_replace('//','/',config('onedrive_root').$remotepath);
		return $path;
	}

	//url转id
	function url2id($url){
		$urlinfo=parse_url($url);
		if(stristr($url,'?')){
			$paths = explode('/', rawurldecode($urlinfo['query']));
		}else{
			$paths = explode('/', rawurldecode($urlinfo['path']));
		}
		$paths=array_values($paths);
		$totalpath = str_replace('//','/',config('onedrive_root').get_absolute_path(join('/', $paths)));
		$itemid=onedrive::path2id($totalpath);
		return $itemid;
	}
	
}


================================================
FILE: controller/ImagesController.php
================================================
<?php 

class ImagesController{
	function generateRandomString($length) {
            $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            $randomString = '';
            for ($i = 0; $i < $length; $i++) {
                $randomString .= $characters[rand(0, strlen($characters) - 1)];
            }
            return $randomString;
        }
	
	function index(){
		if($this->is_image($_FILES["file"]) ){
		    $filename = $_FILES["file"]['name'];
			$content = file_get_contents( $_FILES["file"]['tmp_name']);
			$remotepath =  'images/'.date('Y/m/d/').$this->generateRandomString(10).'/';
			$remotefile = $remotepath.$filename;
			$result = onedrive::upload(config('onedrive_root').$remotefile, $content);
			
			if($result){
				$root = get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).config('root_path');
				$http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
				$url = $_SERVER['HTTP_HOST'].$root.'/'.$remotepath.rawurldecode($filename).((config('root_path') == '?')?'&s':'?s');
				$url = $http_type.str_replace('//','/', $url);
				view::direct($url);
			}
		}
		return view::load('images/index');
	}

	function is_image($file){
		$config = config('images@base');
		$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
		if(!in_array($ext,$config['exts'])){
			return false;
		}
		if($file['size'] > 10485760 || $file['size'] == 0){
			return false;
		}

		return true;
	}
}


================================================
FILE: controller/IndexController.php
================================================
<?php 
class IndexController{
	private $url_path;
	private $name;
	private $path;
	private $items;
	private $time;

	function __construct(){
		//获取路径和文件名
		$paths = explode('/', rawurldecode($_GET['path']));
		if(substr($_SERVER['REQUEST_URI'], -1) != '/'){
			$this->name = array_pop($paths);
		}
		$this->url_path = get_absolute_path(join('/', $paths));
		$this->path = get_absolute_path(config('onedrive_root').$this->url_path);
		//获取文件夹下所有元素
		$this->items = $this->items($this->path);
	}

	
	function index(){
		//是否404
		$this->is404();

		$this->is_password();

		header("Expires:-1");
		header("Cache-Control:no_cache");
		header("Pragma:no-cache");

		if(!empty($this->name)){//file
			return $this->file();
		}else{//dir
			return $this->dir();
		}
	}

	//判断是否加密
	function is_password(){
		if(empty($this->items['.password'])){
			return false;
		}else{
			$this->items['.password']['path'] = get_absolute_path($this->path).'.password';
 		}
		
		$password = $this->get_content($this->items['.password']);
		list($password) = explode("\n",$password);
		$password = trim($password);
		unset($this->items['.password']);
		if(!empty($password) && strcmp($password, $_COOKIE[md5($this->path)]) === 0||$_COOKIE['admin'] == md5(config('password').config('refresh_token'))){
			return true;
		}

		$this->password($password);
		
	}

	function password($password){
		if(!empty($_POST['password']) && strcmp($password, $_POST['password']) === 0){
			setcookie(md5($this->path), $_POST['password']);
			return true;
		}
		$navs = $this->navs();
		echo view::load('password')->with('navs',$navs);
		exit();
	}

	//文件
	function file(){
		$item = $this->items[$this->name];
		if ($item['folder']) {//是文件夹
			$url = $_SERVER['REQUEST_URI'].'/';
		}elseif(!is_null($_GET['t']) ){//缩略图
			$url = $this->thumbnail($item);
		}elseif($_SERVER['REQUEST_METHOD'] == 'POST' || !is_null($_GET['s']) ){
			return $this->show($item);
		}else{//返回下载链接
			$url = $item['downloadUrl'];
		}
		header('Location: '.$url);
	}


	
	//文件夹
	function dir(){
		$root = get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).config('root_path');
		$navs = $this->navs();
		//以'/'拆分路径,并重新连接
		$except_paths_buffer = explode('/', config('except_path'));
		$except_path_buffer = get_absolute_path(join('/', $except_paths_buffer));
		$upload_paths_buffer = explode('/', config('offline')['upload_path']);
		$upload_path_buffer = get_absolute_path(join('/', $upload_paths_buffer));
		$online = config('offline')['online'];
		//定义变脸,表示是否渲染此目录下的文件
		$iscolorbar = true;
		//不渲染设置为all,或者当前路径与指定不渲染路径相同,则不渲染。如果设置为空,则渲染
		if(strcmp(config('except_path'),'all')==0||strcmp(get_absolute_path($this->path), get_absolute_path(config('onedrive_root').$except_path_buffer))==0){
			$iscolorbar = false;
		}else if(empty(config('except_path'))){
			$iscolorbar = true;
		}
		//指定的游客在线上传路径是否和当前路径一致,相同则不渲染。
		if(strcmp(get_absolute_path($this->path),get_absolute_path(config('onedrive_root').$upload_path_buffer))==0){
			$iscolorbar = false;
		}
		
		if($iscolorbar)
		{
			if($this->items['index.html']){
				$this->items['index.html']['path'] = get_absolute_path($this->path).'index.html';
				$index = $this->get_content($this->items['index.html']);
				header('Content-type: text/html');
				echo $index;
				exit();
			}
	
			if($this->items['README.md']){
				$this->items['README.md']['path'] = get_absolute_path($this->path).'README.md';
				$readme = $this->get_content($this->items['README.md']);
				$Parsedown = new Parsedown();
				$readme = $Parsedown->text($readme);
				//不在列表中展示
				unset($this->items['README.md']);
			}
	
			if($this->items['HEAD.md']){
				$this->items['HEAD.md']['path'] = get_absolute_path($this->path).'HEAD.md';
				$head = $this->get_content($this->items['HEAD.md']);
				$Parsedown = new Parsedown();
				$head = $Parsedown->text($head);
				//不在列表中展示
				unset($this->items['HEAD.md']);
			}
		}
		
		//在线上传条件,后台开启或者登陆为管理员
		if(config('offline')['online']||is_login()){
			$manager['online']=true;
		}
		else{
			$manager['online']=false;
		}

		if(config('offline')['offline']||is_login()){
			$manager['offline']=true;
		}else{
			$manager['offline']=false;
		}

		if(is_login()){
			$manager['create_folder']=true;
		}else{
			$manager['create_folder']=false;
		}
		return view::load('list')->with('title', empty(str_replace("/","",urldecode($this->url_path)))?"根目录":str_replace("/","",urldecode($this->url_path)))
					->with('navs', $navs)
					->with('path',join("/", array_map("rawurlencode", explode("/", $this->url_path)))  )
					->with('root', $root)
					->with('items', $this->items)
					->with('head',$head)
					->with('readme',$readme)
					->with('manager',$manager);
	}

	function show($item){
		$root = get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).(config('root_path')?'?/':'');
		$ext = strtolower(pathinfo($item['name'], PATHINFO_EXTENSION));
		$data['title'] = $item['name'];
		$data['navs'] = $this->navs();
		$data['item'] = $item;
		$data['ext'] = $ext;
		$data['item']['path'] = get_absolute_path($this->path).$this->name;
		$http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
		$uri = onedrive::urlencode(get_absolute_path($this->url_path.'/'.$this->name));
		$data['url'] = $http_type.$_SERVER['HTTP_HOST'].$root.$uri;
		

		$show = config('show');
		foreach($show as $n=>$exts){
			if(in_array($ext,$exts)){
				return view::load('show/'.$n)->with($data);
			}
		}

		header('Location: '.$item['downloadUrl']);
	}
	//缩略图
	function thumbnail($item){
		if(!empty($_GET['t'])){
			list($width, $height) = explode('|', $_GET['t']);
		}else{
			//800 176 96
			$width = $height = 800;
		}
		$item['thumb'] = onedrive::thumbnail($this->path.$this->name);
		list($item['thumb'],$tmp) = explode('&width=', $item['thumb']);
		$item['thumb'] .= strpos($item['thumb'], '?')?'&':'?';
		return $item['thumb']."width={$width}&height={$height}";
	}

	//文件夹下元素
	function items($path, $fetch=false){
		$items = cache::get('dir_'.$this->path, function(){
			return onedrive::dir($this->path);
		}, config('cache_expire_time'));
		return $items;
	}

	function navs(){
		$root = get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).config('root_path');
		$navs['/'] = get_absolute_path($root.'/');
		foreach(explode('/',$this->url_path) as $v){
			if(empty($v)){
				continue;
			}
			$navs[rawurldecode($v)] = end($navs).$v.'/';
		}
		if(!empty($this->name)){
			$navs[$this->name] = end($navs).urlencode($this->name);
		}
		
		return $navs;
	}

	static function get_content($item){
		$content = cache::get('content_'.$item['path'], function() use ($item){
			$resp = fetch::get($item['downloadUrl']);
			if($resp->http_code == 200){
				return $resp->content;
			}
		}, config('cache_expire_time') );
		return $content;
	}



	//时候404
	function is404(){
		if(!empty($this->items[$this->name]) || (empty($this->name) && is_array($this->items)) ){
			return false;
		}

		http_response_code(404);
		view::load('404')->show();
		die();
	}

	function __destruct(){
		if (!function_exists("fastcgi_finish_request")) {
			return;
		}
	}
}


================================================
FILE: controller/UploadController.php
================================================
<?php 
define('VIEW_PATH', ROOT.'view/admin/');
class UploadController{

	//从网站服务器目录上传文件
	function index(){
		if($_POST['upload'] == 1){
			$local = realpath($_POST['local']);
			$remotepath = get_absolute_path($_POST['remote']);
			if(is_file($local)){
				$this->add_task($local, $remotepath);
				$message = "文件<kbd>".$local."</kbd>已添加到队列";
			}elseif(is_dir($local)){
				$this->scan_dir($local, $remotepath);
				$message = "文件夹<kbd>".$local."</kbd>已添加到队列";
			}elseif($local == realpath('.')){
				$message = "因为安全原因,程序文件夹根目录不能上传";
			}else{
				$message = "文件不存在";
			}
			$request = $this->task_request();
			$request['url'] = substr($request['url'],0,-4).'run';
			fetch::post($request);
		}elseif(!empty($_POST['begin_task'])){
			$this->task($_POST['begin_task']);
		}elseif(!empty($_POST['delete_task'])){
			unset($_POST['delete_task']);
			config('@upload', (array)$uploads);
		}elseif(!empty($_POST['empty_uploaded'])){
			config('@uploaded', array());
		}
		$uploading = config('@upload');
		$uploaded = array_reverse((array)config('@uploaded'));
		return view::load('upload')->with('uploading', $uploading)->with('uploaded', $uploaded)->with('message', $message);
	}

	//扫描文件夹,添加到任务队列
	private function scan_dir($localpath, $remotepath){
		$files = scandir($localpath);
		foreach ($files as $file) {
			if ($file == '.' || $file == '..') {
				continue;
			}
			if (is_dir($localpath . '/' . $file)) {
		        $this->scan_dir($localpath . '/' . $file, $remotepath.$file.'/');
		    }else{
			    $localfile = realpath($localpath . '/' . $file);
			    $remotefile = $remotepath.$file;
			    $this->add_task($localfile, $remotefile);
		    }
		}
	}

	private function add_task($localfile, $remotefile){
	    $task = array(
			'localfile'=>$localfile,
			'remotepath' => $remotefile,
			'filesize'=>onedrive::_filesize($localfile),
			'upload_type'=>'web',
			'update_time'=>0,
	    );

	    $uploads = (array)config('@upload');
	    if(empty($uploads[$remotefile])){
		    $uploads[$remotefile] = $task;
		    config('@upload', $uploads);
	    }
	}

	//运行队列中的任务
	function run(){
		$uploads = (array)config('@upload');
		$time = time();
		$runing = 0;
		foreach($uploads as $task){
			if($time < ($task['update_time']+60) AND $task['type']=='web' ){
				$runing = $runing +1;
			}
			if($runing > 5)break;
		}
		
		foreach($uploads as $remotepath=>$task){
			if($time < ($task['update_time']+60) OR !is_array($task) ){
				continue;
			}
			$runing = $runing +1;
			print $remotepath.PHP_EOL;
			fetch::post($this->task_request($remotepath));
			if($runing > 5)break;
		}

		if(count($uploads) > 5){
			set_time_limit(100);
			sleep(60);
			$request = $this->task_request();
			$request['url'] = substr($request['url'],0,-4).'run';
			fetch::get($request);
		}
	}

	private function task_request($remotepath=''){
		$request['headers'] = "Cookie: admin=".md5(config('password').config('refresh_token')).PHP_EOL;
		$request['headers'] .= "Host: ".$_SERVER['HTTP_HOST'];
		$request['curl_opt']=[CURLOPT_CONNECTTIMEOUT => 1,CURLOPT_TIMEOUT=>1,CURLOPT_FOLLOWLOCATION=>true];
		$http_type = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
		$request['url'] = $http_type.'127.0.0.1'.get_absolute_path(dirname($_SERVER['PHP_SELF'])).'?/admin/upload/task';
		$request['post_data'] = 'remotepath='.urlencode($remotepath);
		return $request;
	}
	
	//执行任务
	function task($remotepath=null){
		$remotepath = is_null($remotepath)?$_POST['remotepath']:$remotepath;
		//file_put_contents('log.txt',$remotepath.PHP_EOL, FILE_APPEND);
		$uploads = config('@upload');
		$task = $uploads[$remotepath];

		if(empty($task)){
			return;
		}
		if($task['filesize'] < 10485760){
			@onedrive::upload($task['remotepath'], file_get_contents($task['localfile']));
			unset($uploads[$remotepath]);
				
			config('@upload', (array)$uploads);
			config($remotepath.'@uploaded','success');
		}else{
			$uploads[$remotepath]['update_time'] = time();
			config('@upload', (array)$uploads);
			$this->upload_large_file($task);
		}
	}

	function upload_large_file($task){		
		//创建上传会话
		if(empty($task['url'])){
			$data = onedrive::create_upload_session($task['remotepath']);
			if(!empty($data['uploadUrl'])){
				$task['url'] = $data['uploadUrl'];
				$task['offset'] = 0;
				$task['length'] = 327680;
				$task['update_time'] = time();
				config($task['remotepath'].'@upload',$task);
			}elseif ( $data === false ){
				$uploads = config('@upload');
				unset($uploads[$task['remotepath']]);
				config('@upload', $uploads);
				config($task['remotepath'].'@uploaded','exists');
			}
		}else{
			$begin_time = microtime(true);
			set_time_limit(0);
			$data = onedrive::upload_session($task['url'], $task['localfile'], $task['offset'], $task['length']);
			if(!empty($data['nextExpectedRanges'])){ 
			//继续上传
				$upload_time = microtime(true) - $begin_time;
				$task['speed'] = $task['length']/$upload_time;
				$task['length'] = intval($task['length']/$upload_time/32768*2)*327680;
				$task['length'] = ($task['length']>104857600)?104857600:$task['length'];
				list($offset, $filesize) = explode('-',$data['nextExpectedRanges'][0]);
				$task['offset'] = intval($offset);
				$info['update_time'] = time();
				config($task['remotepath'].'@upload',$task);
			}elseif(!empty($data['@content.downloadUrl']) || !empty($data['id'])){ 
			//上传完成
				unset($uploads[$task['remotepath']]);
				config('@upload', $uploads);
				config($task['remotepath'].'@uploaded','success');
				return;
			}else{
			//失败,重新获取信息
				echo "re get url";
				$data = onedrive::upload_session_status($task['url']);
				if(empty($data)|| $info['length']<100){
					onedrive::delete_upload_session($task['url']);
					unset($task['url']);
					config($task['remotepath'].'@upload', $task);
				}elseif(!empty($data['nextExpectedRanges'])){
					list($offset, $filesize) = explode('-',$data['nextExpectedRanges'][0]);
					$task['offset'] = intval($offset);
					$task['length'] = $task['length']/1.5;
					config($task['remotepath'].'@upload', $task);
				}
			}
		}
		$request= $this->task_request($task['remotepath']);
		$resp = fetch::post($request);
		//var_dump($resp);
	}
	
}


================================================
FILE: index.php
================================================
<?php

require  __DIR__.'/init.php';
/**
 *    程序安装
 */
//选择OD国际版?世纪互联版。
if (config('area')!=="cn"){
	onedrive::$api_url = 'https://graph.microsoft.com/v1.0';
	onedrive::$oauth_url = 'https://login.microsoftonline.com/common/oauth2/v2.0';
}else{
	onedrive::$api_url = "https://microsoftgraph.chinacloudapi.cn/v1.0";
    onedrive::$oauth_url = "https://login.partner.microsoftonline.cn/common/oauth2/v2.0";
}

if( empty( config('refresh_token') ) ){
	route::any('/','AdminController@install');
}

/**
 *    系统后台
 */
route::group(function(){
	return ($_COOKIE['admin'] == md5(config('password').config('refresh_token')) );
},function(){
	route::get('/logout','AdminController@logout');
	route::any('/admin/','AdminController@settings');
	route::any('/admin/cache','AdminController@cache');
	route::any('/admin/show','AdminController@show');
	route::any('/admin/setpass','AdminController@setpass');
	route::any('/admin/images','AdminController@images');
    route::any('/admin/offline','AdminController@offline');
	route::any('/admin/upload','UploadController@index');
	//守护进程
	route::any('/admin/upload/run','UploadController@run');
	//上传进程
	route::post('/admin/upload/task','UploadController@task');
});
//登陆
route::any('/login','AdminController@login');

//onedrive操作
route::any('/offline','CommonController@offline');
route::any('/onlinefileupload','CommonController@onlinefileupload');
route::any('/create_folder','CommonController@create_folder');
route::any('/rename','CommonController@rename');
route::any('/deleteitems','CommonController@deleteitems');
route::any('/search','CommonController@search');
route::any('/paste','CommonController@paste');
route::any('/upload_url','CommonController@upload_url');
//跳转到登陆
route::any('/admin/',function(){
	return view::direct(get_absolute_path(dirname($_SERVER['SCRIPT_NAME'])).'?/login');
});

define('VIEW_PATH', ROOT.'view/themes/'.(config('style')?config('style'):'material').'/');
/**
 *    OneImg
 */
$images = config('images@base');
if( ($_COOKIE['admin'] == md5(config('password').config('refresh_token')) || $images['public']) ){
	route::any('/images','ImagesController@index');
	if($images['home']){
		route::any('/','ImagesController@index');
	}
}


/**
 *    列目录
 */
route::group(function () {
	$hotlink = config('onedrive_hotlink');

	// 未启用防盗链
	if (!$hotlink) {
		return true;
	}
	// referer 不存在
	if (!isset($_SERVER['HTTP_REFERER'])) {
		return true;
	}

	$referer_domain = get_domain($_SERVER['HTTP_REFERER']);
	// 当前域本身
	if (str_is(get_domain(), $referer_domain)) {
		return true;
	}

	// 白名单
	$hotlinks = explode(';', $hotlink);
	$referer = false;
	
	foreach ($hotlinks as $_hotlink) {
		if (str_is(trim($_hotlink), $referer_domain)) {
			$referer = true;
		}
	}
	if (!$referer) {
		header('HTTP/1.1 403 Forbidden');
	}

	return $referer;
}, function() {
    route::any('{path:#all}','IndexController@index');
});


================================================
FILE: init.php
================================================
<?php
error_reporting(E_ALL & ~E_NOTICE);
date_default_timezone_set('PRC');
define('TIME', time());
!defined('ROOT') && define('ROOT', str_replace("\\", "/", dirname(__FILE__)) . '/');

//__autoload方法
function i_autoload($className) {
	if (is_int(strripos($className, '..'))) {
		return;
	}
	$file = ROOT . 'lib/' . $className . '.php';
	if (file_exists($file)) {
		include $file;
	}
}
spl_autoload_register('i_autoload');

!defined('FILE_FLAGS') && define('FILE_FLAGS', LOCK_EX);
/**
 * config('name');
 * config('name@file');
 * config('@file');
 */
if (!function_exists('config')) {
	!defined('CONFIG_PATH') && define('CONFIG_PATH', ROOT . 'config/');
	function config($key) {
		static $configs = array();
		list($key, $file) = explode('@', $key, 2);
		$file = empty($file) ? 'base' : $file;

		$file_name = CONFIG_PATH . $file . '.php';
		//读取配置
		if (empty($configs[$file]) AND file_exists($file_name)) {
			$configs[$file] = @include $file_name;
		}
		if (func_num_args() === 2) {
			$value = func_get_arg(1);
			//写入配置
			if (!empty($key)) {
				$configs[$file] = (array) $configs[$file];
				if (is_null($value)) {
					unset($configs[$file][$key]);
				} else {
					$configs[$file][$key] = $value;
				}
				//cache::clear();
			} else {
				if (is_null($value)) {
					return unlink($file_name);
				} else {
					$configs[$file] = $value;
				}
			}
			file_put_contents($file_name, "<?php return " . var_export($configs[$file], true) . ";", FILE_FLAGS);
		} else {
			//返回结果
			if (!empty($key)) {
				return $configs[$file][$key];
			}

			return $configs[$file];
		}

	}
}

// cache
define('CACHE_PATH', ROOT.'cache/');
cache::$type = empty( config('cache_type') )?'secache':config('cache_type');


if (!function_exists('db')) {
	function db($table) {
		return db::table($table);
	}
}

if (!function_exists('view')) {
	function view($file, $set = null) {
		return view::load($file, $set = null);
	}
}

if (!function_exists('_')) {
	function _($str) {
		return htmlspecialchars($str);
	}
}

if (!function_exists('e')) {
	function e($str) {
		echo $str;
	}
}

if (!function_exists('str_is')) {
	function str_is($pattern, $value)
	{
		if (is_null($pattern)) {
			$patterns = [];
		}
		$patterns = ! is_array($pattern) ? [$pattern] : $pattern;
		if (empty($patterns)) {
			return false;
		}
		foreach ($patterns as $pattern) {
			if ($pattern == $value) {
				return true;
			}
			$pattern = preg_quote($pattern, '#');
			$pattern = str_replace('\*', '.*', $pattern);
			if (preg_match('#^'.$pattern.'\z#u', $value) === 1) {
				return true;
			}
		}
		return false;
	}
}

if (!function_exists('get_domain')) {
	function get_domain($url=null)
	{
		if (is_null($url)) {
			return $_SERVER['HTTP_HOST'];
		}
		return strstr(ltrim(strstr($url, '://'), '://'), '/', true);
	}
}

function get_absolute_path($path) {
    $path = str_replace(array('/', '\\', '//'), '/', $path);
    $parts = array_filter(explode('/', $path), 'strlen');
    $absolutes = array();
    foreach ($parts as $part) {
        if ('.' == $part) continue;
        if ('..' == $part) {
            array_pop($absolutes);
        } else {
            $absolutes[] = $part;
        }
    }
    return str_replace('//','/','/'.implode('/', $absolutes).'/');
}

function is_login(){
	if($_COOKIE['admin'] == md5(config('password').config('refresh_token'))){
		return true;
	}else{
		return false;
	}
}

!defined('CONTROLLER_PATH') && define('CONTROLLER_PATH', ROOT.'controller/');
onedrive::$client_id = config('client_id');
onedrive::$client_secret = config('client_secret');
onedrive::$redirect_uri = config('redirect_uri');

================================================
FILE: lib/Parsedown.php
================================================
<?php

#
#
# Parsedown
# http://parsedown.org
#
# (c) Emanuil Rusev
# http://erusev.com
#
# For the full license information, view the LICENSE file that was distributed
# with this source code.
#
#

class Parsedown
{
    # ~

    const version = '1.7.1';

    # ~

    function text($text)
    {
        # make sure no definitions are set
        $this->DefinitionData = array();

        # standardize line breaks
        $text = str_replace(array("\r\n", "\r"), "\n", $text);

        # remove surrounding line breaks
        $text = trim($text, "\n");

        # split text into lines
        $lines = explode("\n", $text);

        # iterate through lines to identify blocks
        $markup = $this->lines($lines);

        # trim line breaks
        $markup = trim($markup, "\n");

        return $markup;
    }

    #
    # Setters
    #

    function setBreaksEnabled($breaksEnabled)
    {
        $this->breaksEnabled = $breaksEnabled;

        return $this;
    }

    protected $breaksEnabled;

    function setMarkupEscaped($markupEscaped)
    {
        $this->markupEscaped = $markupEscaped;

        return $this;
    }

    protected $markupEscaped;

    function setUrlsLinked($urlsLinked)
    {
        $this->urlsLinked = $urlsLinked;

        return $this;
    }

    protected $urlsLinked = true;

    function setSafeMode($safeMode)
    {
        $this->safeMode = (bool) $safeMode;

        return $this;
    }

    protected $safeMode;

    protected $safeLinksWhitelist = array(
        'http://',
        'https://',
        'ftp://',
        'ftps://',
        'mailto:',
        'data:image/png;base64,',
        'data:image/gif;base64,',
        'data:image/jpeg;base64,',
        'irc:',
        'ircs:',
        'git:',
        'ssh:',
        'news:',
        'steam:',
    );

    #
    # Lines
    #

    protected $BlockTypes = array(
        '#' => array('Header'),
        '*' => array('Rule', 'List'),
        '+' => array('List'),
        '-' => array('SetextHeader', 'Table', 'Rule', 'List'),
        '0' => array('List'),
        '1' => array('List'),
        '2' => array('List'),
        '3' => array('List'),
        '4' => array('List'),
        '5' => array('List'),
        '6' => array('List'),
        '7' => array('List'),
        '8' => array('List'),
        '9' => array('List'),
        ':' => array('Table'),
        '<' => array('Comment', 'Markup'),
        '=' => array('SetextHeader'),
        '>' => array('Quote'),
        '[' => array('Reference'),
        '_' => array('Rule'),
        '`' => array('FencedCode'),
        '|' => array('Table'),
        '~' => array('FencedCode'),
    );

    # ~

    protected $unmarkedBlockTypes = array(
        'Code',
    );

    #
    # Blocks
    #

    protected function lines(array $lines)
    {
        $CurrentBlock = null;

        foreach ($lines as $line)
        {
            if (chop($line) === '')
            {
                if (isset($CurrentBlock))
                {
                    $CurrentBlock['interrupted'] = true;
                }

                continue;
            }

            if (strpos($line, "\t") !== false)
            {
                $parts = explode("\t", $line);

                $line = $parts[0];

                unset($parts[0]);

                foreach ($parts as $part)
                {
                    $shortage = 4 - mb_strlen($line, 'utf-8') % 4;

                    $line .= str_repeat(' ', $shortage);
                    $line .= $part;
                }
            }

            $indent = 0;

            while (isset($line[$indent]) and $line[$indent] === ' ')
            {
                $indent ++;
            }

            $text = $indent > 0 ? substr($line, $indent) : $line;

            # ~

            $Line = array('body' => $line, 'indent' => $indent, 'text' => $text);

            # ~

            if (isset($CurrentBlock['continuable']))
            {
                $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);

                if (isset($Block))
                {
                    $CurrentBlock = $Block;

                    continue;
                }
                else
                {
                    if ($this->isBlockCompletable($CurrentBlock['type']))
                    {
                        $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
                    }
                }
            }

            # ~

            $marker = $text[0];

            # ~

            $blockTypes = $this->unmarkedBlockTypes;

            if (isset($this->BlockTypes[$marker]))
            {
                foreach ($this->BlockTypes[$marker] as $blockType)
                {
                    $blockTypes []= $blockType;
                }
            }

            #
            # ~

            foreach ($blockTypes as $blockType)
            {
                $Block = $this->{'block'.$blockType}($Line, $CurrentBlock);

                if (isset($Block))
                {
                    $Block['type'] = $blockType;

                    if ( ! isset($Block['identified']))
                    {
                        $Blocks []= $CurrentBlock;

                        $Block['identified'] = true;
                    }

                    if ($this->isBlockContinuable($blockType))
                    {
                        $Block['continuable'] = true;
                    }

                    $CurrentBlock = $Block;

                    continue 2;
                }
            }

            # ~

            if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
            {
                $CurrentBlock['element']['text'] .= "\n".$text;
            }
            else
            {
                $Blocks []= $CurrentBlock;

                $CurrentBlock = $this->paragraph($Line);

                $CurrentBlock['identified'] = true;
            }
        }

        # ~

        if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type']))
        {
            $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
        }

        # ~

        $Blocks []= $CurrentBlock;

        unset($Blocks[0]);

        # ~

        $markup = '';

        foreach ($Blocks as $Block)
        {
            if (isset($Block['hidden']))
            {
                continue;
            }

            $markup .= "\n";
            $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']);
        }

        $markup .= "\n";

        # ~

        return $markup;
    }

    protected function isBlockContinuable($Type)
    {
        return method_exists($this, 'block'.$Type.'Continue');
    }

    protected function isBlockCompletable($Type)
    {
        return method_exists($this, 'block'.$Type.'Complete');
    }

    #
    # Code

    protected function blockCode($Line, $Block = null)
    {
        if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted']))
        {
            return;
        }

        if ($Line['indent'] >= 4)
        {
            $text = substr($Line['body'], 4);

            $Block = array(
                'element' => array(
                    'name' => 'pre',
                    'handler' => 'element',
                    'text' => array(
                        'name' => 'code',
                        'text' => $text,
                    ),
                ),
            );

            return $Block;
        }
    }

    protected function blockCodeContinue($Line, $Block)
    {
        if ($Line['indent'] >= 4)
        {
            if (isset($Block['interrupted']))
            {
                $Block['element']['text']['text'] .= "\n";

                unset($Block['interrupted']);
            }

            $Block['element']['text']['text'] .= "\n";

            $text = substr($Line['body'], 4);

            $Block['element']['text']['text'] .= $text;

            return $Block;
        }
    }

    protected function blockCodeComplete($Block)
    {
        $text = $Block['element']['text']['text'];

        $Block['element']['text']['text'] = $text;

        return $Block;
    }

    #
    # Comment

    protected function blockComment($Line)
    {
        if ($this->markupEscaped or $this->safeMode)
        {
            return;
        }

        if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
        {
            $Block = array(
                'markup' => $Line['body'],
            );

            if (preg_match('/-->$/', $Line['text']))
            {
                $Block['closed'] = true;
            }

            return $Block;
        }
    }

    protected function blockCommentContinue($Line, array $Block)
    {
        if (isset($Block['closed']))
        {
            return;
        }

        $Block['markup'] .= "\n" . $Line['body'];

        if (preg_match('/-->$/', $Line['text']))
        {
            $Block['closed'] = true;
        }

        return $Block;
    }

    #
    # Fenced Code

    protected function blockFencedCode($Line)
    {
        if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([^`]+)?[ ]*$/', $Line['text'], $matches))
        {
            $Element = array(
                'name' => 'code',
                'text' => '',
            );

            if (isset($matches[1]))
            {
                $class = 'language-'.$matches[1];

                $Element['attributes'] = array(
                    'class' => $class,
                );
            }

            $Block = array(
                'char' => $Line['text'][0],
                'element' => array(
                    'name' => 'pre',
                    'handler' => 'element',
                    'text' => $Element,
                ),
            );

            return $Block;
        }
    }

    protected function blockFencedCodeContinue($Line, $Block)
    {
        if (isset($Block['complete']))
        {
            return;
        }

        if (isset($Block['interrupted']))
        {
            $Block['element']['text']['text'] .= "\n";

            unset($Block['interrupted']);
        }

        if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
        {
            $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);

            $Block['complete'] = true;

            return $Block;
        }

        $Block['element']['text']['text'] .= "\n".$Line['body'];

        return $Block;
    }

    protected function blockFencedCodeComplete($Block)
    {
        $text = $Block['element']['text']['text'];

        $Block['element']['text']['text'] = $text;

        return $Block;
    }

    #
    # Header

    protected function blockHeader($Line)
    {
        if (isset($Line['text'][1]))
        {
            $level = 1;

            while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
            {
                $level ++;
            }

            if ($level > 6)
            {
                return;
            }

            $text = trim($Line['text'], '# ');

            $Block = array(
                'element' => array(
                    'name' => 'h' . min(6, $level),
                    'text' => $text,
                    'handler' => 'line',
                ),
            );

            return $Block;
        }
    }

    #
    # List

    protected function blockList($Line)
    {
        list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');

        if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
        {
            $Block = array(
                'indent' => $Line['indent'],
                'pattern' => $pattern,
                'element' => array(
                    'name' => $name,
                    'handler' => 'elements',
                ),
            );

            if($name === 'ol')
            {
                $listStart = stristr($matches[0], '.', true);

                if($listStart !== '1')
                {
                    $Block['element']['attributes'] = array('start' => $listStart);
                }
            }

            $Block['li'] = array(
                'name' => 'li',
                'handler' => 'li',
                'text' => array(
                    $matches[2],
                ),
            );

            $Block['element']['text'] []= & $Block['li'];

            return $Block;
        }
    }

    protected function blockListContinue($Line, array $Block)
    {
        if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
        {
            if (isset($Block['interrupted']))
            {
                $Block['li']['text'] []= '';

                $Block['loose'] = true;

                unset($Block['interrupted']);
            }

            unset($Block['li']);

            $text = isset($matches[1]) ? $matches[1] : '';

            $Block['li'] = array(
                'name' => 'li',
                'handler' => 'li',
                'text' => array(
                    $text,
                ),
            );

            $Block['element']['text'] []= & $Block['li'];

            return $Block;
        }

        if ($Line['text'][0] === '[' and $this->blockReference($Line))
        {
            return $Block;
        }

        if ( ! isset($Block['interrupted']))
        {
            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);

            $Block['li']['text'] []= $text;

            return $Block;
        }

        if ($Line['indent'] > 0)
        {
            $Block['li']['text'] []= '';

            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);

            $Block['li']['text'] []= $text;

            unset($Block['interrupted']);

            return $Block;
        }
    }

    protected function blockListComplete(array $Block)
    {
        if (isset($Block['loose']))
        {
            foreach ($Block['element']['text'] as &$li)
            {
                if (end($li['text']) !== '')
                {
                    $li['text'] []= '';
                }
            }
        }

        return $Block;
    }

    #
    # Quote

    protected function blockQuote($Line)
    {
        if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
        {
            $Block = array(
                'element' => array(
                    'name' => 'blockquote',
                    'handler' => 'lines',
                    'text' => (array) $matches[1],
                ),
            );

            return $Block;
        }
    }

    protected function blockQuoteContinue($Line, array $Block)
    {
        if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
        {
            if (isset($Block['interrupted']))
            {
                $Block['element']['text'] []= '';

                unset($Block['interrupted']);
            }

            $Block['element']['text'] []= $matches[1];

            return $Block;
        }

        if ( ! isset($Block['interrupted']))
        {
            $Block['element']['text'] []= $Line['text'];

            return $Block;
        }
    }

    #
    # Rule

    protected function blockRule($Line)
    {
        if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
        {
            $Block = array(
                'element' => array(
                    'name' => 'hr'
                ),
            );

            return $Block;
        }
    }

    #
    # Setext

    protected function blockSetextHeader($Line, array $Block = null)
    {
        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
        {
            return;
        }

        if (chop($Line['text'], $Line['text'][0]) === '')
        {
            $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';

            return $Block;
        }
    }

    #
    # Markup

    protected function blockMarkup($Line)
    {
        if ($this->markupEscaped or $this->safeMode)
        {
            return;
        }

        if (preg_match('/^<(\w[\w-]*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
        {
            $element = strtolower($matches[1]);

            if (in_array($element, $this->textLevelElements))
            {
                return;
            }

            $Block = array(
                'name' => $matches[1],
                'depth' => 0,
                'markup' => $Line['text'],
            );

            $length = strlen($matches[0]);

            $remainder = substr($Line['text'], $length);

            if (trim($remainder) === '')
            {
                if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
                {
                    $Block['closed'] = true;

                    $Block['void'] = true;
                }
            }
            else
            {
                if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
                {
                    return;
                }

                if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
                {
                    $Block['closed'] = true;
                }
            }

            return $Block;
        }
    }

    protected function blockMarkupContinue($Line, array $Block)
    {
        if (isset($Block['closed']))
        {
            return;
        }

        if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
        {
            $Block['depth'] ++;
        }

        if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
        {
            if ($Block['depth'] > 0)
            {
                $Block['depth'] --;
            }
            else
            {
                $Block['closed'] = true;
            }
        }

        if (isset($Block['interrupted']))
        {
            $Block['markup'] .= "\n";

            unset($Block['interrupted']);
        }

        $Block['markup'] .= "\n".$Line['body'];

        return $Block;
    }

    #
    # Reference

    protected function blockReference($Line)
    {
        if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
        {
            $id = strtolower($matches[1]);

            $Data = array(
                'url' => $matches[2],
                'title' => null,
            );

            if (isset($matches[3]))
            {
                $Data['title'] = $matches[3];
            }

            $this->DefinitionData['Reference'][$id] = $Data;

            $Block = array(
                'hidden' => true,
            );

            return $Block;
        }
    }

    #
    # Table

    protected function blockTable($Line, array $Block = null)
    {
        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
        {
            return;
        }

        if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '')
        {
            $alignments = array();

            $divider = $Line['text'];

            $divider = trim($divider);
            $divider = trim($divider, '|');

            $dividerCells = explode('|', $divider);

            foreach ($dividerCells as $dividerCell)
            {
                $dividerCell = trim($dividerCell);

                if ($dividerCell === '')
                {
                    continue;
                }

                $alignment = null;

                if ($dividerCell[0] === ':')
                {
                    $alignment = 'left';
                }

                if (substr($dividerCell, - 1) === ':')
                {
                    $alignment = $alignment === 'left' ? 'center' : 'right';
                }

                $alignments []= $alignment;
            }

            # ~

            $HeaderElements = array();

            $header = $Block['element']['text'];

            $header = trim($header);
            $header = trim($header, '|');

            $headerCells = explode('|', $header);

            foreach ($headerCells as $index => $headerCell)
            {
                $headerCell = trim($headerCell);

                $HeaderElement = array(
                    'name' => 'th',
                    'text' => $headerCell,
                    'handler' => 'line',
                );

                if (isset($alignments[$index]))
                {
                    $alignment = $alignments[$index];

                    $HeaderElement['attributes'] = array(
                        'style' => 'text-align: '.$alignment.';',
                    );
                }

                $HeaderElements []= $HeaderElement;
            }

            # ~

            $Block = array(
                'alignments' => $alignments,
                'identified' => true,
                'element' => array(
                    'name' => 'table',
                    'handler' => 'elements',
                ),
            );

            $Block['element']['text'] []= array(
                'name' => 'thead',
                'handler' => 'elements',
            );

            $Block['element']['text'] []= array(
                'name' => 'tbody',
                'handler' => 'elements',
                'text' => array(),
            );

            $Block['element']['text'][0]['text'] []= array(
                'name' => 'tr',
                'handler' => 'elements',
                'text' => $HeaderElements,
            );

            return $Block;
        }
    }

    protected function blockTableContinue($Line, array $Block)
    {
        if (isset($Block['interrupted']))
        {
            return;
        }

        if ($Line['text'][0] === '|' or strpos($Line['text'], '|'))
        {
            $Elements = array();

            $row = $Line['text'];

            $row = trim($row);
            $row = trim($row, '|');

            preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);

            foreach ($matches[0] as $index => $cell)
            {
                $cell = trim($cell);

                $Element = array(
                    'name' => 'td',
                    'handler' => 'line',
                    'text' => $cell,
                );

                if (isset($Block['alignments'][$index]))
                {
                    $Element['attributes'] = array(
                        'style' => 'text-align: '.$Block['alignments'][$index].';',
                    );
                }

                $Elements []= $Element;
            }

            $Element = array(
                'name' => 'tr',
                'handler' => 'elements',
                'text' => $Elements,
            );

            $Block['element']['text'][1]['text'] []= $Element;

            return $Block;
        }
    }

    #
    # ~
    #

    protected function paragraph($Line)
    {
        $Block = array(
            'element' => array(
                'name' => 'p',
                'text' => $Line['text'],
                'handler' => 'line',
            ),
        );

        return $Block;
    }

    #
    # Inline Elements
    #

    protected $InlineTypes = array(
        '"' => array('SpecialCharacter'),
        '!' => array('Image'),
        '&' => array('SpecialCharacter'),
        '*' => array('Emphasis'),
        ':' => array('Url'),
        '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'),
        '>' => array('SpecialCharacter'),
        '[' => array('Link'),
        '_' => array('Emphasis'),
        '`' => array('Code'),
        '~' => array('Strikethrough'),
        '\\' => array('EscapeSequence'),
    );

    # ~

    protected $inlineMarkerList = '!"*_&[:<>`~\\';

    #
    # ~
    #

    public function line($text, $nonNestables=array())
    {
        $markup = '';

        # $excerpt is based on the first occurrence of a marker

        while ($excerpt = strpbrk($text, $this->inlineMarkerList))
        {
            $marker = $excerpt[0];

            $markerPosition = strpos($text, $marker);

            $Excerpt = array('text' => $excerpt, 'context' => $text);

            foreach ($this->InlineTypes[$marker] as $inlineType)
            {
                # check to see if the current inline type is nestable in the current context

                if ( ! empty($nonNestables) and in_array($inlineType, $nonNestables))
                {
                    continue;
                }

                $Inline = $this->{'inline'.$inlineType}($Excerpt);

                if ( ! isset($Inline))
                {
                    continue;
                }

                # makes sure that the inline belongs to "our" marker

                if (isset($Inline['position']) and $Inline['position'] > $markerPosition)
                {
                    continue;
                }

                # sets a default inline position

                if ( ! isset($Inline['position']))
                {
                    $Inline['position'] = $markerPosition;
                }

                # cause the new element to 'inherit' our non nestables

                foreach ($nonNestables as $non_nestable)
                {
                    $Inline['element']['nonNestables'][] = $non_nestable;
                }

                # the text that comes before the inline
                $unmarkedText = substr($text, 0, $Inline['position']);

                # compile the unmarked text
                $markup .= $this->unmarkedText($unmarkedText);

                # compile the inline
                $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']);

                # remove the examined text
                $text = substr($text, $Inline['position'] + $Inline['extent']);

                continue 2;
            }

            # the marker does not belong to an inline

            $unmarkedText = substr($text, 0, $markerPosition + 1);

            $markup .= $this->unmarkedText($unmarkedText);

            $text = substr($text, $markerPosition + 1);
        }

        $markup .= $this->unmarkedText($text);

        return $markup;
    }

    #
    # ~
    #

    protected function inlineCode($Excerpt)
    {
        $marker = $Excerpt['text'][0];

        if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
        {
            $text = $matches[2];
            $text = preg_replace("/[ ]*\n/", ' ', $text);

            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'code',
                    'text' => $text,
                ),
            );
        }
    }

    protected function inlineEmailTag($Excerpt)
    {
        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches))
        {
            $url = $matches[1];

            if ( ! isset($matches[2]))
            {
                $url = 'mailto:' . $url;
            }

            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'a',
                    'text' => $matches[1],
                    'attributes' => array(
                        'href' => $url,
                    ),
                ),
            );
        }
    }

    protected function inlineEmphasis($Excerpt)
    {
        if ( ! isset($Excerpt['text'][1]))
        {
            return;
        }

        $marker = $Excerpt['text'][0];

        if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
        {
            $emphasis = 'strong';
        }
        elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
        {
            $emphasis = 'em';
        }
        else
        {
            return;
        }

        return array(
            'extent' => strlen($matches[0]),
            'element' => array(
                'name' => $emphasis,
                'handler' => 'line',
                'text' => $matches[1],
            ),
        );
    }

    protected function inlineEscapeSequence($Excerpt)
    {
        if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
        {
            return array(
                'markup' => $Excerpt['text'][1],
                'extent' => 2,
            );
        }
    }

    protected function inlineImage($Excerpt)
    {
        if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
        {
            return;
        }

        $Excerpt['text']= substr($Excerpt['text'], 1);

        $Link = $this->inlineLink($Excerpt);

        if ($Link === null)
        {
            return;
        }

        $Inline = array(
            'extent' => $Link['extent'] + 1,
            'element' => array(
                'name' => 'img',
                'attributes' => array(
                    'src' => $Link['element']['attributes']['href'],
                    'alt' => $Link['element']['text'],
                ),
            ),
        );

        $Inline['element']['attributes'] += $Link['element']['attributes'];

        unset($Inline['element']['attributes']['href']);

        return $Inline;
    }

    protected function inlineLink($Excerpt)
    {
        $Element = array(
            'name' => 'a',
            'handler' => 'line',
            'nonNestables' => array('Url', 'Link'),
            'text' => null,
            'attributes' => array(
                'href' => null,
                'title' => null,
            ),
        );

        $extent = 0;

        $remainder = $Excerpt['text'];

        if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches))
        {
            $Element['text'] = $matches[1];

            $extent += strlen($matches[0]);

            $remainder = substr($remainder, $extent);
        }
        else
        {
            return;
        }

        if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches))
        {
            $Element['attributes']['href'] = $matches[1];

            if (isset($matches[2]))
            {
                $Element['attributes']['title'] = substr($matches[2], 1, - 1);
            }

            $extent += strlen($matches[0]);
        }
        else
        {
            if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
            {
                $definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
                $definition = strtolower($definition);

                $extent += strlen($matches[0]);
            }
            else
            {
                $definition = strtolower($Element['text']);
            }

            if ( ! isset($this->DefinitionData['Reference'][$definition]))
            {
                return;
            }

            $Definition = $this->DefinitionData['Reference'][$definition];

            $Element['attributes']['href'] = $Definition['url'];
            $Element['attributes']['title'] = $Definition['title'];
        }

        return array(
            'extent' => $extent,
            'element' => $Element,
        );
    }

    protected function inlineMarkup($Excerpt)
    {
        if ($this->markupEscaped or $this->safeMode or strpos($Excerpt['text'], '>') === false)
        {
            return;
        }

        if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*[ ]*>/s', $Excerpt['text'], $matches))
        {
            return array(
                'markup' => $matches[0],
                'extent' => strlen($matches[0]),
            );
        }

        if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?[^-])*-->/s', $Excerpt['text'], $matches))
        {
            return array(
                'markup' => $matches[0],
                'extent' => strlen($matches[0]),
            );
        }

        if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w[\w-]*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
        {
            return array(
                'markup' => $matches[0],
                'extent' => strlen($matches[0]),
            );
        }
    }

    protected function inlineSpecialCharacter($Excerpt)
    {
        if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text']))
        {
            return array(
                'markup' => '&amp;',
                'extent' => 1,
            );
        }

        $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot');

        if (isset($SpecialCharacter[$Excerpt['text'][0]]))
        {
            return array(
                'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
                'extent' => 1,
            );
        }
    }

    protected function inlineStrikethrough($Excerpt)
    {
        if ( ! isset($Excerpt['text'][1]))
        {
            return;
        }

        if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
        {
            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'del',
                    'text' => $matches[1],
                    'handler' => 'line',
                ),
            );
        }
    }

    protected function inlineUrl($Excerpt)
    {
        if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
        {
            return;
        }

        if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
        {
            $url = $matches[0][0];

            $Inline = array(
                'extent' => strlen($matches[0][0]),
                'position' => $matches[0][1],
                'element' => array(
                    'name' => 'a',
                    'text' => $url,
                    'attributes' => array(
                        'href' => $url,
                    ),
                ),
            );

            return $Inline;
        }
    }

    protected function inlineUrlTag($Excerpt)
    {
        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
        {
            $url = $matches[1];

            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'a',
                    'text' => $url,
                    'attributes' => array(
                        'href' => $url,
                    ),
                ),
            );
        }
    }

    # ~

    protected function unmarkedText($text)
    {
        if ($this->breaksEnabled)
        {
            $text = preg_replace('/[ ]*\n/', "<br />\n", $text);
        }
        else
        {
            $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "<br />\n", $text);
            $text = str_replace(" \n", "\n", $text);
        }

        return $text;
    }

    #
    # Handlers
    #

    protected function element(array $Element)
    {
        if ($this->safeMode)
        {
            $Element = $this->sanitiseElement($Element);
        }

        $markup = '<'.$Element['name'];

        if (isset($Element['attributes']))
        {
            foreach ($Element['attributes'] as $name => $value)
            {
                if ($value === null)
                {
                    continue;
                }

                $markup .= ' '.$name.'="'.self::escape($value).'"';
            }
        }

        if (isset($Element['text']))
        {
            $markup .= '>';

            if (!isset($Element['nonNestables'])) 
            {
                $Element['nonNestables'] = array();
            }

            if (isset($Element['handler']))
            {
                $markup .= $this->{$Element['handler']}($Element['text'], $Element['nonNestables']);
            }
            else
            {
                $markup .= self::escape($Element['text'], true);
            }

            $markup .= '</'.$Element['name'].'>';
        }
        else
        {
            $markup .= ' />';
        }

        return $markup;
    }

    protected function elements(array $Elements)
    {
        $markup = '';

        foreach ($Elements as $Element)
        {
            $markup .= "\n" . $this->element($Element);
        }

        $markup .= "\n";

        return $markup;
    }

    # ~

    protected function li($lines)
    {
        $markup = $this->lines($lines);

        $trimmedMarkup = trim($markup);

        if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '<p>')
        {
            $markup = $trimmedMarkup;
            $markup = substr($markup, 3);

            $position = strpos($markup, "</p>");

            $markup = substr_replace($markup, '', $position, 4);
        }

        return $markup;
    }

    #
    # Deprecated Methods
    #

    function parse($text)
    {
        $markup = $this->text($text);

        return $markup;
    }

    protected function sanitiseElement(array $Element)
    {
        static $goodAttribute = '/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/';
        static $safeUrlNameToAtt  = array(
            'a'   => 'href',
            'img' => 'src',
        );

        if (isset($safeUrlNameToAtt[$Element['name']]))
        {
            $Element = $this->filterUnsafeUrlInAttribute($Element, $safeUrlNameToAtt[$Element['name']]);
        }

        if ( ! empty($Element['attributes']))
        {
            foreach ($Element['attributes'] as $att => $val)
            {
                # filter out badly parsed attribute
                if ( ! preg_match($goodAttribute, $att))
                {
                    unset($Element['attributes'][$att]);
                }
                # dump onevent attribute
                elseif (self::striAtStart($att, 'on'))
                {
                    unset($Element['attributes'][$att]);
                }
            }
        }

        return $Element;
    }

    protected function filterUnsafeUrlInAttribute(array $Element, $attribute)
    {
        foreach ($this->safeLinksWhitelist as $scheme)
        {
            if (self::striAtStart($Element['attributes'][$attribute], $scheme))
            {
                return $Element;
            }
        }

        $Element['attributes'][$attribute] = str_replace(':', '%3A', $Element['attributes'][$attribute]);

        return $Element;
    }

    #
    # Static Methods
    #

    protected static function escape($text, $allowQuotes = false)
    {
        return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8');
    }

    protected static function striAtStart($string, $needle)
    {
        $len = strlen($needle);

        if ($len > strlen($string))
        {
            return false;
        }
        else
        {
            return strtolower(substr($string, 0, $len)) === strtolower($needle);
        }
    }

    static function instance($name = 'default')
    {
        if (isset(self::$instances[$name]))
        {
            return self::$instances[$name];
        }

        $instance = new static();

        self::$instances[$name] = $instance;

        return $instance;
    }

    private static $instances = array();

    #
    # Fields
    #

    protected $DefinitionData;

    #
    # Read-Only

    protected $specialCharacters = array(
        '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|',
    );

    protected $StrongRegex = array(
        '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
        '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us',
    );

    protected $EmRegex = array(
        '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s',
        '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
    );

    protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?';

    protected $voidElements = array(
        'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
    );

    protected $textLevelElements = array(
        'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont',
        'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing',
        'i', 'rp', 'del', 'code',          'strike', 'marquee',
        'q', 'rt', 'ins', 'font',          'strong',
        's', 'tt', 'kbd', 'mark',
        'u', 'xm', 'sub', 'nobr',
                   'sup', 'ruby',
                   'var', 'span',
                   'wbr', 'time',
    );
}


================================================
FILE: lib/cache/filecache_.php
================================================
<?php 
class filecache_{
	private $cache_path;
	
	function __construct($cache_path= null){
		if(empty($cache_path)){
			$cache_path = CACHE_PATH;
		}
		$this->cache_path = $cache_path;
	}

	function get($key){
		$file = $this->cache_path . md5($key) . '.php';
		$data = @include $file;
		if( is_array($data) && $data['expire'] > time() && !is_null($data['data']) ){
			return $data['data'];
		}else{
			return null;
		}
	}

	function set($key, $value=null, $expire=99999999){
		$file = $this->cache_path . md5($key) . '.php';
		$data['expire'] = time() + $expire;
		$data['data'] = $value;
		return @file_put_contents($file, "<?php return " . var_export($data, true) . ";", FILE_FLAGS);
	}

	function clear(){
		array_map('unlink', glob($this->cache_path.'*.php'));
	}
}

================================================
FILE: lib/cache/memcache_.php
================================================
<?php 
class memcache_{
	private $m;
	
	function __construct($config = null){
		$this->m = new Memcache();
		if(empty($config)){
			$config = 'localhost:11211';
		}
		list($host, $port) = explode(':', $config, 2);
		$this->m->addServer($host, $port);
	}

	function get($key){
		$data = $this->m->get($key);
		if( is_array($data) && $data['expire'] > time() && !is_null($data['data']) ){
			return $data['data'];
		}else{
			return null;
		}
	}

	function set($key, $value=null, $expire=99999999){
		$data['expire'] = time() + $expire;
		$data['data'] = $value;
		return $this->m->set($key, $data);
	}

	function clear(){
		$this->m->flush(10);
	}
}


================================================
FILE: lib/cache/redis_.php
================================================
<?php
class redis_{
        private $redis;

        function __construct($config = null){
                $this->redis = new Redis();
                if(empty($config)){
                        $config = 'localhost:6379';
                }
                list($host, $port) = explode(':', $config, 2);
                $this->redis->pconnect($host, $port);
        }

        function get($key){
                $gRefreshTime = $this->redis->get("OneIndex_gRefreshTime");
                $key = "OneIndex_$gRefreshTime\_" . $key;
                $data = $this->redis->get($key);
                return unserialize($data) ?: null;
        }

        function set($key, $value=null, $expire=600){
                $gRefreshTime = $this->redis->get("OneIndex_gRefreshTime");
                if (empty($gRefreshTime)) {
                        $gRefreshTime = time();
                        $this->redis->set("OneIndex_gRefreshTime", $gRefreshTime);
                }
                $key = "OneIndex_$gRefreshTime\_" . $key;
                return $this->redis->set($key, serialize($value), $expire);
        }

        function clear(){
                $this->redis->set("OneIndex_gRefreshTime", $gRefreshTime);
        }
}


================================================
FILE: lib/cache/secache_.php
================================================
<?php 
class secache_{
	private $cachefile;
	private $c;
	
	function __construct($config=null){
		
		list($cachefile, $size) = explode(':', $config, 2);
		
		if(empty($cachefile)){
			$cachefile = CACHE_PATH.'cachedata';
		}

		if(empty($size)){
			$size = '100M';
		}

		define('SECACHE_SIZE',$size);
		$this->cachefile = $cachefile;
		$this->c = new secache();
		$this->c->workat($this->cachefile);
	}

	function get($key){
		$this->c->fetch(md5($key),$data);
		if( is_array($data) && $data['expire'] > time() && !is_null($data['data']) ){
			return $data['data'];
		}else{
			return null;
		}
	}

	function set($key, $value=null, $expire=99999999){
		$data['expire'] = time() + $expire;
		$data['data'] = $value;
		return $this->c->store(md5($key),$data);
		
	}

	function clear(){
		return $this->c->clear();
	}
}

class secache{
    var $idx_node_size = 40;
	var $idx_node_base = 0;
    var $data_base_pos = 262588; //40+20+24*16+16*16*16*16*4;
    var $schema_item_size = 24;
    var $header_padding = 20; //保留空间 放置php标记防止下载
    var $info_size = 20; //保留空间 4+16 maxsize|ver
    //40起 添加20字节保留区域
    var $idx_seq_pos = 40; //id 计数器节点地址
    var $dfile_cur_pos = 44; //id 计数器节点地址
    var $idx_free_pos = 48; //id 空闲链表入口地址
    var $idx_base_pos = 444; //40+20+24*16
    var $min_size = 10240; //10M最小值
    var $schema_struct = array('size','free','lru_head','lru_tail','hits','miss');
    var $ver = '$Rev$';
    var $name = '系统默认缓存(文件型)';
    function workat($file){
        $this->_file = $file.'.php';
        $this->_bsize_list = array(
            512=>10,
            3<<10=>10,
            8<<10=>10,
            20<<10=>4,
            30<<10=>2,
            50<<10=>2,
            80<<10=>2,
            96<<10=>2,
            128<<10=>2,
            224<<10=>2,
            256<<10=>2,
            512<<10=>1,
            1024<<10=>1,
        );
        $this->_node_struct = array(
            'next'=>array(0,'V'),
            'prev'=>array(4,'V'),
            'data'=>array(8,'V'),
            'size'=>array(12,'V'),
            'lru_right'=>array(16,'V'),
            'lru_left'=>array(20,'V'),
            'key'=>array(24,'H*'),
        );
        if(!file_exists($this->_file)){
            $this->create();
        }else{
            $this->_rs = fopen($this->_file,'rb+') or $this->trigger_error('Can\'t open the cachefile: '.realpath($this->_file),E_USER_ERROR);
            $this->_seek($this->header_padding);
            $info = unpack('V1max_size/a*ver',fread($this->_rs,$this->info_size));
			$info['ver'] = trim($info['ver']);
            if($info['ver']!=$this->ver){
                $this->_format(true);
            }else{
                $this->max_size = $info['max_size'];
            }
        }
        $this->idx_node_base = $this->data_base_pos+$this->max_size;
        $this->_block_size_list = array_keys($this->_bsize_list);
        sort($this->_block_size_list);
        return true;
    }
    function create(){
        $this->_rs = fopen($this->_file,'wb+') or $this->trigger_error('Can\'t open the cachefile: '.realpath($this->_file),E_USER_ERROR);;
        fseek($this->_rs,0);
        fputs($this->_rs,'<'.'?php exit()?'.'>');
        return $this->_format();
    }
    function _puts($offset,$data){
        if($offset < $this->max_size*1.5){
            $this->_seek($offset);
            return fputs($this->_rs,$data);
        }else{
            $this->trigger_error('Offset over quota:'.$offset,E_USER_ERROR);
        }
    }
    function _seek($offset){
        return fseek($this->_rs,$offset);
    }
    function clear(){
        return $this->_format(true);
    }
    function fetch($key,&$return){
        if($this->lock(false)){
            $locked = true;
        }
        if($this->search($key,$offset)){
            $info = $this->_get_node($offset);
            $schema_id = $this->_get_size_schema_id($info['size']);
            if($schema_id===false){
                if($locked) $this->unlock();
                return false;
            }
            $this->_seek($info['data']);
            $data = fread($this->_rs,$info['size']);
            $return = unserialize($data);
            if($return===false){
                if($locked) $this->unlock();
                return false;
            }
            if($locked){
                $this->_lru_push($schema_id,$info['offset']);
                $this->_set_schema($schema_id,'hits',$this->_get_schema($schema_id,'hits')+1);
                return $this->unlock();
            }else{
                return true;
            }
        }else{
            if($locked) $this->unlock();
            return false;
        }
    }
    /**
     * lock
     * 如果flock不管用,请继承本类,并重载此方法
     *
     * @param mixed $is_block 是否阻塞
     * @access public
     * @return void
     */
    function lock($is_block,$whatever=false){
        ignore_user_abort(1);
        return flock($this->_rs, $is_block?LOCK_EX:LOCK_EX+LOCK_NB);
    }
    /**
     * unlock
     * 如果flock不管用,请继承本类,并重载此方法
     *
     * @access public
     * @return void
     */
    function unlock(){
        ignore_user_abort(0);
        return flock($this->_rs, LOCK_UN);
    }
    function delete($key,$pos=false){
        if($pos || $this->search($key,$pos)){
            if($info = $this->_get_node($pos)){
                //删除data区域
                if($info['prev']){
                    $this->_set_node($info['prev'],'next',$info['next']);
                    $this->_set_node($info['next'],'prev',$info['prev']);
                }else{ //改入口位置
                    $this->_set_node($info['next'],'prev',0);
                    $this->_set_node_root($key,$info['next']);
                }
                $this->_free_dspace($info['size'],$info['data']);
                $this->_lru_delete($info);
                $this->_free_node($pos);
                return $info['prev'];
            }
        }
        return false;
    }
    function store($key,$value){
        if($this->lock(true)){
            //save data
            $data = serialize($value);
            $size = strlen($data);
            //get list_idx
            $has_key = $this->search($key,$list_idx_offset);
            $schema_id = $this->_get_size_schema_id($size);
            if($schema_id===false){
                $this->unlock();
                return false;
            }
            if($has_key){
                $hdseq = $list_idx_offset;
                $info = $this->_get_node($hdseq);
                if($schema_id == $this->_get_size_schema_id($info['size'])){
                    $dataoffset = $info['data'];
                }else{
                    //破掉原有lru
                    $this->_lru_delete($info);
                    if(!($dataoffset = $this->_dalloc($schema_id))){
                        $this->unlock();
                        return false;
                    }
                    $this->_free_dspace($info['size'],$info['data']);
                    $this->_set_node($hdseq,'lru_left',0);
                    $this->_set_node($hdseq,'lru_right',0);
                }
                $this->_set_node($hdseq,'size',$size);
                $this->_set_node($hdseq,'data',$dataoffset);
            }else{
                if(!($dataoffset = $this->_dalloc($schema_id))){
                    $this->unlock();
                    return false;
                }
                $hdseq = $this->_alloc_idx(array(
                    'next'=>0,
                    'prev'=>$list_idx_offset,
                    'data'=>$dataoffset,
                    'size'=>$size,
                    'lru_right'=>0,
                    'lru_left'=>0,
                    'key'=>$key,
                ));
                if($list_idx_offset>0){
                    $this->_set_node($list_idx_offset,'next',$hdseq);
                }else{
                    $this->_set_node_root($key,$hdseq);
                }
            }
            if($dataoffset>$this->max_size){
                $this->trigger_error('alloc datasize:'.$dataoffset,E_USER_WARNING);
                return false;
            }
            $this->_puts($dataoffset,$data);
            $this->_set_schema($schema_id,'miss',$this->_get_schema($schema_id,'miss')+1);
            $this->_lru_push($schema_id,$hdseq);
            $this->unlock();
            return true;
        }else{
            $this->trigger_error("Couldn't lock the file !",E_USER_WARNING);
            return false;
        }
    }
    /**
     * search
     * 查找指定的key
     * 如果找到节点则$pos=节点本身 返回true
     * 否则 $pos=树的末端 返回false
     *
     * @param mixed $key
     * @access public
     * @return void
     */
    function search($key,&$pos){
        return $this->_get_pos_by_key($this->_get_node_root($key),$key,$pos);
    }
    function _get_size_schema_id($size){
        foreach($this->_block_size_list as $k=>$block_size){
            if($size <= $block_size){
                return $k;
            }
        }
        return false;
    }
    function _parse_str_size($str_size,$default){
        if(preg_match('/^([0-9]+)\s*([gmk]|)$/i',$str_size,$match)){
            switch(strtolower($match[2])){
            case 'g':
                if($match[1]>1){
                    $this->trigger_error('Max cache size 1G',E_USER_ERROR);
                }
                $size = $match[1]<<30;
                break;
            case 'm':
                $size = $match[1]<<20;
                break;
            case 'k':
                $size = $match[1]<<10;
                break;
            default:
                $size = $match[1];
            }
            if($size<=0){
                $this->trigger_error('Error cache size '.$this->max_size,E_USER_ERROR);
                return false;
            }elseif($size<10485760){
                return 10485760;
            }else{
                return $size;
            }
        }else{
            return $default;
        }
    }
    function _format($truncate=false){
        if($this->lock(true,true)){
            if($truncate){
                $this->_seek(0);
                ftruncate($this->_rs,$this->idx_node_base);
            }
            $this->max_size = $this->_parse_str_size(SECACHE_SIZE,15728640); //default:15m
            $this->_puts($this->header_padding,pack('V1a*',$this->max_size,$this->ver));
            ksort($this->_bsize_list);
            $ds_offset = $this->data_base_pos;
            $i=0;
            foreach($this->_bsize_list as $size=>$count){
                //将预分配的空间注册到free链表里
                $count *= min(3,floor($this->max_size/10485760));
                $next_free_node = 0;
                for($j=0;$j<$count;$j++){
                    $this->_puts($ds_offset,pack('V',$next_free_node));
                    $next_free_node = $ds_offset;
                    $ds_offset+=intval($size);
                }
                $code = pack(str_repeat('V1',count($this->schema_struct)),$size,$next_free_node,0,0,0,0);
                $this->_puts(60+$i*$this->schema_item_size,$code);
                $i++;
            }
            $this->_set_dcur_pos($ds_offset);
            $this->_puts($this->idx_base_pos,str_repeat("\0",262144));
            $this->_puts($this->idx_seq_pos,pack('V',1));
            $this->unlock();
            return true;
        }else{
            $this->trigger_error("Couldn't lock the file !",E_USER_ERROR);
            return false;
        }
    }
    function _get_node_root($key){
        $this->_seek(hexdec(substr($key,0,4))*4+$this->idx_base_pos);
        $a= fread($this->_rs,4);
        list(,$offset) = unpack('V',$a);
        return $offset;
    }
    function _set_node_root($key,$value){
        return $this->_puts(hexdec(substr($key,0,4))*4+$this->idx_base_pos,pack('V',$value));
    }
    function _set_node($pos,$key,$value){
        if(!$pos){
            return false;
        }
        if(isset($this->_node_struct[$key])){
            return $this->_puts($pos*$this->idx_node_size+$this->idx_node_base+$this->_node_struct[$key][0],pack($this->_node_struct[$key][1],$value));
        }else{
            return false;
        }
    }
    function _get_pos_by_key($offset,$key,&$pos){
        if(!$offset){
            $pos = 0;
            return false;
        }
        $info = $this->_get_node($offset);
        if($info['key']==$key){
            $pos = $info['offset'];
            return true;
        }elseif($info['next'] && $info['next']!=$offset){
            return $this->_get_pos_by_key($info['next'],$key,$pos);
        }else{
            $pos = $offset;
            return false;
        }
    }
    function _lru_delete($info){
        if($info['lru_right']){
            $this->_set_node($info['lru_right'],'lru_left',$info['lru_left']);
        }else{
            $this->_set_schema($this->_get_size_schema_id($info['size']),'lru_tail',$info['lru_left']);
        }
        if($info['lru_left']){
            $this->_set_node($info['lru_left'],'lru_right',$info['lru_right']);
        }else{
            $this->_set_schema($this->_get_size_schema_id($info['size']),'lru_head',$info['lru_right']);
        }
        return true;
    }
    function _lru_push($schema_id,$offset){
        $lru_head = $this->_get_schema($schema_id,'lru_head');
        $lru_tail = $this->_get_schema($schema_id,'lru_tail');
        if((!$offset) || ($lru_head==$offset))return;
        $info = $this->_get_node($offset);
        $this->_set_node($info['lru_right'],'lru_left',$info['lru_left']);
        $this->_set_node($info['lru_left'],'lru_right',$info['lru_right']);
        $this->_set_node($offset,'lru_right',$lru_head);
        $this->_set_node($offset,'lru_left',0);
        $this->_set_node($lru_head,'lru_left',$offset);
        $this->_set_schema($schema_id,'lru_head',$offset);
        if($lru_tail==0){
            $this->_set_schema($schema_id,'lru_tail',$offset);
        }elseif($lru_tail==$offset && $info['lru_left']){
            $this->_set_schema($schema_id,'lru_tail',$info['lru_left']);
        }
        return true;
    }
    function _get_node($offset){
        $this->_seek($offset*$this->idx_node_size + $this->idx_node_base);
        $info = unpack('V1next/V1prev/V1data/V1size/V1lru_right/V1lru_left/H*key',fread($this->_rs,$this->idx_node_size));
        $info['offset'] = $offset;
        return $info;
    }
    function _lru_pop($schema_id){
        if($node = $this->_get_schema($schema_id,'lru_tail')){
            $info = $this->_get_node($node);
            if(!$info['data']){
                return false;
            }
            $this->delete($info['key'],$info['offset']);
            if(!$this->_get_schema($schema_id,'free')){
                $this->trigger_error('pop lru,But nothing free...',E_USER_ERROR);
            }
            return $info;
        }else{
            return false;
        }
    }
    function _dalloc($schema_id,$lru_freed=false){
        if($free = $this->_get_schema($schema_id,'free')){ //如果lru里有链表
            $this->_seek($free);
            list(,$next) = unpack('V',fread($this->_rs,4));
            $this->_set_schema($schema_id,'free',$next);
            return $free;
        }elseif($lru_freed){
            $this->trigger_error('Bat lru poped freesize',E_USER_ERROR);
            return false;
        }else{
            $ds_offset = $this->_get_dcur_pos();
            $size = $this->_get_schema($schema_id,'size');
            if($size+$ds_offset > $this->max_size){
                if($info = $this->_lru_pop($schema_id)){
                    return $this->_dalloc($schema_id,$info);
                }else{
                    $this->trigger_error('Can\'t alloc dataspace',E_USER_ERROR);
                    return false;
                }
            }else{
                $this->_set_dcur_pos($ds_offset+$size);
                return $ds_offset;
            }
        }
    }
    function _get_dcur_pos(){
        $this->_seek($this->dfile_cur_pos);
        list(,$ds_offset) = unpack('V',fread($this->_rs,4));
        return $ds_offset;
    }
    function _set_dcur_pos($pos){
        return $this->_puts($this->dfile_cur_pos,pack('V',$pos));
    }
    function _free_dspace($size,$pos){
        if($pos>$this->max_size){
            $this->trigger_error('free dspace over quota:'.$pos,E_USER_ERROR);
            return false;
        }
        $schema_id = $this->_get_size_schema_id($size);
        if($free = $this->_get_schema($schema_id,'free')){
            $this->_puts($free,pack('V1',$pos));
        }else{
            $this->_set_schema($schema_id,'free',$pos);
        }
        $this->_puts($pos,pack('V1',0));
    }
    function _dfollow($pos,&$c){
        $c++;
        $this->_seek($pos);
        list(,$next) = unpack('V1',fread($this->_rs,4));
        if($next){
            return $this->_dfollow($next,$c);
        }else{
            return $pos;
        }
    }
    function _free_node($pos){
        $this->_seek($this->idx_free_pos);
        list(,$prev_free_node) = unpack('V',fread($this->_rs,4));
        $this->_puts($pos*$this->idx_node_size+$this->idx_node_base,pack('V',$prev_free_node).str_repeat("\0",$this->idx_node_size-4));
        return $this->_puts($this->idx_free_pos,pack('V',$pos));
    }
    function _alloc_idx($data){
        $this->_seek($this->idx_free_pos);
        list(,$list_pos) = unpack('V',fread($this->_rs,4));
        if($list_pos){
            $this->_seek($list_pos*$this->idx_node_size+$this->idx_node_base);
            list(,$prev_free_node) = unpack('V',fread($this->_rs,4));
            $this->_puts($this->idx_free_pos,pack('V',$prev_free_node));
        }else{
            $this->_seek($this->idx_seq_pos);
            list(,$list_pos) = unpack('V',fread($this->_rs,4));
            $this->_puts($this->idx_seq_pos,pack('V',$list_pos+1));
        }
        return $this->_create_node($list_pos,$data);
    }
    function _create_node($pos,$data){
        $this->_puts($pos*$this->idx_node_size + $this->idx_node_base
            ,pack('V1V1V1V1V1V1H*',$data['next'],$data['prev'],$data['data'],$data['size'],$data['lru_right'],$data['lru_left'],$data['key']));
        return $pos;
    }
    function _set_schema($schema_id,$key,$value){
        $info = array_flip($this->schema_struct);
        return $this->_puts(60+$schema_id*$this->schema_item_size + $info[$key]*4,pack('V',$value));
    }
    function _get_schema($id,$key){
        $info = array_flip($this->schema_struct);
        $this->_seek(60+$id*$this->schema_item_size);
        unpack('V1'.implode('/V1',$this->schema_struct),fread($this->_rs,$this->schema_item_size));
        $this->_seek(60+$id*$this->schema_item_size + $info[$key]*4);
        list(,$value) =unpack('V',fread($this->_rs,4));
        return $value;
    }
    function _all_schemas(){
        $schema = array();
        for($i=0;$i<16;$i++){
            $this->_seek(60+$i*$this->schema_item_size);
            $info = unpack('V1'.implode('/V1',$this->schema_struct),fread($this->_rs,$this->schema_item_size));
            if($info['size']){
                $info['id'] = $i;
                $schema[$i] = $info;
            }else{
                return $schema;
            }
        }
    }
    function schemaStatus(){
        $return = array();
        foreach($this->_all_schemas() as $k=>$schemaItem){
            if($schemaItem['free']){
                $this->_dfollow($schemaItem['free'],$schemaItem['freecount']);
            }
            $return[] = $schemaItem;
        }
        return $return;
    }
    function status(&$curBytes,&$totalBytes){
        $totalBytes = $curBytes = 0;
        $hits = $miss = 0;
        $schemaStatus = $this->schemaStatus();
        $totalBytes = $this->max_size;
        $freeBytes = $this->max_size - $this->_get_dcur_pos();
        foreach($schemaStatus as $schema){
            $freeBytes+=$schema['freecount']*$schema['size'];
            $miss += $schema['miss'];
            $hits += $schema['hits'];
        }
        $curBytes = $totalBytes-$freeBytes;
        $return[] = array('name'=>'缓存命中','value'=>$hits);
        $return[] = array('name'=>'缓存未命中','value'=>$miss);
        return $return;
    }
    function trigger_error($errstr,$errno){
        trigger_error($errstr,$errno);
    }
}
?>


================================================
FILE: lib/cache.php
================================================
<?php

	!defined('CACHE_PATH') && define('CACHE_PATH', sys_get_temp_dir().'/');
	class cache{
		// 驱动方式(支持filecache/memcache/secache)
		static $type = 'secache';

		// 返回缓存实例
    	protected static function c(){
	    	static $instance = null;
	    	if(!is_null($instance)){
		    	return $instance;
	    	}
	    	
			list($type, $config) = explode(':', self::$type, 2);

			$type .= '_';
	    	if( in_array($type, array('filecache_', 'memcache_', 'secache_', 'redis_')) ){
		    	$file = str_replace("\\", "/", dirname(__FILE__)) . '/cache/'.$type.'.php';
			    include_once( $file );
		    	$instance = new $type($config);
		    	return $instance;
	    	}
    	}

		// 获取缓存
		static function get($key, $default=null, $expire=99999999){
			$value = self::c()->get($key);
			if(!is_null($value)){
				return $value;
			}elseif(is_callable($default)){
				$value = $default();
				self::set($key, $value, $expire);
				return $value;
			}elseif(!is_null($default)){
				self::set($key, $default, $expire);
				return $default;
			}
		}

		// 设置缓存
		static function set($key, $value, $expire=99999999){
			return self::c()->set($key, $value, $expire);
		}

		// 清空缓存
		static function clear(){
			return self::c()->clear();
		}

		// 删除缓存
		static function del($key){
			return self::set($key, null);
		}

		// 判断缓存是否设置
		static function has($key){
			if(is_null(self::get($key))){
				return false;
			}else{
				return true;
			}
		}
		// 读取并删除缓存
		static function pull($key){
			$value = self::get($key);
			self::del($key);
			return $value;
		}
	}


================================================
FILE: lib/fetch.php
================================================
<?php
class fetch {
	public static $headers = "User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";
	public static $cookies;
	public static $curl_opt;
	public static $proxy;

	public static $max_connect = 10;

	public static function init($opt = array()) {
		self::$curl_opt = array(
			CURLOPT_RETURNTRANSFER => 1, //true, $head 有请求的返回值
			CURLOPT_BINARYTRANSFER => true, //返回原生的Raw输出
			CURLOPT_HEADER => true, //启用时会将头文件的信息作为数据流输出。
			CURLOPT_FAILONERROR => true, //显示HTTP状态码,默认行为是忽略编号小于等于400的HTTP信息。
			CURLOPT_AUTOREFERER => true, //当根据Location:重定向时,自动设置header中的Referer:信息。
			CURLOPT_FOLLOWLOCATION => false, //跳转
			CURLOPT_CONNECTTIMEOUT => 3, //在发起连接前等待的时间,如果设置为0,则无限等待。
			CURLOPT_TIMEOUT => 5, //设置cURL允许执行的最长秒数。
			CURLOPT_ENCODING => 'gzip,deflate',
			CURLOPT_SSL_VERIFYHOST => false,
			CURLOPT_SSL_VERIFYPEER => false,
		);
		foreach ($opt as $k => $v) {
			self::$curl_opt[$k] = $v;
		}
	}

	/**
	 * fetch::get('http://www.google.com/');
	 * fetch::post('http://www.google.com/', array('name'=>'foo'));
	 */
	public static function __callstatic($method, $args) {
		if (is_null(self::$curl_opt)) {
			self::init();
		}
		@list($request, $post_data, $callback) = $args;
		if (is_callable($post_data)) {
			$callback = $post_data;
			$post_data = null;
		}

		//single_curl
		if (is_string($request) || !empty($request['url'])) {
			$request = self::bulid_request($request, $method, $post_data, $callback);
			return self::single_curl($request);
		} elseif (is_array($request)) {
			//rolling_curl
			foreach ($request as $k => $r) {
				$requests[$k] = self::bulid_request($r, $method, $post_data, $callback);
			}
			return self::rolling_curl($requests);
		}
	}

	private static function bulid_request($request, $method = 'GET', $post_data = null, $callback = null) {
		//url
		if (is_string($request)) {
			$request = array('url' => $request);
		}
		empty($request['method']) && $request['method'] = $method;
		empty($request['post_data']) && $request['post_data'] = $post_data;
		empty($request['callback']) && $request['callback'] = $callback;
		return $request;
	}

	private static function bulid_ch(&$request) {
		// url
		$ch = curl_init($request['url']);
		// curl_opt
		$curl_opt = empty($request['curl_opt']) ? array() : $request['curl_opt'];
		$curl_opt = $curl_opt + (array) self::$curl_opt;
		// method
		$curl_opt[CURLOPT_CUSTOMREQUEST] = strtoupper($request['method']);
		// post_data
		if (!empty($request['post_data'])) {
			$curl_opt[CURLOPT_POST] = true;
			$curl_opt[CURLOPT_POSTFIELDS] = $request['post_data'];
		}
		// header
		$headers = @self::bulid_request_header($request['headers'], $cookies);
		$curl_opt[CURLOPT_HTTPHEADER] = $headers;

		// cookies
		$request['cookies'] = empty($request['cookies']) ? fetch::$cookies : $request['cookies'];
		$cookies = empty($request['cookies']) ? $cookies : self::cookies_arr2str($request['cookies']);
		if (!empty($cookies)) {
			$curl_opt[CURLOPT_COOKIE] = $cookies;
		}

		//proxy
		$proxy = empty($request['proxy']) ? self::$proxy : $request['proxy'];
		if (!empty($proxy)) {
			$curl_opt[CURLOPT_PROXY] = $proxy;
		}

		//setopt
		curl_setopt_array($ch, $curl_opt);

		$request['curl_opt'] = $curl_opt;
		$request['ch'] = $ch;

		return $ch;
	}

	private static function response($raw, $ch) {
		$response = (object) curl_getinfo($ch);
		$response->raw = $raw;
		//$raw = fetch::iconv($raw, $response->content_type);
		$response->headers = substr($raw, 0, $response->header_size);
		$response->cookies = fetch::get_respone_cookies($response->headers);
		fetch::$cookies = array_merge((array) fetch::$cookies, $response->cookies);
		$response->content = substr($raw, $response->header_size);
		return $response;
	}

	private static function single_curl($request) {
		$ch = self::bulid_ch($request);
		$raw = curl_exec($ch);
		$response = self::response($raw, $ch);
		curl_close($ch);
		if (is_callable($request['callback'])) {
			call_user_func($request['callback'], $response, $request);
		}
		return $response;
	}

	private static function rolling_curl($requests) {
		$master = curl_multi_init();
		$map = array();
		// start the first batch of requests
		do {
			$k = key($requests);
			$request = current($requests);
			next($requests);
			$ch = self::bulid_ch($request);
			curl_multi_add_handle($master, $ch);
			$key = (string) $ch;
			$map[$key] = array($k, $request['callback']);
		} while (count($map) < self::$max_connect && count($map) < count($requests));

		do {
			while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM);
			if ($execrun != CURLM_OK) {
				break;
			}

			// a request was just completed -- find out which one
			while ($done = curl_multi_info_read($master)) {
				$key = (string) $done['handle'];

				list($k, $callback) = $map[$key];

				// get the info and content returned on the request
				$raw = curl_multi_getcontent($done['handle']);
				$response = self::response($raw, $done['handle']);
				$responses[$k] = $response;

				// send the return values to the callback function.
				if (is_callable($callback)) {
					$key = (string) $done['handle'];
					unset($map[$key]);
					call_user_func($callback, $response, $requests[$k], $k);
				}

				// start a new request (it's important to do this before removing the old one)
				$k = key($requests);
				if (!empty($k)) {
					$k = key($requests);
					$request = current($requests);
					next($requests);
					$ch = self::bulid_ch($request);
					curl_multi_add_handle($master, $ch);
					$key = (string) $ch;
					$map[$key] = array($k, $request['callback']);
					curl_multi_exec($master, $running);
				}

				// remove the curl handle that just completed
				curl_multi_remove_handle($master, $done['handle']);
			}

			// Block for data in / output; error handling is done by curl_multi_exec
			if ($running) {
				curl_multi_select($master, 10);
			}

		} while ($running);

		return $responses;
	}

	private static function bulid_request_header($headers, &$cookies) {
		if (is_array($headers)) {
			$headers = join(PHP_EOL, $headers);
		}
		if (is_array(self::$headers)) {
			self::$headers = join(PHP_EOL, self::$headers);
		}
		$headers = self::$headers.PHP_EOL .$headers;

		foreach (explode(PHP_EOL, $headers) as $k => $v) {
			@list($k, $v) = explode(':', $v, 2);
			if (empty($k) || empty($v)) {
				continue;
			}
			$k = implode('-', array_map('ucfirst', explode('-', $k)));
			$tmp[$k] = $v;
		}

		foreach ((array) $tmp as $k => $v) {
			if ($k == 'Cookie') {
				$cookies = $v;
			} else {
				$return[] = $k . ':' . $v;
			}
		}
		return (array) $return;
	}

	public static function iconv(&$raw, $content_type) {
		@list($tmp, $charset) = explode('CHARSET=', strtoupper($content_type));

		if (empty($charset) && stripos($content_type, 'html') > 0) {
			preg_match('@\<meta.+?charset=([\w]+)[\'|\"]@i', $raw, $matches);
			$charset = empty($matches[1]) ? null : $matches[1];
		}

		return empty($charset) ? $raw : iconv($charset, "UTF-8//IGNORE", $raw);
	}

	public static function get_respone_cookies($raw) {
		$cookies = array();
		if(strpos($raw, PHP_EOL) != false){
		    $lines = explode(PHP_EOL, $raw);
		}elseif(strpos($raw, "\r\n") != false){
		    $lines = explode("\r\n", $raw);
		}elseif(strpos($raw, '\r\n') != false){
		    $lines = explode('\r\n', $raw);
		}
		
		foreach ((array)$lines as $line) {
			if (substr($line, 0, 11) == 'Set-Cookie:') {
				list($k, $v) = explode('=', substr($line, 11), 2);
				list($v, $tmp) = explode(';', $v);
				$cookies[trim($k)] = trim($v);
			}
		}
		return $cookies;
	}

	public static function cookies_arr2str($arr) {
		$str = "";
		foreach ((array) $arr as $k => $v) {
			$str .= $k . "=" . $v . "; ";
		}
		return $str;
	}
}

================================================
FILE: lib/onedrive.php
================================================
<?php
	class onedrive{
		static $client_id;
		static $client_secret;
		static $redirect_uri;
		//国际版
		static $api_url = 'https://graph.microsoft.com/v1.0';
		static $oauth_url = 'https://login.microsoftonline.com/common/oauth2/v2.0';
		//世纪互联版
		// static $api_url = "https://microsoftgraph.chinacloudapi.cn/v1.0";
		// static $oauth_url = "https://login.partner.microsoftonline.cn/common/oauth2/v2.0";

		//验证URL,浏览器访问、授权
		static function authorize_url(){
			$client_id = self::$client_id;
			$scope = urlencode("offline_access files.readwrite.all");
			$redirect_uri = self::$redirect_uri;
			$url = self::$oauth_url."/authorize?client_id={$client_id}&scope={$scope}&response_type=code&redirect_uri={$redirect_uri}";
			
			if($_SERVER['HTTP_HOST'] != 'localhost'){
				$url .= '&state='.urlencode('http://'.$_SERVER['HTTP_HOST'].get_absolute_path(dirname($_SERVER['PHP_SELF'])));
			}
			
			return $url;
		}

		//使用 $code, 获取 $refresh_token
		static function authorize($code = ""){
			$client_id = self::$client_id;
			$client_secret = self::$client_secret;
			$redirect_uri = self::$redirect_uri;

			$url = self::$oauth_url."/token";
			$post_data = "client_id={$client_id}&redirect_uri={$redirect_uri}&client_secret={$client_secret}&code={$code}&grant_type=authorization_code";
			fetch::$headers = "Content-Type: application/x-www-form-urlencoded";
			$resp = fetch::post($url, $post_data);
			$data = json_decode($resp->content, true);
			return $data;
		}

		//使用 $refresh_token,获取 $access_token
		static function get_token($refresh_token){
			$client_id = self::$client_id;
			$client_secret = self::$client_secret;
			$redirect_uri = self::$redirect_uri;

			$request['url'] = self::$oauth_url."/token";
			$request['post_data']  = "client_id={$client_id}&redirect_uri={$redirect_uri}&client_secret={$client_secret}&refresh_token={$refresh_token}&grant_type=refresh_token";
			$request['headers']= "Content-Type: application/x-www-form-urlencoded";
			$resp = fetch::post($request);
			$data = json_decode($resp->content, true);
			return $data;
		}

		//获取 $access_token, 带缓存
		static function access_token(){
			$token = config('@token');
			if($token['expires_on'] > time()+600){
				return $token['access_token'];
			}else{
            			if (empty($token) || empty($token['refresh_token'])) {
                			$refresh_token = config('refresh_token');
            			} else {
                			$refresh_token = $token['refresh_token'];
            			}
				$token = self::get_token($refresh_token);
				if(!empty($token['refresh_token'])){
					$token['expires_on'] = time()+ $token['expires_in'];
					config('@token', $token);
					return $token['access_token'];
				}
			}
			return "";
		}


		// 生成一个request,带token
		static function request($path="/", $query=""){
			$path = self::urlencode($path);
			$path = empty($path)?'/':":/{$path}:/";
			$token = self::access_token();
			$request['headers'] = "Authorization: bearer {$token}".PHP_EOL."Content-Type: application/json".PHP_EOL;
			$request['url'] = self::$api_url."/me/drive/root".$path.$query;
			return $request;
		}

		
		//返回目录信息
		static function dir($path="/"){
			$request = self::request($path, 'children?select=name,size,folder,lastModifiedDateTime,id,@microsoft.graph.downloadUrl');
			$items = array();
			self::dir_next_page($request, $items);
			//不在列表显示的文件夹
			$hide_list = explode(PHP_EOL,config('onedrive_hide'));
			if(is_array($hide_list) && count($hide_list)>0){
				foreach($hide_list as $hide_dir){
					foreach($items as $key=>$_array){
						$buf = trim($hide_dir);
						if($buf && stristr($key, $buf))unset($items[$key]);
					}
				}
			}
			return $items;
		}

		//通过分页获取页面所有item
		static function dir_next_page($request, &$items, $retry=0){
			$resp = fetch::get($request);
			
			$data = json_decode($resp->content, true);
			if(empty($data) && $retry < 3){
				$retry += 1;
				return self::dir_next_page($request, $items, $retry);
			}
			
			foreach((array)$data['value'] as $item){
				//var_dump($item);
				$items[$item['name']] = array(
					'name'=>$item['name'],
					'id' => $item['id'],
					'size'=>$item['size'],
					'lastModifiedDateTime'=>strtotime($item['lastModifiedDateTime']),
					'downloadUrl'=>$item['@microsoft.graph.downloadUrl'],
					'folder'=>empty($item['folder'])?false:true
				);
			}

			if(!empty($data['@odata.nextLink'])){
				$request = self::request();
				$request['url'] = $data['@odata.nextLink'];
				return self::dir_next_page($request, $items);
			}
		}
	
		//关键字搜索
		static function search($keyword){
			$token = self::access_token();
			$keyword=self::urlencode($keyword);
			$request['headers'] = "Authorization: bearer {$token}".PHP_EOL."Content-Type: application/json".PHP_EOL;
			$request['url'] = self::$api_url."/me/drive/root/search(q='".$keyword."')";
			$resp=fetch::get($request);
			$data = json_decode($resp->content, true);

			foreach((array)$data['value'] as $item){
				//var_dump($item);
				$path = self::id2path($item['id']);
				$items[$item['name']] = array(
					'name'=>$item['name'],
					'id' => $item['id'],
					'size'=>$item['size'],
					'lastModifiedDateTime'=>strtotime($item['lastModifiedDateTime']),
					'folder'=>empty($item['folder'])?false:true,
					'path'=>$path
				);
			}
			return $items;
		}

		//文件缩略图链接
		static function thumbnail($path,$size='large'){
			$request = self::request($path,"thumbnails/0?select={$size}");
			$resp = fetch::get($request);
			$data = json_decode($resp->content, true);
			$request = self::request($path,"thumbnails/0?select={$size}");
			return @$data[$size]['url'];
		}

		static function share($path){
			$request = self::request($path,"createLink");
			$post_data['type'] = 'view';
			$post_data['scope'] = 'anonymous';
			$resp = fetch::post($request, json_encode($post_data));
			$data = json_decode($resp->content, true);
			return $data;
		}

		//文件上传函数
		static function upload($path,$content){
			$request = self::request($path,"content");
			$request['post_data'] = $content;
			$resp = fetch::put($request);
			$data = @json_decode($resp->content, true);
			return $data;
		}
		//url上传
		static function upload_url($path, $url){
			$request = self::request(get_absolute_path(dirname($path)),"children");
			$request['headers'] .= "Prefer: respond-async".PHP_EOL;
			$post_data['@microsoft.graph.sourceUrl'] = $url;
			$post_data['name'] = pathinfo($path, PATHINFO_BASENAME );
			$post_data['file'] = json_decode("{}");
			$request['post_data'] = json_encode($post_data);
			$resp = fetch::post($request);
			list($tmp, $location) = explode('Location:', $resp->headers);
			list($location, $tmp) = explode(PHP_EOL, $location);
			// return $resp;
			return trim($location);
		}
		
		static function create_upload_session($path){
			$request = self::request($path, 'createUploadSession');
			$request['post_data'] = '{"item": {"@microsoft.graph.conflictBehavior": "fail"}}';
			$token = self::access_token();
			$resp = fetch::post($request);
			$data = json_decode($resp->content, true);
			if($resp->http_code == 409){
				return false;
			}
			return $data;
		}

		static function upload_session($url, $file, $offset, $length=10240){
			$token = self::access_token();
			$file_size = self::_filesize($file);
			$content_length = (($offset+$length)>$file_size)?($file_size-$offset):$length;
			$end = $offset+$content_length-1;
			$post_data = self::file_content($file, $offset, $length);

			$request['url'] = $url;
			$request['curl_opt']=[CURLOPT_TIMEOUT=>360];
			$request['headers'] = "Authorization: bearer {$token}".PHP_EOL;
			$request['headers'] .= "Content-Length: {$content_length}".PHP_EOL;
			$request['headers'] .= "Content-Range: bytes {$offset}-{$end}/{$file_size}";
			$request['post_data'] = $post_data;
			$resp = fetch::put($request);
			$data = json_decode($resp->content, true);
			return $data;
		}

		static function upload_session_status($url){
			$token = self::access_token();
			fetch::$headers = "Authorization: bearer {$token}".PHP_EOL."Content-Type: application/json".PHP_EOL;
			$resp = fetch::get($url);
			$data = json_decode($resp->content, true);
			return $data;
		}

		static function delete_upload_session($url){
			$token = self::access_token();
			fetch::$headers = "Authorization: bearer {$token}".PHP_EOL."Content-Type: application/json".PHP_EOL;
			$resp = fetch::delete($url);
			$data = json_decode($resp->content, true);
			return $data;
		}

		static function file_content($file, $offset, $length){
			$handler = fopen($file, "rb") OR die('获取文件内容失败');
			fseek($handler, $offset);
			
			return fread($handler, $length);
		}

		static function human_filesize($size, $precision = 1) {
			for($i = 0; ($size / 1024) > 1; $i++, $size /= 1024) {}
			return round($size, $precision).(['B','KB','MB','GB','TB','PB','EB','ZB','YB'][$i]);
		}

		static function urlencode($path){
			foreach(explode('/', $path) as $k=>$v){
				if(empty(!$v)){
					$paths[] = rawurlencode($v);
				}
			}
			return @join('/',$paths);
		}
			
		static function _filesize($path){
		    if (!file_exists($path))
		        return false;
		    $size = filesize($path);
		    
		    if (!($file = fopen($path, 'rb')))
		        return false;
		    
		    if ($size >= 0){//Check if it really is a small file (< 2 GB)
		        if (fseek($file, 0, SEEK_END) === 0){//It really is a small file
		            fclose($file);
		            return $size;
		        }
		    }
		    
		    //Quickly jump the first 2 GB with fseek. After that fseek is not working on 32 bit php (it uses int internally)
		    $size = PHP_INT_MAX - 1;
		    if (fseek($file, PHP_INT_MAX - 1) !== 0){
		        fclose($file);
		        return false;
		    }
		    
		    $length = 1024 * 1024;
		    while (!feof($file)){//Read the file until end
		        $read = fread($file, $length);
		        $size = bcadd($size, $length);
		    }
		    $size = bcsub($size, $length);
		    $size = bcadd($size, strlen($read));
		    
		    fclose($file);
		    return $size;
		}

		//新建文件夹
		public static function create_folder($path = '/', $name = '新建文件夹')
		{
			$path = self::urlencode($path);
			$path = empty($path) ? '/' : ":/{$path}:/";
			$api = self::$api_url."/me/drive/root".$path.'/children';
			$token = self::access_token();
			$curl = curl_init();
			curl_setopt_array($curl, array(
				CURLOPT_URL => $api,
				CURLOPT_RETURNTRANSFER => true,
				CURLOPT_ENCODING => '',
				CURLOPT_MAXREDIRS => 10,
				CURLOPT_TIMEOUT => 0,
				CURLOPT_FOLLOWLOCATION => true,
				CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
				CURLOPT_CUSTOMREQUEST => 'POST',
				CURLOPT_POSTFIELDS => "{\n  \"name\": \"".$name."\",\n  \"folder\": { },\n  \"@microsoft.graph.conflictBehavior\": \"rename\"\n}",
				CURLOPT_HTTPHEADER => array(
					'Authorization: Bearer '.$token.'',
					'Content-Type: application/json',
				),
			));
	
			$response = curl_exec($curl);
	
			curl_close($curl);
			return $response;
		}

		//文件重命名
		public static function rename($itemid, $name)
		{
			$token = self::access_token();
			$api = str_replace('root', 'items/'.$itemid, self::$api_url."/me/drive/root");
			$curl = curl_init();
			curl_setopt_array($curl, array(
				CURLOPT_URL => $api,
				CURLOPT_RETURNTRANSFER => true,
				CURLOPT_ENCODING => '',
				CURLOPT_MAXREDIRS => 10,
				CURLOPT_TIMEOUT => 0,
				CURLOPT_FOLLOWLOCATION => true,
				CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
				CURLOPT_CUSTOMREQUEST => 'PATCH',
				CURLOPT_POSTFIELDS => "{\n  \"name\": \"".$name."\"\n}",
				CURLOPT_HTTPHEADER => array(
					'Authorization: Bearer '.$token,
					'Content-Type: application/json',
				),
			));
			$response = curl_exec($curl);
			curl_close($curl);
			return $response;
		}
		
		  //文件删除
		  public static function delete($itemid = array())
		  {
			  $access_token = self::access_token();
			  $apie = str_replace('root', 'items/', self::$api_url."/me/drive/root");
			  $apis = array();
			  for ($i = 0; $i < count($itemid); ++$i) {
				  $apis[$i] = $apie.$itemid[$i];
			  }
			  $result = $res = $ch = array();
			  $nch = 0;
			  $mh = curl_multi_init();
			  foreach ($apis as $nk => $url) {
				  $timeout = 20;
				  $ch[$nch] = curl_init();
				  curl_setopt_array($ch[$nch], array(
					  CURLOPT_URL => $url,
					  CURLOPT_TIMEOUT => $timeout,
					  CURLOPT_RETURNTRANSFER => true,
					  CURLOPT_MAXREDIRS => 10,
					  CURLOPT_FOLLOWLOCATION => true,
					  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
					  CURLOPT_CUSTOMREQUEST => 'DELETE',
					  CURLOPT_HTTPHEADER => array(
						  'Authorization: Bearer '.$access_token,
						  'Content-Type: application/json',
					  ),
				  ));
	  
				  curl_multi_add_handle($mh, $ch[$nch]);
				  ++$nch;
			  }
	  
			  /* wait for performing request */
	  
			  do {
				  $mrc = curl_multi_exec($mh, $running);
			  } while (CURLM_CALL_MULTI_PERFORM == $mrc);
	  
			  while ($running && $mrc == CURLM_OK) {
				  // wait for network
				  if (curl_multi_select($mh, 0.5) > -1) {
					  // pull in new data;
					  do {
						  $mrc = curl_multi_exec($mh, $running);
					  } while (CURLM_CALL_MULTI_PERFORM == $mrc);
				  }
			  }
	  
			  if ($mrc != CURLM_OK) {
				  error_log('CURL Data Error');
			  }
			  /* get data */
			  $nch = 0;
			  foreach ($apis as $moudle => $node) {
				  if (($err = curl_error($ch[$nch])) == '') {
					  $res[$nch] = curl_multi_getcontent($ch[$nch]);
					  $result[$moudle] = $res[$nch];
				  } else {
					  error_log('curl error');
				  }
				  curl_multi_remove_handle($mh, $ch[$nch]);
				  curl_close($ch[$nch]);
				  ++$nch;
			  }
			  curl_multi_close($mh);
			  return $result;
		  }
		  
		//文件批量移动
		public static function move($itemid = array(), $newitemid)
		{		
			// var_dump($itemid);
			$apis = array();
			$api = str_replace('root', 'items/', self::$api_url."/me/drive/root");
			for ($i = 0; $i < count($itemid); ++$i) {
				$apis[$i] = $api.$itemid[$i];
			}

		
			// $result = $res = $ch = array();
			$nch = 0;
			$mh = curl_multi_init();
			foreach ($apis as $nk => $url) {
				$timeout = 20;
				$ch[$nch] = curl_init();
				curl_setopt_array($ch[$nch], array(
					CURLOPT_URL => $url,
					CURLOPT_TIMEOUT => $timeout,
					CURLOPT_RETURNTRANSFER => true,
					CURLOPT_MAXREDIRS => 10,
					CURLOPT_FOLLOWLOCATION => true,
					CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
					CURLOPT_CUSTOMREQUEST => 'PATCH',
					CURLOPT_POSTFIELDS => "{\n  \"parentReference\": {\n    \"id\": \"".$newitemid."\"\n  }\n  \n}",
					CURLOPT_HTTPHEADER => array(
						'Authorization: Bearer '.self::access_token(),
						'Content-Type: application/json',
					),
				));

				curl_multi_add_handle($mh, $ch[$nch]);
				++$nch;
			}

			/* wait for performing request */

			do {
				$mrc = curl_multi_exec($mh, $running);
			} while (CURLM_CALL_MULTI_PERFORM == $mrc);

			while ($running && $mrc == CURLM_OK) {
				// wait for network
				if (curl_multi_select($mh, 0.5) > -1) {
					// pull in new data;
					do {
						$mrc = curl_multi_exec($mh, $running);
					} while (CURLM_CALL_MULTI_PERFORM == $mrc);
				}
			}

			if ($mrc != CURLM_OK) {
				error_log('CURL Data Error');
			}

			/* get data */

			$nch = 0;

			foreach ($apis as $moudle => $node) {
				if (($err = curl_error($ch[$nch])) == '') {
					$res[$nch] = curl_multi_getcontent($ch[$nch]);
					$result[$moudle] = $res[$nch];
				} else {
					error_log('curl error');
				}

				curl_multi_remove_handle($mh, $ch[$nch]);
				curl_close($ch[$nch]);
				++$nch;
			}

			curl_multi_close($mh);
			return $result;
		}

		 //文件批量复制
		 public static function copy($itemids=array(), $destitemid){
			
			$detail = self::detail($destitemid);
			$dvid = $detail['parentReference']['driveId'];//其driveid与其父项dvid相同
			$token = self::access_token();
			$request['headers'] = "Authorization: bearer {$token}".PHP_EOL."Content-Type: application/json".PHP_EOL;
			foreach($itemids as $index => $itemid){
				$itemdetail=self::detail($itemid);
				$request['url'] = self::$api_url."/me/drive/items/".$itemid.'/copy';
				$request['post_data'] = '{"parentReference": {"driveId": "'.$dvid.'","id": "'.$destitemid.'"},"name": "'.$itemdetail['name'].'"}';
				$resp[$index]=fetch::post($request);
			}
			return $resp;
		 }

		 //文件路径转itemid
		 public static function path2id($path)
		 {
			 $request = self::request(urldecode($path));
			 $access_token = self::access_token();
			 $request['headers'] = "Authorization: bearer {$access_token}".PHP_EOL.'Content-Type: application/json'.PHP_EOL;
			 $resp = fetch::get($request);
			 $data = json_decode($resp->content, true);
			 return $data['id'];
		 }

		 //itemid转文件路径,原理:移动项目到其本身所在文件夹,可以返回其路径信息
		 //itemid:待转item的id
		 //parentid:待转item父项id。
		 public static function id2path($itemid)
		 {
			$resp_json = self::detail($itemid);
			$totalpath=$resp_json['parentReference']['path'];
			$count=strpos($totalpath,"/drive/root:");
			$pathwithroot=substr_replace($totalpath,"",$count,strlen('/drive/root:'));
			$count2 = strpos($pathwithroot,chr(config('onedrive_path')));
			$path = config('root_path').'/'.substr_replace($pathwithroot,"",$count2,strlen(config('onedrive_root'))).'/';
			$path = str_replace("//",'/',$path).$resp_json['name'];
			return $path;
		 }

		 //itemid获取详细信息
		 public static function detail($itemid){
			$token = self::access_token();
			$request['headers'] = "Authorization: bearer {$token}".PHP_EOL."Content-Type: application/json".PHP_EOL;
			$request['url'] = self::$api_url."/me/drive/items/".$itemid;
			$resp = fetch::get($request);
			$data = json_decode($resp->content, true);
			return $data;
		 }

		
	}


================================================
FILE: lib/oneindex.php
================================================
<?php
	class oneindex{
		static $dir = array();
		static $file = array();
		static $thumb = array();

		//使用 $refresh_token,获取 $access_token
		static function get_token($refresh_token){
			
		}

		// 刷新缓存
		static function refresh_cache($path){
			set_time_limit(0);
			if( php_sapi_name() == "cli" ){
			   echo $path.PHP_EOL;
			}
			$items = onedrive::dir($path);
			if(is_array($items)){
				cache::set('dir_'.$path, $items, config('cache_expire_time') );
			}
			foreach((array)$items as $item){
			    if($item['folder']){
			        self::refresh_cache($path.$item['name'].'/');
			    }
			}
		}

		// 列目录
		static function dir($path = '/'){
			$path = self::get_absolute_path($path);

			if(!empty(self::$dir[$path])){
				return self::$dir[$path];
			} 
			
			self::$dir[$path] = cache::get('dir_'.$path, function() use ($path){
				return onedrive::dir($path);
			}, config('cache_expire_time'));
			return self::$dir[$path];
		}

		// 获取文件信息
		static function file($path){
			$path = self::get_absolute_path($path);
			$path_parts = pathinfo($path);
			$items = self::dir($path_parts['dirname']);
			if(!empty($items) && !empty($items[$path_parts['basename']])){
				return $items[$path_parts['basename']];
			}
		}

		
		// 文件是否存在
		static function file_exists($path){
			if(!empty(self::file($path))){
				return true;
			}
			return false;
		}

		//获取文件内容
		static function get_content($path){
			$item = self::file($path);
			// 仅小于10M 获取内容
			if(empty($item) OR $item['size'] > 10485760){
				return false;
			}

			return cache::get('content_'.$item['path'], function() use ($item){
				$resp = fetch::get($item['downloadUrl']);
				if($resp->http_code == 200){
					return $resp->content;
				}
			}, config('cache_expire_time') );
		}



		//缩略图
		static function thumb($path,$width=800,$height=800){
			$path = self::get_absolute_path($path);
			if(empty(self::$thumb[$path])){
				self::$thumb[$path] = cache::get('thumb_'.$path, function() use ($path){
					$url = onedrive::thumbnail($path);
					list($url,$tmp) = explode('&width=', $url);
					return $url;
				}, config('cache_expire_time'));
			}
			
			self::$thumb[$path] .= strpos(self::$thumb[$path], '?')?'&':'?';
			return self::$thumb[$path]."width={$width}&height={$height}";
		}

		//获取下载链接
		static function download_url($path){
			$item = self::file($path);
			if(!empty($item['downloadUrl'])){
				return $item['downloadUrl'];
			}
			return false;
		}

		static function web_url($path){
			$path = self::get_absolute_path($path);
			$path = rtrim($path, '/');

			if(!empty(config($path.'@weburl'))){
				return config($path.'@weburl');
			}else{
				$share = onedrive::share($path);
				if(!empty($share['link']['webUrl'])){
					config($path.'@weburl', $share['link']['webUrl']);
					return $share['link']['webUrl'];
				}
			}
		}

		static function direct_link($path){
			$web_url = self::web_url($path);
			if(!empty($web_url)){
				$arr = explode('/', $web_url);
				if( strpos($arr[2],'sharepoint.com') >0 ){
					$k = array_pop($arr);
					unset($arr[3]);
					unset($arr[4]);
					return join('/', $arr).'/_layouts/15/download.aspx?share='.$k;
				}elseif ( strpos($arr[2],'1drv.ms') >0 ){
					# code...
				}
			}
		}


		//工具函数获取绝对路径
		static function get_absolute_path($path) {
		    $path = str_replace(array('/', '\\', '//'), '/', $path);
		    $parts = array_filter(explode('/', $path), 'strlen');
		    $absolutes = array();
		    foreach ($parts as $part) {
		        if ('.' == $part) continue;
		        if ('..' == $part) {
		            array_pop($absolutes);
		        } else {
		            $absolutes[] = $part;
		        }
		    }
		    return str_replace('//','/','/'.implode('/', $absolutes).'/');
		}
	}


================================================
FILE: lib/route.php
================================================
<?php
class route {
	public static $uri;
	private static $method;
	private static $root = '/';
	static $runed = false;

	public static $patterns = array(
		'#any' => '[^/]+',
		'#num' => '[0-9]+',
		'#all' => '.*',
	);

	public static function __callstatic($method, $args) {
		if (self::$runed) {
			return;
		}

		if (empty(self::$method)) {
			self::init();
		}

		$method = strtoupper($method);
		if ($method != self::$method && !in_array($method, ['ANY', 'ERROR', 'ON'])) {
			return;
		}
		$pattern = trim(array_shift($args), '\/');
		$pattern = self::$root . $pattern;

		if (self::uri_match($pattern, self::$uri)) {
			if (is_string($args[0]) && strpos($args[0], '@') > 0) {
				list($class, $action) = explode('@', $args[0]);
				$object = new $class();
				$args[0] = array($object, $action);
			}

			$return = call_user_func($args[0]);
			if (is_array($return)) {
				print json_encode($return);
			} else {
				print (string) $return;
			}
			self::$runed = true;
		}
	}

	public static function init() {
		if (!empty(self::$method)) {return;}
		self::$uri = self::get_uri();
		self::$method = empty($_POST['_METHOD']) ? $_SERVER['REQUEST_METHOD'] : $_POST['_METHOD'];
		if (defined('CONTROLLER_PATH')) {
			spl_autoload_register(function ($class) {
				$file = CONTROLLER_PATH . $class . '.php';
				if (file_exists($file)) {
					include $file;
				}
			});
		}
	}

	public static function auto($controller_path) {
		self::init();
		$uri = self::get_uri();
		list($tmp, $controller, $action) = explode('/', $uri);
		$controller = empty($controller) ? 'IndexController' : ucfirst($controller) . 'Controller';
		$action = empty($action) ? 'index' : $action;
		$file = $controller_path . $controller . '.php';
		if (file_exists($file)) {
			include $file;
			if (is_callable(array($controller, $action))) {
				$obj = new $controller();
				print (string) $obj->$action();
				return;
			}
		}
	}

	public static function group($middleware, $callback){
		self::init();
		if (is_string($middleware) && strpos($middleware, '@') > 0) {
			list($class, $action) = explode('@', $middleware);
			$object = new $class();
			$result = $object->$action();
		}elseif(is_callable($middleware)){
			$result = $middleware();
		}

		if($result == true && is_callable($callback)){
			return $callback();
		}
	}

	public static function resource($name, $controller) {
		self::get('/' . $name, $controller . '@index');
		self::get('/' . $name . '/add', $controller . '@add');
		self::post('/' . $name, $controller . '@store');
		self::get('/' . $name . '/{id:#num}', $controller . '@show');
		self::get('/' . $name . '/{id:#num}/edit', $controller . '@edit');
		self::post('/' . $name . '/{id:#num}', $controller . '@update');
		self::get('/' . $name . '/{id:#num}/delete', $controller . '@delete');
	}

	public static function uri_match($pattern, $uri) {
		$pattern = ($pattern == '/') ? '/' : rtrim($pattern, '\/');

		$ps = explode('/', $pattern);

		$searches = array_keys(static::$patterns);
		$replaces = array_values(static::$patterns);

		foreach($ps as &$p){
				$p = str_replace($searches, $replaces, $p);
				$p = preg_replace("`\{(\w+)\:([^\)]+)\}`", '(?P<$1>$2)', $p);	
		}

		$pattern = join('/',$ps);

		if (preg_match("`^{$pattern}$`", $uri)) {
			preg_match_all("`^{$pattern}$`", $uri, $matches, PREG_PATTERN_ORDER);
			foreach ($matches as $key => $value) {
				if (!is_int($key)) {
					$_GET[$key] = $matches[$key][0];
				}
			}
			return true;
		}
	}

	public static function get_uri() {
		$file = basename($_SERVER['PHP_SELF']);
		$path = dirname($_SERVER['PHP_SELF']);
		$req_uri = $_SERVER['REQUEST_URI'];

		if ($path != '/' && strpos($req_uri, $path) === 0) {
			$req_uri = substr($req_uri, strlen($path));
		}

		if (strpos($req_uri, '/?/') === 0) {
			$req_uri = parse_url($req_uri, PHP_URL_QUERY);
			list($req_uri) = explode('&', $req_uri);
			unset($_GET[$req_uri]);
		}
		$uri = parse_url($req_uri, PHP_URL_PATH);
		return '/' . trim($uri, '\/');
	}
}

================================================
FILE: lib/sqlite.php
================================================
<?php

class sqlite implements \Countable
{
    /**
     * @var PDO
     */
    private $db = null;

    /**
     * @var string
     */
    private $name = null;

    public function __construct($name, $filename = "data.sqlite3")
    {
        $this->db = new PDO('sqlite:' . $filename);
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->name = $name;
        $this->createTable();
    }

    /**
     * @param string $key key
     *
     * @throws InvalidArgumentException
     * @return string|null
     */
    public function get($key)
    {
        if (!is_string($key)) {
            throw new InvalidArgumentException('Expected string as key');
        }

        $stmt = $this->db->prepare(
            'SELECT value FROM ' . $this->name . ' WHERE key = :key;'
        );
        $stmt->bindParam(':key', $key, PDO::PARAM_STR);
        $stmt->execute();

        if ($row = $stmt->fetch(PDO::FETCH_OBJ)) {
            return $row->value;
        }

        return null;
    }

    /**
     * @param string $key key
     * @param string $value value
     *
     * @throws InvalidArgumentException
     */
    public function set($key, $value)
    {
        if (!is_string($key)) {
            throw new InvalidArgumentException('Expected string as key');
        }

        $queryString = 'REPLACE INTO ' . $this->name . ' VALUES (:key, :value);';
        $stmt = $this->db->prepare($queryString);
        $stmt->bindParam(':key', $key, \PDO::PARAM_STR);
        $stmt->bindParam(':value', $value, \PDO::PARAM_STR);
        $stmt->execute();
    }

    /**
     * @param string $key key
     *
     * @return null
     */
    public function delete($key)
    {
        $stmt = $this->db->prepare(
            'DELETE FROM ' . $this->name . ' WHERE key = :key;'
        );
        $stmt->bindParam(':key', $key, \PDO::PARAM_STR);
        $stmt->execute();
    }

    /**
     * Delete all values from store
     *
     * @return null
     */
    public function deleteAll()
    {
        $stmt = $this->db->prepare('DELETE FROM ' . $this->name);
        $stmt->execute();
        $this->data = array();
    }

    /**
     * @return int
     */
    public function count()
    {
        return (int) $this->db->query('SELECT COUNT(*) FROM ' . $this->name)->fetchColumn();
    }

    /**
     * Create storage table in database if not exists
     *
     * @return null
     */
    private function createTable()
    {
        $stmt = 'CREATE TABLE IF NOT EXISTS "' . $this->name . '"';
        $stmt.= '(key TEXT PRIMARY KEY, value TEXT);';
        $this->db->exec($stmt);
    }
}


================================================
FILE: lib/view.php
================================================
<?php
!defined('VIEW_PATH') && define('VIEW_PATH', 'view/');
class view {
	private $_view = array('file' => '', 'data' => array());
	static $_pos = null;
    static $_section = null;

	static function load($file, $set = null) {
		if (is_int(strripos($file, '..'))) {
			die("error view file name:$file");
		}
		$file = str_replace('.', '/', $file);

		return new view($file, $set);
	}

	public function __construct($file, $set = null) {
		if (isset(self::$_pos)) {
			$this->_view['parent'] = self::$_pos;
			$this->with($this->_view['parent']->_view['data']);
		}
		$this->_view['file'] = $file;
		$this->with($set);
	}

	public function with($name, $value = NULL) {
		if (is_array($name)) {
			$this->_view['data'] = array_merge($this->_view['data'], $name);
		} elseif (is_string($name)) {
			$this->_view['data'][$name] = $value;
		}
		return $this;
	}

	public function __toString() {
		self::$_pos = $this;

		$this->_view['file'] = VIEW_PATH . $this->_view['file'] . '.php';
		if(!file_exists($this->_view['file'])){
			self::to404('404');
		}

		extract($this->_view['data']);

		ob_start();
		include $this->_view['file'];

		if (isset($this->_view['layout'])) {
			echo $this->_view['layout'] . ob_get_clean();
		}


		self::$_pos = isset($this->_view['parent']) ? $this->_view['parent'] : NULL;

		$return_str = ob_get_clean();

		return $return_str;
	}

	public function show() {
		echo $this;
	}

    
	static function layout($file) {
		ob_start();
		$view_layout = self::load($file);
		self::$_pos->_view['layout'] = $view_layout;
	}

	static function section($name) {
		if (isset(self::$_pos->_view['section'][$name])) {
			echo self::$_pos->_view['section'][$name];
		} elseif (isset(self::$_pos->_view['parent']->_view['section'][$name])) {
			echo self::$_pos->_view['parent']->_view['section'][$name];
		}
	}

	static function begin($name) {
        self::$_section = $name;
		ob_start();
	}

	static function end() {
		self::$_pos->_view['section'][self::$_section] = ob_get_clean();
        self::$_section = null;
	}

	static function direct($loction) {
		header("Location:$loction");
		exit();
	}

	static function abort() {
		header("HTTP/1.1 502 Bad Gateway");
		exit();
	}

	static function to404(){
		header("HTTP/1.1 404 Not Found");
		exit();
	}
}


================================================
FILE: one.php
================================================
<?php 
if( php_sapi_name() !== "cli" ){
   die( "NoAccess" );
}
require 'init.php';
ini_set('memory_limit', '128M');

class one{
	static function cache_clear(){
		cache::clear();
	}

	static function cache_refresh(){
		oneindex::refresh_cache(get_absolute_path(config('onedrive_root')));
	}

	static function token_refresh(){
		$refresh_token = config('refresh_token');
		$token = onedrive::get_token($refresh_token);
		if(!empty($token['refresh_token'])){
			config('@token', $token);
		}
	}

	static function upload_file($localfile, $remotefile=null){
		$localfile = realpath($localfile);
		if(!file_exists($localfile)){
			exit('file not exists');
		}
		print ' 本地文件:'.$localfile.PHP_EOL;

		if(empty($remotefile)){
			$remotepath = pathinfo($localfile, PATHINFO_BASENAME);
		}elseif(substr($remotefile, -1) == '/'){
			$remotepath = get_absolute_path($remotefile);
			$remotepath = substr($remotepath,1).pathinfo($localfile, PATHINFO_BASENAME);
		}else{
			$remotepath = ltrim($remotefile, '/');
		}
		print ' 远程文件:'.$remotepath.PHP_EOL;
		
		$filesize = onedrive::_filesize($localfile) OR die('无法获取文件大小');
		if($filesize < 10485760){
			print ' 上传方式:直接上传'.PHP_EOL;
			$begin_time = microtime(true);
			$result = onedrive::upload($remotepath, file_get_contents($localfile));
			if(!empty($result)){
				$upload_time = microtime(true) - $begin_time;
				print ' 上传成功:'.onedrive::human_filesize($filesize/$upload_time).'/s'.PHP_EOL;
			}else{
				print ' 上传失败!'.PHP_EOL;
			}
		}else{
			print ' 上传方式:分块上传'.PHP_EOL;
			return self::upload_large_file($localfile, $remotepath);
		}
		return;
	}
	
	static function upload_folder($localfolder, $remotefolder='/'){
		$localfolder = realpath($localfolder);
		$remotefolder = get_absolute_path($remotefolder);
		print ' 开始上传文件夹'.PHP_EOL;
		self::folder2upload($localfolder,$remotefolder);
	}

	static function folder2upload($localfolder, $remotefolder){
		$files = scandir($localfolder);
		foreach ($files as $file) {
			if ($file == '.' || $file == '..') {
				continue;
			}
			if (is_dir($localfolder . '/' . $file)) {
		        self::folder2upload($localfolder . '/' . $file, $remotefolder.$file.'/');
		    }else{
			    $localfile = realpath($localfolder . '/' . $file);
			    $remotefile = $remotefolder.$file;
			    self::upload_file($localfile, $remotefile);
		    }
		}
	}

	//static function add2uploading($path,$remotefolder) {
	//  $files = scandir($path);
	//  foreach ($files as $file) {
	//    if ($file != '.' && $file != '..') {
	//      if (is_dir($path . '/' . $file)) {
	//        self::add2uploading($path . '/' . $file, $remotefolder.$file.'/');
	//      } else {
	//	    $localfile = realpath($path . '/' . $file);
	//	    echo $localfile.PHP_EOL;
	//	    $remotepath = $remotefolder.$file;
	//        $task = array(
	//			'localfile'=>$localfile,
	//			'remotepath' => $remotepath,
	//			'filesize'=>onedrive::_filesize($localfile),
	//			'update_time'=>0
	//        );
	//        $uploads = config('@upload');
	//        if(empty($uploads[$remotepath])){
	//	        $uploads[$remotepath] = $task;
	//	        config('@upload', $uploads);
	//        }
	//      }
	//    }
	//  }
	//}


	static function upload_large_file($localfile, $remotepath){
		fetch::init([CURLOPT_TIMEOUT=>200]);
		$upload = config('@upload');
		$info = $upload[$remotepath];
		if(empty($info['url'])){
			print ' 创建上传会话'.PHP_EOL;
			$data = onedrive::create_upload_session($remotepath);
			if(!empty($data['uploadUrl'])){
				$info['url'] = $data['uploadUrl'];
				$info['localfile'] = $localfile;
				$info['remotepath'] = $remotepath;
				$info['filesize'] = onedrive::_filesize($localfile);
				$info['offset'] = 0;
				$info['length'] = 327680;
				$info['update_time'] = time();
				$upload[$remotepath] = $info;
				config('@upload', $upload);
			}elseif ( $data === false ){
				print ' 文件已存在!'.PHP_EOL;
				return;
			}
		}
		
		if(empty($info['url'])){
			print ' 获取会话失败!'.PHP_EOL;
			sleep(3);
			return self::upload_large_file($localfile, $remotepath);
		}
		
		print ' 上传分块'.onedrive::human_filesize($info['length']).'	';
		$begin_time = microtime(true);
		$data = onedrive::upload_session($info['url'], $info['localfile'], $info['offset'], $info['length']);

		if(!empty($data['nextExpectedRanges'])){
			$upload_time = microtime(true) - $begin_time;
			$info['speed'] = $info['length']/$upload_time;
			
			print onedrive::human_filesize($info['speed']).'/s'.'	'.round(($info['offset']/$info['filesize'])*100).'%	'.PHP_EOL;
			$info['length'] = intval($info['length']/$upload_time/32768*2)*327680;
			$info['length'] = ($info['length']>104857600)?104857600:$info['length'];
			
			list($offset, $filesize) = explode('-',$data['nextExpectedRanges'][0]);
			$info['offset'] = $offset;
			$info['update_time'] = time();
			$upload[$remotepath] = $info;
			config('@upload', $upload);
		}elseif(!empty($data['@content.downloadUrl']) || !empty($data['id'])){
			unset($upload[$remotepath]);
			config('@upload', $upload);
			print ' 上传完成!'.PHP_EOL;
			return;
		}else{
			print ' 失败!'.PHP_EOL;
			$data = onedrive::upload_session_status($info['url']);
			if(empty($data)|| $info['length']<100){
				onedrive::delete_upload_session($info['url']);
				unset($upload[$remotepath]);
				config('@upload', $upload);
			}elseif(!empty($data['nextExpectedRanges'])){
				list($offset, $filesize) = explode('-',$data['nextExpectedRanges'][0]);
				$info['offset'] = $offset;
				$info['length'] = $info['length']/1.5;
				$upload[$remotepath] = $info;
				config('@upload', $upload);
			}
		}

		return self::upload_large_file($localfile, $remotepath);
		
	}

	
}


array_shift($argv);
$action = str_replace(':', '_',array_shift($argv));

if(is_callable(['one',$action])){
	@call_user_func_array(['one',$action], $argv);
	exit();
}
?>
oneindex commands :
 cache
  cache:clear    	clear cache
  cache:refresh  	refresh cache
 token
  token:refresh  	refresh token
 upload
  upload:file  		upload a file to onedrive
  upload:folder  	upload a folder to onedrive


================================================
FILE: statics/common/offline/css/main.css
================================================
/* 
 * Copyright (C) 2015 Binux <roy@binux.me>
 *
 * This file is part of YAAW (https://github.com/binux/yaaw).
 *
 * YAAW is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * YAAW is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You may get a copy of the GNU Lesser General Public License
 * from http://www.gnu.org/licenses/lgpl.txt
 *
 */

.select-box {
    cursor: pointer;
    user-select: none;
    -moz-user-select: none;
}
.btn-inline {
    /* fix for MAC/chrome */
    display: inline !important;
}
.btn-inline:before, .btn-inline:after {
    /* fix for IE8 */
    content: none !important;
    display: none !important;
}

/* header */
.main-head {
    position: relative;
}
.main-head h1 {
    display: inline-block;
}

#main-alert {
    position: absolute;
    left: 0;
    width: 100%;
    text-align: center;
}
#main-alert-inline {
    display: inline-block;
    text-align: left;
    position: relative;
    top: -10px;
    z-index: 99;
}

#global-info {
    position: absolute;
    bottom: 0;
    right: 0;
}
#global-version {
    text-align: right;
}

/* main-control */
#main-control {
    margin-top: 10px;
}

#select-btn {
    margin-right: 30px;
}
.select-box {
    display: inline-block;
    vertical-align: text-top;
    border: 1px solid #C6C6C6;
    border: 1px solid rgba(155, 155, 155, .57);
    width: 14px;
    height: 14px;
    line-height: 14px;
}

#do-all-btn {
    position: relative;
    margin-left: 10px;
}

#info-btn {
    margin-left: 10px;
}

#other-grp {
}

/* active-tasks */
#active-tasks {
    margin-top: 40px;
}
.empty-tasks {
    text-align: center;
    padding: 8px;
}
.section-header {
    font-size: 16px;
}
.section-header i {
    margin-right: 5px;
    vertical-align: baseline;
}

/* other-tasks */
#other-tasks {
    margin-top: 40px;
}
#waiting-tasks-table {
    margin-bottom: 0;
}
#stopped-tasks-table {
    border-top: 0;
    margin-top: 0;
}

/* tasks */
.tasks-table {
    margin: 0;
    margin-top: 10px;
}

.task.selected {
    background-color: #F9F9F9;
}
.tasks-table > li {
    display: block;
    position: relative;
    margin-top: -1px;
    border-top: 1px solid #DDD;
    border-bottom: 1px solid #DDD;
    line-height: 18px;
    text-align: left;
    vertical-align: top;
}
.tasks-table > li:hover {
    background-color: #f5f5f5;
}

.left-area {
    position: relative;
    padding: 8px;
}
.right-area {
    position: absolute;
    top: 0;
    right: 0;
    padding: 8px;
}

.task .task-name {
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.task .task-name span {
    word-break: break-all;
    margin-left: 3px;
    font-size: 18px;
    font-weight: bold;
}

.task .task-name .select-box {
    vertical-align: -15%;
}
.task:hover .select-box {
    border-color: #666;
}

.task .task-info span {
    margin-right: 8px;
}

.task .task-info,
.task .progress-info {
    margin-top: 4px;
}
.task .progress {
    margin: 1px 0;
}

.task .download-speed,
.task .upload-speed,
.task .seeders {
    margin-right: 8px;
}

#other-tasks .task-info {
    margin: 0;
    overflow: hidden;
    white-space: nowrap;
}

@media (max-height: 600px) {
    .modal.fade.in {
        position: absolute;
        top: 260px;
    }
}

@media (max-width: 550px) {
    .modal.fade.in {
        top: 60px;
    }
    .modal-body {
        max-height: none;
    }

    #main-alert {
        top: 25px;
    }

    #offline-cached {
        display: none;
    }

    #select-btn {
        margin-right: 10px;
    }
    #not-selected-grp {
        float: right;
    }
    #selected-grp {
        float: right;
    }
    #other-grp {
        clear: both;
        margin-top: 5px;
    }

    #active-tasks {
        margin-top: 20px;
    }
    #active-tasks .left-area {
        padding-bottom: 0;
        margin-right: 0;
    }
    .task .task-name {
        margin-right: 0;
        overflow: visible;
        white-space: normal;
    }
    #active-tasks .right-area {
        padding-top: 0;
        position: relative;
        width: auto;
    }

    #other-tasks .left-area {
        margin-right: 0;
    }
    #other-tasks .right-area {
        position: relative;
        padding-top: 0;
    }
    #other-tasks .right-area .task-info {
        position: absolute;
        top: 0;
        left: 0;
    }
    #other-tasks .right-area .pull-right {
        width: 100%;
    }
    #other-tasks .right-area .pull-right .progress {
        margin-left: 110px;
    }
}
@media (min-width: 551px) and (max-width: 980px) {
    #active-tasks .left-area {
        margin-right: 186px;
    }
    #active-tasks .right-area {
        width: 170px;
    }

    #other-tasks .left-area {
        margin-right: 246px;
    }
    #other-tasks .right-area {
        width: 230px;
    }
    #other-tasks .task-info {
        width: 120px;
    }
    #other-tasks .progress {
        width: 100px;
    }
}
@media (min-width: 980px) {
    #active-tasks .left-area {
        margin-right: 286px;
    }
    #active-tasks .right-area {
        width: 270px;
    }

    #other-tasks .left-area {
        margin-right: 416px;
    }
    #other-tasks .right-area {
        width: 400px;
    }
    #other-tasks .task-info {
        width: 190px;
    }
    #other-tasks .progress {
        width: 200px;
    }
}

/* task infobox */
.info-open {
    background-color: #F9F9F9;
}
.info-box {
}
.info-box .tab-content {
    height: 300px;
    overflow-y: auto;
}
.info-box .nav {
    margin-top: -1px;
    margin-bottom: 0;
    height: 300px;
}
#ib-status,
#ib-options,
#ib-peers {
    position: relative;
    margin: 18px 0;
}
#ib-files .file-list {
    margin-left: -25px;
}
#ib-files ul,
#ib-options ul {
    margin-top: 5px;
}
#ib-files li {
    display: block;
    cursor: pointer;
    line-height: 14px;
    padding-bottom: 6px;
    vertical-align: top;
    border-bottom: 1px solid #FFF;
}
#ib-files .ib-file-title:hover {
    border-bottom: 1px solid #666;
}
#ib-file-btn,
#ib-options-btn {
    float: right !important;
    margin: 0 0 5px 5px;
}
@media (max-width: 980px) {
    #ib-file-btn, #ib-options-btn {
        float: none !important;
        margin-bottom: 5px;
    }
}
.ib-file-title {
    margin-left: 5px;
}
.ib-file-size {
    margin-left: 20px;
}
#ib-options li {
    display: block;
    float: left;
    padding-bottom: 6px;
    margin-right: 100px;
}
#ib-options li span {
    display: block;
    text-align: right;
    padding-right: 1em;
    width: 140px;
    line-height: 24px;
}
#ib-options li > * {
    float: left;
}
#ib-peers .ip_port {
    display: inline-block;
    width: 250px;
}

/* task-contextmenu */

#task-contextmenu {
    position: fixed;
    z-index: 99;
}

/* add task modal */
#add-task-modal {
    overflow-x: hidden;
}
#add-task-modal .modal-body.hover {
    padding: 13px;
    border: 2px solid #666;
}

#add-task-uri {
    text-align: center;
    white-space: nowrap;
    padding: 10px 19px;
    margin: 0;
    overflow: hidden;
}
#add-task-uri div {
    padding-right: 118px;
}
#uri-input {
    width: 100%; 
}
#uri-textarea {
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    width: 100%;
    margin: 0;
}

#uri-more {
    font-size: 7px;
    text-align: center;
    height: 10px;
    margin: 0 20px 20px;
    line-height: 10px;
    color: #DDD;
    background-color: whiteSmoke;
    cursor: pointer;
}
#uri-more:hover {
    background-color: #DDD;
    color: #999;
}

#torrent-up-input {
    position: absolute;
    top: 0;
    left: 0;
    text-align: right;
    height: 100%;
    width: 100%;
    -moz-opacity: 0;
    filter: alpha(opacity: 0);
    opacity: 0;
    z-index: 2;
    cursor: pointer;
}
#torrent-up-btn {
    position: relative;
}

#add-task-alert {
    position: relative;
    top: 5px;
}

#add-task-option {
    padding: 0 50px 0 20px;
}
@media (max-width: 480px) {
    #add-task-option {
        padding: 0 10px 0 20px;
    }
}
#add-task-option .controls {
    padding-right: 10px;
}
#add-task-option .input-xlarge {
    width: 100%;
}
#add-task-option .half {
    float: left;
    width: 220px;
}
#add-task-option .control-label {
    width: 70px;
}
#add-task-option .controls {
    margin-left: 85px;
}

/* aria2 global setting */
#copyright {
    margin-top: 10px;
    float: left;
}
#setting-form .rpc-path-group .controls {
    padding-right: 70px;
}
@media (max-width: 480px) {
    #setting-form .rpc-path-group .controls {
        padding-right: 35px;
    }
}
#setting-form .rpc-path-wrap {
    padding-right: 34px;
    width: 100%;
}
#setting-form .rpc-path-wrap .add-on {
    position: absolute;
    right: 1px;
}
#rpc-path {
  width: 100%;
  height: 28px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
}
#aria2-gs-form {
    margin-right: 30px;
}
@media (max-width: 480px) {
    #aria2-gs-form {
        margin-right: 0;
    }
}
#aria2-gs-form .controls {
    padding-right: 10px;
}
#aria2-gs-form .input-xlarge {
    width: 100%;
}
#aria2-gs-form .half {
    float: left;
    width: 240px;
    margin-left: 10px;
}
#aria2-gs-form .half .control-label {
    width: 110px;
}
#aria2-gs-form .half .controls {
    margin-left: 130px;
    padding-right: 0;
}

/* vim: set et sw=4 ts=4 sts=4 fdm=marker ff=unix fenc=utf8: */ 


================================================
FILE: statics/common/offline/js/aria2.js
================================================
/* 
 * Copyright (C) 2015 Binux <roy@binux.me>
 *
 * This file is part of YAAW (https://github.com/binux/yaaw).
 *
 * YAAW is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * YAAW is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You may get a copy of the GNU Lesser General Public License
 * from http://www.gnu.org/licenses/lgpl.txt
 *
 */

if (typeof ARIA2=="undefined"||!ARIA2) var ARIA2=(function(){
  var jsonrpc_interface, jsonrpc_protocol, jsonrpc_ws, interval_id, rpc_secret = null,
      unique_id = 0, ws_callback = {};
  var active_tasks_snapshot="", finished_tasks_list=undefined, tasks_cnt_snapshot="", select_lock=false, need_refresh=false;
  var auto_refresh=false;

  function get_error(result) {
    if (typeof result == "string")
      return result;
    else if (typeof result.error == "string")
      return result.error;
    else if (result.error && result.error.message)
      return result.error.message;
  }

  function default_error(result) {
    //console.debug(result);

    var error_msg = get_error(result);

    $("#main-alert .alert").attr("class", "alert alert-error");
    $("#main-alert .alert-msg").html("<strong>Error: </strong>"+error_msg);
    $("#main-alert").show();
  }

  function main_alert(_class, msg, timeout) {
    var msg_id = (new Date()).getTime();
    $("#main-alert .alert").attr("class", "alert "+_class);
    $("#main-alert .alert-msg").html(msg);
    $("#main-alert").data("msg_id", msg_id).show();
    if (timeout) {
      window.setTimeout(function() { 
        if($("#main-alert").data("msg_id") == msg_id) {
          $("#main-alert").fadeOut();
        }
      }, timeout);
    }
    return msg_id;
  }

  function bind_event(dom) {
    dom.find("[rel=tooltip]").tooltip({"placement": "bottom", trigger : 'hover'});
  }

  function get_title(result) {
    var dir = result.dir;
    var title = "Unknown";
    if (result.bittorrent && result.bittorrent.info && result.bittorrent.info.name)
      title = result.bittorrent.info.name;
    else if (result.files[0].path && result.files[0].path.replace(
      new RegExp("^"+dir.replace(/\\/g, "/").replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')+"/?"), "").split("/").length) {
      title = result.files[0].path.replace(new RegExp("^"+dir.replace(/\\/g, "/").replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')+"/?"), "").split("/");
      if (result.bittorrent)
        title = title[0];
      else
        title = title[title.length-1];
    } else if (result.files.length && result.files[0].uris.length && result.files[0].uris[0].uri)
      title = result.files[0].uris[0].uri;

    if (result.files.length > 1) {
      var cnt = 0;
      for (var i=0; i<result.files.length; i++) {
        if (result.files[i].selected == "true")
          cnt += 1;
      }
      if (cnt > 1)
        title += " ("+cnt+ " files..)"
    }
    return title;
  }

  function request_auth(url) {
    return url.match(/^(?:(?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(?:\/\/)?(?:([^:@]*(?::[^:@]*)?)?@)?/)[1];
  }
  function remove_auth(url) {
    return url.replace(/^((?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(\/\/)?(?:(?:[^:@]*(?::[^:@]*)?)?@)?(.*)/, '$1$2$3');
  }

  return {
    init: function(path, onready) {
      var connect_msg_id = main_alert("alert-info", "connecting...");
      $("#add-task-option-wrap").empty().append(YAAW.tpl.add_task_option({}));
      $("#aria2-gsetting").empty().append(YAAW.tpl.aria2_global_setting({}));

      jsonrpc_interface = path || location.protocol+"//"+(location.host.split(":")[0]||"localhost")+":6800"+"/jsonrpc";
      var auth_str = request_auth(jsonrpc_interface);
      if (auth_str && auth_str.indexOf('token:') == 0) {
        rpc_secret = auth_str;
        jsonrpc_interface = remove_auth(jsonrpc_interface);
      }

      if (jsonrpc_interface.indexOf("http") == 0) {
        jsonrpc_protocol = "http";
        $.jsonRPC.setup({endPoint: jsonrpc_interface, namespace: 'aria2'});
        ARIA2.request = ARIA2.request_http;
        ARIA2.batch_request = ARIA2.batch_request_http;
        if (onready) onready();
        if ($("#main-alert").data("msg_id") == connect_msg_id) {
          $("#main-alert").fadeOut();
        }
      } else if (jsonrpc_interface.indexOf("ws") == 0 && WebSocket) {
        jsonrpc_protocol = "ws"
        jsonrpc_ws = new WebSocket(jsonrpc_interface);
        jsonrpc_ws.onmessage = function(event) {
          var data = JSON.parse(event.data);
          //console.debug(data);
          if ($.isArray(data) && data.length) {
            var id = data[0].id;
            if (ws_callback[id]) {
              ws_callback[id].success(data);
              delete ws_callback[id];
            }
          } else {
            if (ws_callback[data.id]) {
              if (data.error)
                ws_callback[data.id].error(data);
              else
                ws_callback[data.id].success(data);
              delete ws_callback[data.id];
            };
          };
        };
        jsonrpc_ws.onerror = function(event) {
          console.warn("error", event);
          main_alert("alert-error", "websocket error. you may need reflush this page to restart.");
          ws_callback = {};
        };
        jsonrpc_ws.onopen = function() {
          ARIA2.request = ARIA2.request_ws;
          ARIA2.batch_request = ARIA2.batch_request_ws;
          if (onready) onready();
          if ($("#main-alert").data("msg_id") == connect_msg_id) {
            $("#main-alert").fadeOut();
          }
        };
      } else {
        main_alert("alert-error", "Unknown protocol");
      };
    },

    request: function(){},
    batch_request: function(){},

    request_http: function(method, params, success, error) {
      if (error == undefined)
        error = default_error;
      if (rpc_secret) {
        params = params || [];
        if (!$.isArray(params)) params = [params];
        params.unshift(rpc_secret);
      }
      $.jsonRPC.request(method, {params:params, success:success, error:error});
    },

    batch_request_http: function(method, params, success, error) {
      if (error == undefined)
        error = default_error;
      var commands = new Array();
      $.each(params, function(i, n) {
        n = n || [];
        if (!$.isArray(n)) n = [n];
        if (rpc_secret) {
          n.unshift(rpc_secret);
        }
        commands.push({method: method, params: n});
      });
      $.jsonRPC.batchRequest(commands, {success:success, error:error});
    },

    _request_data: function(method, params, id) {
      var dataObj = {
        jsonrpc: '2.0',
        method: 'aria2.'+method,
        id: id
      }
      if(typeof(params) !== 'undefined') {
        dataObj.params = params;
      }
      return dataObj;
    },

    _get_unique_id: function() {
      ++unique_id;
      return unique_id;
    },

    request_ws: function(method, params, success, error) {
      var id = ARIA2._get_unique_id();
      ws_callback[id] = {
        'success': success || function(){},
        'error': error || default_error,
      };
      if (rpc_secret) {
        params = params || [];
        if (!$.isArray(params)) params = [params];
        params.unshift(rpc_secret);
      }
      jsonrpc_ws.send(JSON.stringify(ARIA2._request_data(method, params, id)));
    },

    batch_request_ws: function(method, params, success, error) {
      var data = [];
      var id = ARIA2._get_unique_id();
      ws_callback[id] = {
        'success': success || function(){},
        'error': error || default_error,
      };
      for (var i=0,l=params.length; i<l; i++) {
        var n = params[i];
        n = n || [];
        if (!$.isArray(n)) n = [n];
        if (rpc_secret) {
          n.unshift(rpc_secret);
        }
        data.push(ARIA2._request_data(method, n, id))
      };
      jsonrpc_ws.send(JSON.stringify(data));
    },

    main_alert: main_alert,

    add_task: function(uri, options) {
      if (!uri) return false;
      if (!$.isArray(uri)) uri = [uri];
      if (!options) options = {};
      ARIA2.request("addUri", [uri, options],
        function(result) {
          //console.debug(result);
          ARIA2.refresh();
          $("#add-task-modal").modal('hide');
          YAAW.add_task.clean();
        }, 
        function(result) {
          //console.debug(result);

          var error_msg = get_error(result);

          $("#add-task-alert .alert-msg").text(error_msg);
          $("#add-task-alert").show();
          console.warn("add task error: "+error_msg);
        });
    },

    madd_task: function(uris, options) {
      if (!$.isArray(uris)) uris = [uris];
      var params = [];
      for (var i=0; i<uris.length; i++) {
        var uri = uris[i].trim();
        if (uri) params.push([[uri], options]);
      };
      ARIA2.batch_request("addUri", params,
        function(result) {
          //console.debug(result);

          var error = new Array();
          $.each(result, function(i, n) {
            var error_msg = get_error(n);
            if (error_msg) error.push(error_msg);
          });

          if (error.length == 0) {
            ARIA2.refresh();
            $("#add-task-modal").modal('hide');
            YAAW.add_task.clean();
          } else {
            var error_msg = error.join("<br />");
            $("#add-task-alert .alert-msg").html(error_msg);
            $("#add-task-alert").show();
            console.warn("add task error: "+error_msg);
          }
        }
      );
    },

    add_torrent: function(torrent, options) {
      if (!torrent) return false;
      if (!options) options = {};
      ARIA2.request("addTorrent", [torrent, [], options],
        function(result) {
          //console.debug(result);
          ARIA2.refresh();
          $("#add-task-modal").modal('hide');
          YAAW.add_task.clean();
        }, 
        function(result) {
          //console.debug(result);

          var error_msg = get_error(result);

          $("#add-task-alert .alert-msg").text(error_msg);
          $("#add-task-alert").show();
          console.warn("add task error: "+error_msg);
        });
    },

    add_metalink: function(metalink, options) {
      if (!metalink) return false;
      if (!options) options = {};
      ARIA2.request("addMetalink", [metalink, [], options],
        function(result) {
          //console.debug(result);
          ARIA2.refresh();
          $("#add-task-modal").modal('hide');
          YAAW.add_task.clean();
        }, 
        function(result) {
          //console.debug(result);

          var error_msg = get_error(result);

          $("#add-task-alert .alert-msg").text(error_msg);
          $("#add-task-alert").show();
          console.warn("add task error: "+error_msg);
        });
    },

    restart_task: function(gids) {
      if (!$.isArray(gids)) gids = [gids];
      $.each(gids, function(n, gid) {
        var result = $("#task-gid-"+gid).data("raw");
        var uris = [];
        $.each(result.files, function(n, e) {
          if (e.uris.length)
            uris.push(e.uris[0].uri);
        });
        if (result.bittorrent) {
          var magnet_link = "magnet:?xt=urn:btih:"+result.infoHash;
          if (result.bittorrent.info.name)
            magnet_link += "&dn="+result.bittorrent.info.name;
          if (result.bittorrent.announceList.length)
            magnet_link += "&tr="+result.bittorrent.announceList.join("&tr=");
          uris.push(magnet_link);
        }
        if (uris.length > 0) {
          ARIA2.request("getOption", [gid], function(result) {
            var options = result.result;
            ARIA2.madd_task(uris, options);
          });
        }
      });
    },

    tell_active: function(keys) {
      if (select_lock) return;
      ARIA2.request("tellActive", keys,
        function(result) {
          //console.debug(result);

          if (select_lock) return;
          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          }

          var snapshot = new Array();
          $.each(result.result, function(i, e) {
            snapshot.push(e.gid);
          });
          if (snapshot.sort().join(",") != active_tasks_snapshot) {
            active_tasks_snapshot = snapshot.sort().join(",");
            need_refresh = true;
            if (auto_refresh && !select_lock)
              ARIA2.refresh();
          }
        
          result = ARIA2.status_fix(result.result);
          $("#active-tasks-table").empty().append(YAAW.tpl.active_task({"tasks": result}));
          $.each(result, function(n, e) {
            $("#task-gid-"+e.gid).data("raw", e);
          });
          bind_event($("#active-tasks-table"))
        }
      );
    },

    check_active_list: function() {
      ARIA2.request("tellActive", [["gid"]],
        function(result) {
          //console.debug(result);

          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          }

          var snapshot = new Array();
          $.each(result.result, function(i, e) {
            snapshot.push(e.gid);
          });
          if (snapshot.sort().join(",") != active_tasks_snapshot) {
            active_tasks_snapshot = snapshot.sort().join(",");
            need_refresh = true;
            if (auto_refresh && !select_lock)
              ARIA2.refresh();
          }
        }
      );
    },

    tell_waiting: function(keys) {
      if (select_lock) return;
      var params = [0, 1000];
      if (keys) params.push(keys);
      ARIA2.request("tellWaiting", params,
        function(result) {
          if (select_lock) return;
          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          }

          result = ARIA2.status_fix(result.result);
          $("#waiting-tasks-table").empty().append(YAAW.tpl.other_task({"tasks": result}));
          $.each(result, function(n, e) {
            $("#task-gid-"+e.gid).data("raw", e);
          });
          bind_event($("#waiting-tasks-table"))

          if ($("#other-tasks .task").length == 0)
            $("#waiting-tasks-table").append($("#other-task-empty").text())
        }
      );
    },

    tell_stopped: function(keys) {
      if (select_lock) return;
      var params = [0, 1000];
      if (keys) params.push(keys);
      ARIA2.request("tellStopped", params,
        function(result) {
          //console.debug(result);
          if (select_lock) return;

          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          }

          result = ARIA2.status_fix(result.result);

          if (finished_tasks_list === undefined) {
            finished_tasks_list = new Array();
            $.each(result, function(i, e) {
              if (e.status != "complete")
                return;
              finished_tasks_list.push(e.gid);
            });
          } else {
            $.each(result, function(i, e) {
              if (e.status != "complete")
                return;
              if (finished_tasks_list.indexOf(e.gid) != -1)
                return;
              if (ARIA2.finish_notification) {
                YAAW.notification("Aria2 Task Finished", e.title);
              }
              finished_tasks_list.push(e.gid);
            });
          }

          $("#stopped-tasks-table").empty().append(YAAW.tpl.other_task({"tasks": result.reverse()}));
          $.each(result, function(n, e) {
            $("#task-gid-"+e.gid).data("raw", e);
          });
          bind_event($("#stopped-tasks-table"))

          if ($("#waiting-tasks-table .empty-tasks").length > 0 &&
            $("#stopped-tasks-table .task").length > 0) {
              $("#waiting-tasks-table").empty();
            }

        }
      );
    },

    status_fix: function(results) {
      for (var i=0; i<results.length; i++) {
        var result = results[i];

        result.title = get_title(result);
        if (result.totalLength == 0)
          result.progress = 0;
        else
          result.progress = (result.completedLength * 1.0 / result.totalLength * 100).toFixed(2);
        result.eta = (result.totalLength - result.completedLength)/result.downloadSpeed;

        result.progressStatus = {
          "active"  : "progress-striped",
          "complete": "progress-success",
          "removed" : "progress-warning",
          "error"   : "progress-danger"
        }[result.status];

        result.downloadSpeed = parseInt(result.downloadSpeed);
        result.uploadSpeed = parseInt(result.uploadSpeed);
        result.uploadLength = parseInt(result.uploadLength);
        result.completedLength = parseInt(result.completedLength);
        result.numSeeders = parseInt(result.numSeeders);
        result.connections = parseInt(result.connections);
      }
      return results;
    },

    change_pos: function(gid, pos, how) {
      ARIA2.request("changePosition", [gid, pos, how],
        function(result) {
          //console.debug(result);

          main_alert("alert-info", "Moved", 1000);
          ARIA2.refresh();
        }
      );
    },

    change_selected_pos: function(gids, pos, how) {
      var params = [];
      $.each(gids, function(i, n) {
        params.push([n, pos, how]);
      });
      ARIA2.batch_request("changePosition", params,
        function(result) {
          //console.debug(result);

          main_alert("alert-info", "Moved", 1000);
          ARIA2.refresh();
        }
      );
    },

    pause: function(gids) {
      if (!$.isArray(gids)) gids = [gids];
      ARIA2.batch_request("pause", gids,
        function(result) {
          //console.debug(result);

          var error = new Array();
          $.each(result, function(i, n) {
            var error_msg = get_error(n);
            if (error_msg) error.push(error_msg);
          });

          if (error.length == 0) {
            main_alert("alert-info", "Paused", 1000);
            ARIA2.refresh();
          } else {
            main_alert("alert-error", error.join("<br />"), 3000);
          }
        }
      );
    },

    unpause: function(gids) {
      if (!$.isArray(gids)) gids = [gids];
      ARIA2.batch_request("unpause", gids,
        function(result) {
          //console.debug(result);

          var error = new Array();
          $.each(result, function(i, n) {
            var error_msg = get_error(n);
            if (error_msg) error.push(error_msg);
          });

          if (error.length == 0) {
            main_alert("alert-info", "Started", 1000);
            ARIA2.refresh();
          } else {
            main_alert("alert-error", error.join("<br />"), 3000);
          }
        }
      );
    },

    remove: function(gids) {
      if (!$.isArray(gids)) gids = [gids];
      ARIA2.batch_request("remove", gids,
        function(result) {
          //console.debug(result);

          var error = new Array();
          $.each(result, function(i, n) {
            var error_msg = get_error(n);
            if (error_msg) error.push(error_msg);
          });

          if (error.length == 0) {
            main_alert("alert-info", "Removed", 1000);
            ARIA2.refresh();
          } else {
            main_alert("alert-error", error.join("<br />"), 3000);
          }
        }
      );
    },

    remove_result: function(gids) {
      if (!$.isArray(gids)) gids = [gids];
      ARIA2.batch_request("removeDownloadResult", gids,
        function(result) {
          //console.debug(result);

          var error = new Array();
          $.each(result, function(i, n) {
            var error_msg = get_error(n);
            if (error_msg) error.push(error_msg);
          });

          if (error.length == 0) {
            main_alert("alert-info", "Removed", 1000);
            ARIA2.tell_stopped();
          } else {
            main_alert("alert-error", error.join("<br />"), 3000);
          }
        }
      );
    },

    get_options: function(gid) {
      ARIA2.request("getOption", [gid],
        function(result) {
          //console.debug(result);

          $("#ib-options").empty().append(YAAW.tpl.ib_options(result.result));
          if ($("#task-gid-"+gid).attr("data-status") == "active")
            $("#ib-options-form *[name]:not(.active-allowed)").attr("disabled", true);
        }
      );
    },

    change_options: function(gid, options) {
      ARIA2.request("changeOption", [gid, options],
        function(result) {
          //console.debug(result);

          main_alert("alert-info", "option updated", 1000);
        }
      );
    },

    get_peers: function(gid) {
      ARIA2.request("getPeers", [gid],
        function(result) {
          console.debug(result);

          $("#ib-peers").empty().append(YAAW.tpl.ib_peers(result.result));
        }
      );
    },

    pause_all: function() {
      ARIA2.request("pauseAll", [],
        function(result) {
          //console.debug(result);

          ARIA2.refresh();
          main_alert("alert-info", "Paused all tasks. Please wait for action such as contacting BitTorrent tracker.", 2000);
        }
      );
    },

    unpause_all: function() {
      ARIA2.request("unpauseAll", [],
        function(result) {
          //console.debug(result);

          ARIA2.refresh();
          main_alert("alert-info", "Unpaused all tasks.", 2000);
        }
      );
    },

    purge_download_result: function() {
      ARIA2.request("purgeDownloadResult", [],
        function(result) {
          //console.debug(result);

          ARIA2.refresh();
          main_alert("alert-info", "Removed all completed/error/removed downloads tasks.", 2000);
        }
      );
    },

    get_global_option: function() {
      ARIA2.request("getGlobalOption", [],
        function(result) {
          if (!result.result)
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);

          result = result.result;
          $("#aria2-gsetting").empty().append(YAAW.tpl.aria2_global_setting(result));
        }
      );
    },

    init_add_task_option: function() {
      ARIA2.request("getGlobalOption", [],
        function(result) {
          if (!result.result)
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);

          result = result.result;
          result["parameterized-uri"] = (result["parameterized-uri"] == "true" ? true : false)
          $("#add-task-option-wrap").empty().append(YAAW.tpl.add_task_option(result));
        }
      );
    },

    change_global_option: function(options) {
      ARIA2.request("changeGlobalOption", [options],
        function(result) {
          if (!result.result)
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          else
            main_alert("alert-success", "Saved", 2000);
        }
      );
    },

    global_stat: function() {
      ARIA2.request("getGlobalStat", [],
        function(result) {
          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          }

          result = result.result;
          var _tasks_cnt_snapshot = ""+result.numActive+","+result.numWaiting+","+result.numStopped;

          if (_tasks_cnt_snapshot != tasks_cnt_snapshot) {
            tasks_cnt_snapshot = _tasks_cnt_snapshot;
            need_refresh = true;
            if (auto_refresh && !select_lock)
              ARIA2.refresh();
          }

          $("#global-speed").empty().append(YAAW.tpl.global_speed(result));
          var title = "↓"+YAAW.tpl.view.format_size_0()(result.downloadSpeed);
          if (result.uploadSpeed > 0)
            title += " ↑"+YAAW.tpl.view.format_size_0()(result.uploadSpeed);
          title += " - Yet Another Aria2 Web Frontend";
          document.title = title;
        }
      );
    },

    get_version: function() {
      ARIA2.request("getVersion", [],
        function(result) {
          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          }

          $("#global-version").text("Aria2 "+result.result.version || "");
        }
      );
    },

    get_status: function(gid) {
      ARIA2.request("tellStatus", [gid],
        function(result) {
          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          }

          result = result.result;
          result.uris = [];
          for (var i=0; i<result.files.length; i++) {
            var file = result.files[i];
            file.title = file.path.replace(new RegExp("^"+result.dir.replace(/\\/g, "[\\/]")+"/?"), "");
            file.selected = file.selected == "true" ? true : false;
            if (file.uris && file.uris.length) {
              for (var j=0; j<file.uris.length; j++) {
                var uri = file.uris[j].uri;
                if (result.uris.indexOf(uri) == -1) {
                  result.uris.push(uri);
                }
              }
            }
          };
          console.log(result.uris);
          $("#ib-status").empty().append(YAAW.tpl.ib_status(result));
          $("#ib-files .file-list").empty().append(YAAW.tpl.files_tree(result.files));
          if ($("#task-gid-"+gid).attr("data-status") == "active")
            $("#ib-file-save").hide();
          if (result.bittorrent) {
            $("#ib-peers-a").show();
          }
        }
      );
    },

    change_option: function(gid, options) {
      ARIA2.request("changeOption", [gid, options],
        function(result) {
          if (!result.result) {
            main_alert("alert-error", "<strong>Error: </strong>rpc result error.", 5000);
          } else {
            main_alert("alert-success", "Change Options OK!", 2000);
          }
        }
      );
    },

    /********************************************************/

    refresh: function() {
      if (!select_lock) {
        need_refresh = false;
        ARIA2.tell_active();
        ARIA2.tell_waiting();
        ARIA2.tell_stopped();
      }
    },

    select_lock: function (bool) {
      select_lock = bool;
    },

    auto_refresh: function(interval) {
      if (interval_id)
        window.clearInterval(interval_id);
      if (!(interval > 0)) {
        auto_refresh = false;
        return ;
      }
      interval_id = window.setInterval(function() {
        ARIA2.global_stat();
        if (select_lock) {
          if (need_refresh) {
            main_alert("", "Task list have changed since last update. Click 'Refresh' button to update task list.");
          }
        } else {
          if (need_refresh) {
            ARIA2.refresh();
          } else {
            ARIA2.tell_active();
          }
        }
      }, interval);
      auto_refresh = true;
    },

    finish_notification: 1,
  }
})();


================================================
FILE: statics/common/offline/js/jquery.Storage.js
================================================
/**
 * Storage plugin
 * Provides a simple interface for storing data such as user preferences.
 * Storage is useful for saving and retreiving data from the user's browser.
 * For newer browsers, localStorage is used.
 * If localStorage isn't supported, then cookies are used instead.
 * Retrievable data is limited to the same domain as this file.
 *
 * Usage:
 * This plugin extends jQuery by adding itself as a static method.
 * $.Storage - is the class name, which represents the user's data store, whether it's cookies or local storage.
 *             <code>if ($.Storage)</code> will tell you if the plugin is loaded.
 * $.Storage.set("name", "value") - Stores a named value in the data store.
 * $.Storage.set({"name1":"value1", "name2":"value2", etc}) - Stores multiple name/value pairs in the data store.
 * $.Storage.get("name") - Retrieves the value of the given name from the data store.
 * $.Storage.remove("name") - Permanently deletes the name/value pair from the data store.
 *
 * @author Dave Schindler
 *
 * Distributed under the MIT License
 *
 * Copyright (c) 2010 Dave Schindler
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
(function($) {
	// Private data
	var isLS=typeof window.localStorage!=='undefined';
	// Private functions
	function wls(n,v){var c;if(typeof n==="string"&&typeof v==="string"){localStorage[n]=v;return true;}else if(typeof n==="object"&&typeof v==="undefined"){for(c in n){if(n.hasOwnProperty(c)){localStorage[c]=n[c];}}return true;}return false;}
	function wc(n,v){var dt,e,c;dt=new Date();dt.setTime(dt.getTime()+31536000000);e="; expires="+dt.toGMTString();if(typeof n==="string"&&typeof v==="string"){document.cookie=n+"="+v+e+"; path=/";return true;}else if(typeof n==="object"&&typeof v==="undefined"){for(c in n) {if(n.hasOwnProperty(c)){document.cookie=c+"="+n[c]+e+"; path=/";}}return true;}return false;}
	function rls(n){return localStorage[n];}
	function rc(n){var nn, ca, i, c;nn=n+"=";ca=document.cookie.split(';');for(i=0;i<ca.length;i++){c=ca[i];while(c.charAt(0)===' '){c=c.substring(1,c.length);}if(c.indexOf(nn)===0){return c.substring(nn.length,c.length);}}return null;}
	function dls(n){return delete localStorage[n];}
	function dc(n){return wc(n,"",-1);}

	/**
	* Public API
	* $.Storage - Represents the user's data store, whether it's cookies or local storage.
	* $.Storage.set("name", "value") - Stores a named value in the data store.
	* $.Storage.set({"name1":"value1", "name2":"value2", etc}) - Stores multiple name/value pairs in the data store.
	* $.Storage.get("name") - Retrieves the value of the given name from the data store.
	* $.Storage.remove("name") - Permanently deletes the name/value pair from the data store.
	*/
	$.extend({
		Storage: {
			set: isLS ? wls : wc,
			get: isLS ? rls : rc,
			remove: isLS ? dls :dc
		}
	});
})(jQuery);

================================================
FILE: statics/common/offline/js/jquery.jsonrpc.js
================================================
(function($) {
  $.extend({
    jsonRPC: {
      // RPC Version Number
      version: '2.0',

      // End point URL, sets default in requests if not
      // specified with the request call
      endPoint: null,

      // Default namespace for methods
      namespace: null,

      /*
       * Provides the RPC client with an optional default endpoint and namespace
       *
       * @param {object} The params object which can contains
       *   {string} endPoint The default endpoint for RPC requests
       *   {string} namespace The default namespace for RPC requests
       */
      setup: function(params) {
        this._validateConfigParams(params);
        this.endPoint = params.endPoint;
        this.namespace = params.namespace;
        this.auth = this.endPoint.match(/^(?:(?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(?:\/\/)?(?:([^:@]*(?::[^:@]*)?)?@)?/)[1];
        return this;
      },

      /*
       * Convenience wrapper method to allow you to temporarily set a config parameter
       * (endPoint or namespace) and ensure it gets set back to what it was before
       *
       * @param {object} The params object which can contains
       *   {string} endPoint The default endpoint for RPC requests
       *   {string} namespace The default namespace for RPC requests
       * @param {function} callback The function to call with the new params in place
       */
      withOptions: function(params, callback) {
        this._validateConfigParams(params);
        // No point in running if there isn't a callback received to run
        if(typeof(callback) === 'undefined') throw("No callback specified");

        origParams = {endPoint: this.endPoint, namespace: this.namespace};
        this.setup(params);
        callback.call(this);
        this.setup(origParams);
      },

      /*
       * Performas a single RPC request
       *
       * @param {string} method The name of the rpc method to be called
       * @param {object} options A collection of object which can contains
       *  params {array} the params array to send along with the request
       *  success {function} a function that will be executed if the request succeeds
       *  error {function} a function that will be executed if the request fails
       *  url {string} the url to send the request to
       *  id {string} the provenance id for this request (defaults to 1)
       * @return {undefined}
       */
      request: function(method, options) {
        if(typeof(options) === 'undefined') {
          options = { id: 1 };
        }
        if (typeof(options.id) === 'undefined') {
          options.id = 1;
        }

        // Validate method arguments
        this._validateRequestMethod(method);
        this._validateRequestParams(options.params);
        this._validateRequestCallbacks(options.success, options.error);

        // Perform the actual request
        this._doRequest(JSON.stringify(this._requestDataObj(method, options.params, options.id)), options);

        return true;
      },

      /*
       * Submits multiple requests
       * Takes an array of objects that contain a method and params
       *
       * @params {array} requests an array of request object which can contain
       *  method {string} the name of the method
       *  param {object} the params object to be sent with the request
       *  id {string} the provenance id for the request (defaults to an incrementer starting at 1)
       * @param {object} options A collection of object which can contains
       *  success {function} a function that will be executed if the request succeeds
       *  error {function} a function that will be executed if the request fails
       *  url {string} the url to send the request to
       * @return {undefined}
       */
      batchRequest: function(requests, options) {
        if(typeof(options) === 'undefined') {
          options = {};
        }

        // Ensure our requests come in as an array
        if(!$.isArray(requests) || requests.length === 0) throw("Invalid requests supplied for jsonRPC batchRequest. Must be an array object that contain at least a method attribute");

        // Make sure each of our request objects are valid
        var _that = this;
        $.each(requests, function(i, req) {
          _that._validateRequestMethod(req.method);
          _that._validateRequestParams(req.params);
          if (typeof(req.id) === 'undefined') {
            req.id = i + 1;
          }
        });
        this._validateRequestCallbacks(options.success, options.error);

        var data = [],
            request;

        // Prepare our request object
        for(var i = 0; i<requests.length; i++) {
          request = requests[i];
          data.push(this._requestDataObj(request.method, request.params, request.id));
        }

        this._doRequest(JSON.stringify(data), options);
      },

      // Validate a params hash
      _validateConfigParams: function(params) {
        if(typeof(params) === 'undefined') {
          throw("No params specified");
        }
        else {
          if(params.endPoint && typeof(params.endPoint) !== 'string'){
            throw("endPoint must be a string");
          }
          if(params.namespace && typeof(params.namespace) !== 'string'){
            throw("namespace must be a string");
          }
        }
      },

      // Request method must be a string
      _validateRequestMethod: function(method) {
        if(typeof(method) !== 'string') throw("Invalid method supplied for jsonRPC request")
        return true;
      },

      // Validate request params.  Must be a) empty, b) an object (e.g. {}), or c) an array
      _validateRequestParams: function(params) {
        if(!(params === null ||
             typeof(params) === 'undefined' ||
             typeof(params) === 'object' ||
             $.isArray(params))) {
          throw("Invalid params supplied for jsonRPC request. It must be empty, an object or 
Download .txt
gitextract_zkw3fajl/

├── .gitignore
├── README.md
├── cache/
│   └── abc
├── config/
│   └── README.md
├── controller/
│   ├── AdminController.php
│   ├── CommonController.php
│   ├── ImagesController.php
│   ├── IndexController.php
│   └── UploadController.php
├── index.php
├── init.php
├── lib/
│   ├── Parsedown.php
│   ├── cache/
│   │   ├── filecache_.php
│   │   ├── memcache_.php
│   │   ├── redis_.php
│   │   └── secache_.php
│   ├── cache.php
│   ├── fetch.php
│   ├── onedrive.php
│   ├── oneindex.php
│   ├── route.php
│   ├── sqlite.php
│   └── view.php
├── one.php
├── statics/
│   ├── common/
│   │   ├── offline/
│   │   │   ├── css/
│   │   │   │   └── main.css
│   │   │   └── js/
│   │   │       ├── aria2.js
│   │   │       ├── jquery.Storage.js
│   │   │       ├── jquery.jsonrpc.js
│   │   │       ├── mustache.js
│   │   │       ├── peerid.js
│   │   │       └── yaaw-1.1.js
│   │   └── search/
│   │       └── js/
│   │           └── search.js
│   └── themes/
│       └── nexmoe/
│           ├── css/
│           │   └── forkGh.css
│           └── js/
│               ├── nexmoe.js
│               └── personjs.js
├── view/
│   ├── admin/
│   │   ├── cache.php
│   │   ├── images.php
│   │   ├── install/
│   │   │   ├── install_0.php
│   │   │   ├── install_1.php
│   │   │   ├── install_2.php
│   │   │   ├── install_3.php
│   │   │   └── layout.php
│   │   ├── layout.php
│   │   ├── login.php
│   │   ├── offline.php
│   │   ├── setpass.php
│   │   ├── settings.php
│   │   ├── show.php
│   │   └── upload.php
│   ├── common/
│   │   ├── offline.php
│   │   ├── search.php
│   │   └── tips.php
│   └── themes/
│       ├── classic/
│       │   ├── 404.php
│       │   ├── layout.php
│       │   └── list.php
│       ├── material/
│       │   ├── 404.php
│       │   ├── images/
│       │   │   ├── index.php
│       │   │   └── layout.php
│       │   ├── layout.php
│       │   ├── list.php
│       │   ├── password.php
│       │   └── show/
│       │       ├── audio.php
│       │       ├── code.php
│       │       ├── doc.php
│       │       ├── image.php
│       │       ├── pdf.php
│       │       ├── stream.php
│       │       ├── video.php
│       │       ├── video2.php
│       │       └── video5.php
│       └── nexmoe/
│           ├── 404.php
│           ├── images/
│           │   ├── index.php
│           │   └── layout.php
│           ├── layout.php
│           ├── list.php
│           ├── password.php
│           ├── readme.html
│           └── show/
│               ├── audio.php
│               ├── code.php
│               ├── doc.php
│               ├── image.php
│               ├── pdf.php
│               ├── stream.php
│               ├── video.php
│               ├── video2.php
│               └── video5.php
└── 使用及免责协议.md
Download .txt
SYMBOL INDEX (387 symbols across 32 files)

FILE: controller/AdminController.php
  class AdminController (line 3) | class AdminController{
    method __construct (line 33) | function __construct(){
    method login (line 36) | function login(){
    method logout (line 44) | function logout(){
    method settings (line 49) | function settings(){
    method offline (line 83) | function offline(){
    method cache_exists (line 100) | function cache_exists($cache_type){
    method cache (line 114) | function cache(){
    method images (line 125) | function images(){
    method show (line 137) | function show(){
    method setpass (line 158) | function setpass(){
    method install (line 174) | function install(){
    method install_0 (line 188) | function install_0(){
    method install_1 (line 198) | function install_1(){
    method install_2 (line 222) | function install_2(){
    method install_3 (line 226) | function install_3(){

FILE: controller/CommonController.php
  class CommonController (line 3) | class CommonController{
    method __construct (line 5) | function __construct(){
    method offline (line 8) | function offline(){
    method search (line 18) | function search(){
    method create_folder (line 39) | function create_folder(){
    method rename (line 59) | function rename(){
    method deleteitems (line 73) | function deleteitems(){
    method upload_url (line 86) | function upload_url(){
    method onlinefileupload (line 115) | function onlinefileupload()
    method uploadcondition (line 154) | function uploadcondition($file){
    method paste (line 166) | function paste(){
    method cut (line 187) | function cut($cutitems,$url){
    method copy (line 194) | function copy($copyitems,$url){
    method url2path (line 201) | function url2path($url){
    method url2id (line 219) | function url2id($url){

FILE: controller/ImagesController.php
  class ImagesController (line 3) | class ImagesController{
    method generateRandomString (line 4) | function generateRandomString($length) {
    method index (line 13) | function index(){
    method is_image (line 32) | function is_image($file){

FILE: controller/IndexController.php
  class IndexController (line 2) | class IndexController{
    method __construct (line 9) | function __construct(){
    method index (line 22) | function index(){
    method is_password (line 40) | function is_password(){
    method password (line 59) | function password($password){
    method file (line 70) | function file(){
    method dir (line 87) | function dir(){
    method show (line 167) | function show($item){
    method thumbnail (line 190) | function thumbnail($item){
    method items (line 204) | function items($path, $fetch=false){
    method navs (line 211) | function navs(){
    method get_content (line 227) | static function get_content($item){
    method is404 (line 240) | function is404(){
    method __destruct (line 250) | function __destruct(){

FILE: controller/UploadController.php
  class UploadController (line 3) | class UploadController{
    method index (line 6) | function index(){
    method scan_dir (line 38) | private function scan_dir($localpath, $remotepath){
    method add_task (line 54) | private function add_task($localfile, $remotefile){
    method run (line 71) | function run(){
    method task_request (line 101) | private function task_request($remotepath=''){
    method task (line 112) | function task($remotepath=null){
    method upload_large_file (line 134) | function upload_large_file($task){

FILE: init.php
  function i_autoload (line 8) | function i_autoload($className) {
  function config (line 27) | function config($key) {
  function db (line 74) | function db($table) {
  function view (line 80) | function view($file, $set = null) {
  function _ (line 86) | function _($str) {
  function e (line 92) | function e($str) {
  function str_is (line 98) | function str_is($pattern, $value)
  function get_domain (line 122) | function get_domain($url=null)
  function get_absolute_path (line 131) | function get_absolute_path($path) {
  function is_login (line 146) | function is_login(){

FILE: lib/Parsedown.php
  class Parsedown (line 16) | class Parsedown
    method text (line 24) | function text($text)
    method setBreaksEnabled (line 51) | function setBreaksEnabled($breaksEnabled)
    method setMarkupEscaped (line 60) | function setMarkupEscaped($markupEscaped)
    method setUrlsLinked (line 69) | function setUrlsLinked($urlsLinked)
    method setSafeMode (line 78) | function setSafeMode($safeMode)
    method lines (line 144) | protected function lines(array $lines)
    method isBlockContinuable (line 307) | protected function isBlockContinuable($Type)
    method isBlockCompletable (line 312) | protected function isBlockCompletable($Type)
    method blockCode (line 320) | protected function blockCode($Line, $Block = null)
    method blockCodeContinue (line 346) | protected function blockCodeContinue($Line, $Block)
    method blockCodeComplete (line 367) | protected function blockCodeComplete($Block)
    method blockComment (line 379) | protected function blockComment($Line)
    method blockCommentContinue (line 401) | protected function blockCommentContinue($Line, array $Block)
    method blockFencedCode (line 421) | protected function blockFencedCode($Line)
    method blockFencedCodeContinue (line 452) | protected function blockFencedCodeContinue($Line, $Block)
    method blockFencedCodeComplete (line 480) | protected function blockFencedCodeComplete($Block)
    method blockHeader (line 492) | protected function blockHeader($Line)
    method blockList (line 525) | protected function blockList($Line)
    method blockListContinue (line 564) | protected function blockListContinue($Line, array $Block)
    method blockListComplete (line 622) | protected function blockListComplete(array $Block)
    method blockQuote (line 641) | protected function blockQuote($Line)
    method blockQuoteContinue (line 657) | protected function blockQuoteContinue($Line, array $Block)
    method blockRule (line 684) | protected function blockRule($Line)
    method blockSetextHeader (line 701) | protected function blockSetextHeader($Line, array $Block = null)
    method blockMarkup (line 719) | protected function blockMarkup($Line)
    method blockMarkupContinue (line 771) | protected function blockMarkupContinue($Line, array $Block)
    method blockReference (line 810) | protected function blockReference($Line)
    method blockTable (line 839) | protected function blockTable($Line, array $Block = null)
    method blockTableContinue (line 946) | protected function blockTableContinue($Line, array $Block)
    method paragraph (line 1000) | protected function paragraph($Line)
    method line (line 1040) | public function line($text, $nonNestables=array())
    method inlineCode (line 1124) | protected function inlineCode($Excerpt)
    method inlineEmailTag (line 1143) | protected function inlineEmailTag($Excerpt)
    method inlineEmphasis (line 1167) | protected function inlineEmphasis($Excerpt)
    method inlineEscapeSequence (line 1199) | protected function inlineEscapeSequence($Excerpt)
    method inlineImage (line 1210) | protected function inlineImage($Excerpt)
    method inlineLink (line 1244) | protected function inlineLink($Excerpt)
    method inlineMarkup (line 1316) | protected function inlineMarkup($Excerpt)
    method inlineSpecialCharacter (line 1348) | protected function inlineSpecialCharacter($Excerpt)
    method inlineStrikethrough (line 1369) | protected function inlineStrikethrough($Excerpt)
    method inlineUrl (line 1389) | protected function inlineUrl($Excerpt)
    method inlineUrlTag (line 1416) | protected function inlineUrlTag($Excerpt)
    method unmarkedText (line 1437) | protected function unmarkedText($text)
    method element (line 1456) | protected function element(array $Element)
    method elements (line 1506) | protected function elements(array $Elements)
    method li (line 1522) | protected function li($lines)
    method parse (line 1545) | function parse($text)
    method sanitiseElement (line 1552) | protected function sanitiseElement(array $Element)
    method filterUnsafeUrlInAttribute (line 1585) | protected function filterUnsafeUrlInAttribute(array $Element, $attribute)
    method escape (line 1604) | protected static function escape($text, $allowQuotes = false)
    method striAtStart (line 1609) | protected static function striAtStart($string, $needle)
    method instance (line 1623) | static function instance($name = 'default')

FILE: lib/cache.php
  class cache (line 4) | class cache{
    method c (line 9) | protected static function c(){
    method get (line 27) | static function get($key, $default=null, $expire=99999999){
    method set (line 42) | static function set($key, $value, $expire=99999999){
    method clear (line 47) | static function clear(){
    method del (line 52) | static function del($key){
    method has (line 57) | static function has($key){
    method pull (line 65) | static function pull($key){

FILE: lib/cache/filecache_.php
  class filecache_ (line 2) | class filecache_{
    method __construct (line 5) | function __construct($cache_path= null){
    method get (line 12) | function get($key){
    method set (line 22) | function set($key, $value=null, $expire=99999999){
    method clear (line 29) | function clear(){

FILE: lib/cache/memcache_.php
  class memcache_ (line 2) | class memcache_{
    method __construct (line 5) | function __construct($config = null){
    method get (line 14) | function get($key){
    method set (line 23) | function set($key, $value=null, $expire=99999999){
    method clear (line 29) | function clear(){

FILE: lib/cache/redis_.php
  class redis_ (line 2) | class redis_{
    method __construct (line 5) | function __construct($config = null){
    method get (line 14) | function get($key){
    method set (line 21) | function set($key, $value=null, $expire=600){
    method clear (line 31) | function clear(){

FILE: lib/cache/secache_.php
  class secache_ (line 2) | class secache_{
    method __construct (line 6) | function __construct($config=null){
    method get (line 24) | function get($key){
    method set (line 33) | function set($key, $value=null, $expire=99999999){
    method clear (line 40) | function clear(){
  class secache (line 45) | class secache{
    method workat (line 61) | function workat($file){
    method create (line 105) | function create(){
    method _puts (line 111) | function _puts($offset,$data){
    method _seek (line 119) | function _seek($offset){
    method clear (line 122) | function clear(){
    method fetch (line 125) | function fetch($key,&$return){
    method lock (line 163) | function lock($is_block,$whatever=false){
    method unlock (line 174) | function unlock(){
    method delete (line 178) | function delete($key,$pos=false){
    method store (line 197) | function store($key,$value){
    method search (line 271) | function search($key,&$pos){
    method _get_size_schema_id (line 274) | function _get_size_schema_id($size){
    method _parse_str_size (line 282) | function _parse_str_size($str_size,$default){
    method _format (line 312) | function _format($truncate=false){
    method _get_node_root (line 346) | function _get_node_root($key){
    method _set_node_root (line 352) | function _set_node_root($key,$value){
    method _set_node (line 355) | function _set_node($pos,$key,$value){
    method _get_pos_by_key (line 365) | function _get_pos_by_key($offset,$key,&$pos){
    method _lru_delete (line 381) | function _lru_delete($info){
    method _lru_push (line 394) | function _lru_push($schema_id,$offset){
    method _get_node (line 412) | function _get_node($offset){
    method _lru_pop (line 418) | function _lru_pop($schema_id){
    method _dalloc (line 433) | function _dalloc($schema_id,$lru_freed=false){
    method _get_dcur_pos (line 458) | function _get_dcur_pos(){
    method _set_dcur_pos (line 463) | function _set_dcur_pos($pos){
    method _free_dspace (line 466) | function _free_dspace($size,$pos){
    method _dfollow (line 479) | function _dfollow($pos,&$c){
    method _free_node (line 489) | function _free_node($pos){
    method _alloc_idx (line 495) | function _alloc_idx($data){
    method _create_node (line 509) | function _create_node($pos,$data){
    method _set_schema (line 514) | function _set_schema($schema_id,$key,$value){
    method _get_schema (line 518) | function _get_schema($id,$key){
    method _all_schemas (line 526) | function _all_schemas(){
    method schemaStatus (line 539) | function schemaStatus(){
    method status (line 549) | function status(&$curBytes,&$totalBytes){
    method trigger_error (line 565) | function trigger_error($errstr,$errno){

FILE: lib/fetch.php
  class fetch (line 2) | class fetch {
    method init (line 10) | public static function init($opt = array()) {
    method __callstatic (line 33) | public static function __callstatic($method, $args) {
    method bulid_request (line 56) | private static function bulid_request($request, $method = 'GET', $post...
    method bulid_ch (line 67) | private static function bulid_ch(&$request) {
    method response (line 106) | private static function response($raw, $ch) {
    method single_curl (line 117) | private static function single_curl($request) {
    method rolling_curl (line 128) | private static function rolling_curl($requests) {
    method bulid_request_header (line 193) | private static function bulid_request_header($headers, &$cookies) {
    method iconv (line 221) | public static function iconv(&$raw, $content_type) {
    method get_respone_cookies (line 232) | public static function get_respone_cookies($raw) {
    method cookies_arr2str (line 252) | public static function cookies_arr2str($arr) {

FILE: lib/onedrive.php
  class onedrive (line 2) | class onedrive{
    method authorize_url (line 14) | static function authorize_url(){
    method authorize (line 28) | static function authorize($code = ""){
    method get_token (line 42) | static function get_token($refresh_token){
    method access_token (line 56) | static function access_token(){
    method request (line 78) | static function request($path="/", $query=""){
    method dir (line 89) | static function dir($path="/"){
    method dir_next_page (line 107) | static function dir_next_page($request, &$items, $retry=0){
    method search (line 136) | static function search($keyword){
    method thumbnail (line 160) | static function thumbnail($path,$size='large'){
    method share (line 168) | static function share($path){
    method upload (line 178) | static function upload($path,$content){
    method upload_url (line 186) | static function upload_url($path, $url){
    method create_upload_session (line 200) | static function create_upload_session($path){
    method upload_session (line 212) | static function upload_session($url, $file, $offset, $length=10240){
    method upload_session_status (line 230) | static function upload_session_status($url){
    method delete_upload_session (line 238) | static function delete_upload_session($url){
    method file_content (line 246) | static function file_content($file, $offset, $length){
    method human_filesize (line 253) | static function human_filesize($size, $precision = 1) {
    method urlencode (line 258) | static function urlencode($path){
    method _filesize (line 267) | static function _filesize($path){
    method create_folder (line 302) | public static function create_folder($path = '/', $name = '新建文件夹')
    method rename (line 332) | public static function rename($itemid, $name)
    method delete (line 358) | public static function delete($itemid = array())
    method move (line 427) | public static function move($itemid = array(), $newitemid)
    method copy (line 504) | public static function copy($itemids=array(), $destitemid){
    method path2id (line 520) | public static function path2id($path)
    method id2path (line 533) | public static function id2path($itemid)
    method detail (line 546) | public static function detail($itemid){

FILE: lib/oneindex.php
  class oneindex (line 2) | class oneindex{
    method get_token (line 8) | static function get_token($refresh_token){
    method refresh_cache (line 13) | static function refresh_cache($path){
    method dir (line 30) | static function dir($path = '/'){
    method file (line 44) | static function file($path){
    method file_exists (line 55) | static function file_exists($path){
    method get_content (line 63) | static function get_content($path){
    method thumb (line 81) | static function thumb($path,$width=800,$height=800){
    method download_url (line 96) | static function download_url($path){
    method web_url (line 104) | static function web_url($path){
    method direct_link (line 119) | static function direct_link($path){
    method get_absolute_path (line 136) | static function get_absolute_path($path) {

FILE: lib/route.php
  class route (line 2) | class route {
    method __callstatic (line 14) | public static function __callstatic($method, $args) {
    method init (line 47) | public static function init() {
    method auto (line 61) | public static function auto($controller_path) {
    method group (line 78) | public static function group($middleware, $callback){
    method resource (line 93) | public static function resource($name, $controller) {
    method uri_match (line 103) | public static function uri_match($pattern, $uri) {
    method get_uri (line 129) | public static function get_uri() {

FILE: lib/sqlite.php
  class sqlite (line 3) | class sqlite implements \Countable
    method __construct (line 15) | public function __construct($name, $filename = "data.sqlite3")
    method get (line 29) | public function get($key)
    method set (line 54) | public function set($key, $value)
    method delete (line 72) | public function delete($key)
    method deleteAll (line 86) | public function deleteAll()
    method count (line 96) | public function count()
    method createTable (line 106) | private function createTable()

FILE: lib/view.php
  class view (line 3) | class view {
    method load (line 8) | static function load($file, $set = null) {
    method __construct (line 17) | public function __construct($file, $set = null) {
    method with (line 26) | public function with($name, $value = NULL) {
    method __toString (line 35) | public function __toString() {
    method show (line 60) | public function show() {
    method layout (line 65) | static function layout($file) {
    method section (line 71) | static function section($name) {
    method begin (line 79) | static function begin($name) {
    method end (line 84) | static function end() {
    method direct (line 89) | static function direct($loction) {
    method abort (line 94) | static function abort() {
    method to404 (line 99) | static function to404(){

FILE: one.php
  class one (line 8) | class one{
    method cache_clear (line 9) | static function cache_clear(){
    method cache_refresh (line 13) | static function cache_refresh(){
    method token_refresh (line 17) | static function token_refresh(){
    method upload_file (line 25) | static function upload_file($localfile, $remotefile=null){
    method upload_folder (line 60) | static function upload_folder($localfolder, $remotefolder='/'){
    method folder2upload (line 67) | static function folder2upload($localfolder, $remotefolder){
    method upload_large_file (line 110) | static function upload_large_file($localfile, $remotepath){

FILE: statics/common/offline/js/aria2.js
  function get_error (line 27) | function get_error(result) {
  function default_error (line 36) | function default_error(result) {
  function main_alert (line 46) | function main_alert(_class, msg, timeout) {
  function bind_event (line 61) | function bind_event(dom) {
  function get_title (line 65) | function get_title(result) {
  function request_auth (line 92) | function request_auth(url) {
  function remove_auth (line 95) | function remove_auth(url) {

FILE: statics/common/offline/js/jquery.Storage.js
  function wls (line 46) | function wls(n,v){var c;if(typeof n==="string"&&typeof v==="string"){loc...
  function wc (line 47) | function wc(n,v){var dt,e,c;dt=new Date();dt.setTime(dt.getTime()+315360...
  function rls (line 48) | function rls(n){return localStorage[n];}
  function rc (line 49) | function rc(n){var nn, ca, i, c;nn=n+"=";ca=document.cookie.split(';');f...
  function dls (line 50) | function dls(n){return delete localStorage[n];}
  function dc (line 51) | function dc(n){return wc(n,"",-1);}

FILE: statics/common/offline/js/mustache.js
  function isWhitespace (line 57) | function isWhitespace(string) {
  function escapeHTML (line 92) | function escapeHTML(string) {
  function debug (line 102) | function debug(e, template, line, file) {
  function lookup (line 127) | function lookup(name, stack, defaultValue) {
  function renderSection (line 170) | function renderSection(name, stack, callback, inverted) {
  function parse (line 218) | function parse(template, options) {
  function _compile (line 471) | function _compile(template, options) {
  function clearCache (line 498) | function clearCache() {
  function compile (line 511) | function compile(template, options) {
  function render (line 532) | function render(template, view, partials) {

FILE: statics/common/offline/js/peerid.js
  function s (line 1) | function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&re...
  function addAzStyle (line 150) | function addAzStyle (id, client, version) {
  function addShadowStyle (line 156) | function addShadowStyle (id, client, version) {
  function addMainlineStyle (line 162) | function addMainlineStyle (id, client) {
  function addSimpleClient (line 166) | function addSimpleClient (client, version, id, position) {
  function getAzStyleClientName (line 181) | function getAzStyleClientName (peerId) {
  function getShadowStyleClientName (line 185) | function getShadowStyleClientName (peerId) {
  function getMainlineStyleClientName (line 189) | function getMainlineStyleClientName (peerId) {
  function getSimpleClient (line 193) | function getSimpleClient (peerId) {
  function getAzStyleClientVersion (line 205) | function getAzStyleClientVersion (client, peerId) {
  function isDigit (line 588) | function isDigit (s) {
  function isLetter (line 593) | function isLetter (s) {
  function isAlphaNumeric (line 598) | function isAlphaNumeric (s) {
  function decodeNumericValueOfByte (line 602) | function decodeNumericValueOfByte (b, minDigits) {
  function Buffer (line 670) | function Buffer (subject, encoding, noZero) {
  function hexWrite (line 831) | function hexWrite (buf, string, offset, length) {
  function utf8Write (line 858) | function utf8Write (buf, string, offset, length) {
  function asciiWrite (line 863) | function asciiWrite (buf, string, offset, length) {
  function binaryWrite (line 868) | function binaryWrite (buf, string, offset, length) {
  function base64Write (line 872) | function base64Write (buf, string, offset, length) {
  function utf16leWrite (line 877) | function utf16leWrite (buf, string, offset, length) {
  function base64Slice (line 1033) | function base64Slice (buf, start, end) {
  function utf8Slice (line 1041) | function utf8Slice (buf, start, end) {
  function asciiSlice (line 1058) | function asciiSlice (buf, start, end) {
  function binarySlice (line 1068) | function binarySlice (buf, start, end) {
  function hexSlice (line 1072) | function hexSlice (buf, start, end) {
  function utf16leSlice (line 1085) | function utf16leSlice (buf, start, end) {
  function readUInt16 (line 1135) | function readUInt16 (buf, offset, littleEndian, noAssert) {
  function readUInt32 (line 1167) | function readUInt32 (buf, offset, littleEndian, noAssert) {
  function readInt16 (line 1224) | function readInt16 (buf, offset, littleEndian, noAssert) {
  function readInt32 (line 1251) | function readInt32 (buf, offset, littleEndian, noAssert) {
  function readFloat (line 1278) | function readFloat (buf, offset, littleEndian, noAssert) {
  function readDouble (line 1295) | function readDouble (buf, offset, littleEndian, noAssert) {
  function writeUInt16 (line 1326) | function writeUInt16 (buf, value, offset, littleEndian, noAssert) {
  function writeUInt32 (line 1355) | function writeUInt32 (buf, value, offset, littleEndian, noAssert) {
  function writeInt16 (line 1401) | function writeInt16 (buf, value, offset, littleEndian, noAssert) {
  function writeInt32 (line 1429) | function writeInt32 (buf, value, offset, littleEndian, noAssert) {
  function writeFloat (line 1457) | function writeFloat (buf, value, offset, littleEndian, noAssert) {
  function writeDouble (line 1482) | function writeDouble (buf, value, offset, littleEndian, noAssert) {
  function base64clean (line 1636) | function base64clean (str) {
  function stringtrim (line 1646) | function stringtrim (str) {
  function clamp (line 1652) | function clamp (index, len, defaultValue) {
  function coerce (line 1662) | function coerce (length) {
  function isArray (line 1670) | function isArray (subject) {
  function isArrayish (line 1676) | function isArrayish (subject) {
  function toHex (line 1682) | function toHex (n) {
  function utf8ToBytes (line 1687) | function utf8ToBytes (str) {
  function asciiToBytes (line 1705) | function asciiToBytes (str) {
  function utf16leToBytes (line 1714) | function utf16leToBytes (str) {
  function base64ToBytes (line 1728) | function base64ToBytes (str) {
  function blitBuffer (line 1732) | function blitBuffer (src, dst, offset, length) {
  function decodeUtf8Char (line 1741) | function decodeUtf8Char (str) {
  function verifuint (line 1754) | function verifuint (value, max) {
  function verifsint (line 1761) | function verifsint (value, max, min) {
  function verifIEEE754 (line 1768) | function verifIEEE754 (value, max, min) {
  function assert (line 1774) | function assert (test, message) {
  function decode (line 1794) | function decode (elt) {
  function b64ToByteArray (line 1810) | function b64ToByteArray (b64) {
  function uint8ToBase64 (line 1856) | function uint8ToBase64 (uint8) {

FILE: statics/common/offline/js/yaaw-1.1.js
  function render (line 352) | function render(f) {

FILE: statics/common/search/js/search.js
  function downall (line 26) | function downall() {
  function thumb (line 41) | function thumb(){
  function copy (line 204) | function copy(){
  function cut (line 210) | function cut(){
  function onClickHander (line 216) | function onClickHander(){
  function checkall (line 248) | function checkall(){
  function getListDom (line 264) | function getListDom(item){

FILE: statics/themes/nexmoe/js/nexmoe.js
  function downall (line 26) | function downall() {
  function thumb (line 41) | function thumb(){
  function onClickHander (line 284) | function onClickHander(){
  function checkall (line 317) | function checkall(){
  function submitForm (line 332) | function submitForm() {
  function submitRemoteFile (line 365) | function submitRemoteFile() {
  function showProgress (line 384) | function showProgress(url){
  function getProgress (line 402) | function getProgress(url){
  function updateProgress (line 421) | function updateProgress(width){
  function getRemoteUrl (line 427) | function getRemoteUrl(){
  function fileNameFromUrl (line 435) | function fileNameFromUrl(url)
  function copy (line 444) | function copy(){
  function cut (line 451) | function cut(){
  function paste (line 465) | function paste(){
  function getCookie (line 555) | function getCookie(cname){
  function getListDom (line 567) | function getListDom(item){

FILE: view/admin/cache.php
  function getPHPExecutableFromPath (line 3) | function getPHPExecutableFromPath() {

FILE: view/common/search.php
  function file_ico (line 3) | function file_ico($item){

FILE: view/themes/material/list.php
  function file_ico (line 3) | function file_ico($item){

FILE: view/themes/material/show/code.php
  function code_type (line 3) | function code_type($ext){

FILE: view/themes/nexmoe/list.php
  function file_ico (line 3) | function file_ico($item){

FILE: view/themes/nexmoe/show/code.php
  function code_type (line 3) | function code_type($ext){
Condensed preview — 87 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (533K chars).
[
  {
    "path": ".gitignore",
    "chars": 13,
    "preview": "**/.DS_Store\n"
  },
  {
    "path": "README.md",
    "chars": 4110,
    "preview": "## 简介\n\n本项目是基于:\n\n- Oneindex\n\n- OneindexN项目地址:https://github.com/xieqifei/OneindexN\n\n详细安装教程:\n- [基于Onedrive和Server搭建下载站/网盘]"
  },
  {
    "path": "cache/abc",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "config/README.md",
    "chars": 36,
    "preview": "# oneindex\nOneDrive Directory Index\n"
  },
  {
    "path": "controller/AdminController.php",
    "chars": 8421,
    "preview": "<?php\ndefine('VIEW_PATH', ROOT.'view/admin/');\nclass AdminController{\n    static $default_config = array(\n      'site_na"
  },
  {
    "path": "controller/CommonController.php",
    "chars": 6110,
    "preview": "<?php \ndefine('VIEW_PATH', ROOT.'view/');\nclass CommonController{\n\t\n\tfunction __construct(){\n\t}\n\t//aria2\n\tfunction offli"
  },
  {
    "path": "controller/ImagesController.php",
    "chars": 1581,
    "preview": "<?php \n\nclass ImagesController{\n\tfunction generateRandomString($length) {\n            $characters = '0123456789abcdefghi"
  },
  {
    "path": "controller/IndexController.php",
    "chars": 7189,
    "preview": "<?php \nclass IndexController{\n\tprivate $url_path;\n\tprivate $name;\n\tprivate $path;\n\tprivate $items;\n\tprivate $time;\n\n\tfun"
  },
  {
    "path": "controller/UploadController.php",
    "chars": 6182,
    "preview": "<?php \ndefine('VIEW_PATH', ROOT.'view/admin/');\nclass UploadController{\n\n\t//从网站服务器目录上传文件\n\tfunction index(){\n\t\tif($_POST["
  },
  {
    "path": "index.php",
    "chars": 2880,
    "preview": "<?php\n\nrequire  __DIR__.'/init.php';\n/**\n *    程序安装\n */\n//选择OD国际版?世纪互联版。\nif (config('area')!==\"cn\"){\n\tonedrive::$api_url"
  },
  {
    "path": "init.php",
    "chars": 3600,
    "preview": "<?php\nerror_reporting(E_ALL & ~E_NOTICE);\ndate_default_timezone_set('PRC');\ndefine('TIME', time());\n!defined('ROOT') && "
  },
  {
    "path": "lib/Parsedown.php",
    "chars": 41273,
    "preview": "<?php\n\n#\n#\n# Parsedown\n# http://parsedown.org\n#\n# (c) Emanuil Rusev\n# http://erusev.com\n#\n# For the full license informa"
  },
  {
    "path": "lib/cache/filecache_.php",
    "chars": 770,
    "preview": "<?php \nclass filecache_{\n\tprivate $cache_path;\n\t\n\tfunction __construct($cache_path= null){\n\t\tif(empty($cache_path)){\n\t\t\t"
  },
  {
    "path": "lib/cache/memcache_.php",
    "chars": 649,
    "preview": "<?php \nclass memcache_{\n\tprivate $m;\n\t\n\tfunction __construct($config = null){\n\t\t$this->m = new Memcache();\n\t\tif(empty($c"
  },
  {
    "path": "lib/cache/redis_.php",
    "chars": 1223,
    "preview": "<?php\nclass redis_{\n        private $redis;\n\n        function __construct($config = null){\n                $this->redis "
  },
  {
    "path": "lib/cache/secache_.php",
    "chars": 20195,
    "preview": "<?php \nclass secache_{\n\tprivate $cachefile;\n\tprivate $c;\n\t\n\tfunction __construct($config=null){\n\t\t\n\t\tlist($cachefile, $s"
  },
  {
    "path": "lib/cache.php",
    "chars": 1550,
    "preview": "<?php\n\n\t!defined('CACHE_PATH') && define('CACHE_PATH', sys_get_temp_dir().'/');\n\tclass cache{\n\t\t// 驱动方式(支持filecache/memc"
  },
  {
    "path": "lib/fetch.php",
    "chars": 7766,
    "preview": "<?php\nclass fetch {\n\tpublic static $headers = \"User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like G"
  },
  {
    "path": "lib/onedrive.php",
    "chars": 17615,
    "preview": "<?php\n\tclass onedrive{\n\t\tstatic $client_id;\n\t\tstatic $client_secret;\n\t\tstatic $redirect_uri;\n\t\t//国际版\n\t\tstatic $api_url ="
  },
  {
    "path": "lib/oneindex.php",
    "chars": 3726,
    "preview": "<?php\n\tclass oneindex{\n\t\tstatic $dir = array();\n\t\tstatic $file = array();\n\t\tstatic $thumb = array();\n\n\t\t//使用 $refresh_to"
  },
  {
    "path": "lib/route.php",
    "chars": 3978,
    "preview": "<?php\nclass route {\n\tpublic static $uri;\n\tprivate static $method;\n\tprivate static $root = '/';\n\tstatic $runed = false;\n\n"
  },
  {
    "path": "lib/sqlite.php",
    "chars": 2626,
    "preview": "<?php\n\nclass sqlite implements \\Countable\n{\n    /**\n     * @var PDO\n     */\n    private $db = null;\n\n    /**\n     * @var"
  },
  {
    "path": "lib/view.php",
    "chars": 2277,
    "preview": "<?php\n!defined('VIEW_PATH') && define('VIEW_PATH', 'view/');\nclass view {\n\tprivate $_view = array('file' => '', 'data' ="
  },
  {
    "path": "one.php",
    "chars": 6008,
    "preview": "<?php \nif( php_sapi_name() !== \"cli\" ){\n   die( \"NoAccess\" );\n}\nrequire 'init.php';\nini_set('memory_limit', '128M');\n\ncl"
  },
  {
    "path": "statics/common/offline/css/main.css",
    "chars": 9575,
    "preview": "/* \n * Copyright (C) 2015 Binux <roy@binux.me>\n *\n * This file is part of YAAW (https://github.com/binux/yaaw).\n *\n * YA"
  },
  {
    "path": "statics/common/offline/js/aria2.js",
    "chars": 27271,
    "preview": "/* \n * Copyright (C) 2015 Binux <roy@binux.me>\n *\n * This file is part of YAAW (https://github.com/binux/yaaw).\n *\n * YA"
  },
  {
    "path": "statics/common/offline/js/jquery.Storage.js",
    "chars": 3855,
    "preview": "/**\n * Storage plugin\n * Provides a simple interface for storing data such as user preferences.\n * Storage is useful for"
  },
  {
    "path": "statics/common/offline/js/jquery.jsonrpc.js",
    "chars": 10033,
    "preview": "(function($) {\n  $.extend({\n    jsonRPC: {\n      // RPC Version Number\n      version: '2.0',\n\n      // End point URL, se"
  },
  {
    "path": "statics/common/offline/js/mustache.js",
    "chars": 14513,
    "preview": "/*!\n * mustache.js - Logic-less {{mustache}} templates with JavaScript\n * http://github.com/janl/mustache.js\n */\nvar Mus"
  },
  {
    "path": "statics/common/offline/js/peerid.js",
    "chars": 58367,
    "preview": "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0)"
  },
  {
    "path": "statics/common/offline/js/yaaw-1.1.js",
    "chars": 35746,
    "preview": "/* \n * Copyright (C) 2015 Binux <roy@binux.me>\n *\n * This file is part of YAAW (https://github.com/binux/yaaw).\n *\n * YA"
  },
  {
    "path": "statics/common/search/js/search.js",
    "chars": 11122,
    "preview": "$ = mdui.JQ;\n$.fn.extend({\n    sortElements: function (comparator, getSortable) {\n        getSortable = getSortable || f"
  },
  {
    "path": "statics/themes/nexmoe/css/forkGh.css",
    "chars": 3541,
    "preview": "/*!\n * \"Fork me on GitHub\" CSS ribbon v0.2.3 | MIT License\n * https://github.com/simonwhitaker/github-fork-ribbon-css\n*/"
  },
  {
    "path": "statics/themes/nexmoe/js/nexmoe.js",
    "chars": 23112,
    "preview": "$ = mdui.JQ;\n$.fn.extend({\n    sortElements: function (comparator, getSortable) {\n        getSortable = getSortable || f"
  },
  {
    "path": "statics/themes/nexmoe/js/personjs.js",
    "chars": 322,
    "preview": "var documentWidth=window.screen.availWidth;\nvar documentHeight=window.screen.availHeight;\nif(documentWidth>documentHeigh"
  },
  {
    "path": "view/admin/cache.php",
    "chars": 1857,
    "preview": "<?php view::layout('layout')?>\n<?php \nfunction getPHPExecutableFromPath() {\n  $paths = explode(PATH_SEPARATOR, getenv('P"
  },
  {
    "path": "view/admin/images.php",
    "chars": 1247,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n<div class=\"mdui-container-fluid\">\n\n\t<div class=\"mdui-ty"
  },
  {
    "path": "view/admin/install/install_0.php",
    "chars": 2460,
    "preview": "<?php view::layout('install/layout')?>\n\n<?php view::begin('content');?>\n\n<div class=\"mdui-container-fluid\">\n\t<div class="
  },
  {
    "path": "view/admin/install/install_1.php",
    "chars": 2395,
    "preview": "<?php view::layout('install/layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\">\n\t<div class"
  },
  {
    "path": "view/admin/install/install_2.php",
    "chars": 504,
    "preview": "<?php view::layout('install/layout')?>\n\n<?php view::begin('content');?>\n<?php ?>\n<div class=\"mdui-container-fluid\">\n\t<di"
  },
  {
    "path": "view/admin/install/install_3.php",
    "chars": 780,
    "preview": "<?php view::layout('install/layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\">\n\t<div class"
  },
  {
    "path": "view/admin/install/layout.php",
    "chars": 2191,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n    <link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"/statics/them"
  },
  {
    "path": "view/admin/layout.php",
    "chars": 3487,
    "preview": "\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0,maximum-sca"
  },
  {
    "path": "view/admin/login.php",
    "chars": 765,
    "preview": "<?php view::layout('install/layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\">\n\t<div class"
  },
  {
    "path": "view/admin/offline.php",
    "chars": 1381,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n<div class=\"mdui-container-fluid\">\n\n\t<div class=\"mdui-ty"
  },
  {
    "path": "view/admin/setpass.php",
    "chars": 832,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n<div class=\"mdui-container-fluid\">\n\n\t<div class=\"mdui-ty"
  },
  {
    "path": "view/admin/settings.php",
    "chars": 3272,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n<div class=\"mdui-container-fluid\">\n\n\t<div class=\"mdui-ty"
  },
  {
    "path": "view/admin/show.php",
    "chars": 694,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n<div class=\"mdui-container-fluid\">\n\n\t<div class=\"mdui-ty"
  },
  {
    "path": "view/admin/upload.php",
    "chars": 3363,
    "preview": "<?php view::layout('layout')?>\n<?php view::begin('content');?>\n<div class=\"mdui-container-fluid\">\n\n\t<div class=\"mdui-typ"
  },
  {
    "path": "view/common/offline.php",
    "chars": 22692,
    "preview": "<?php view::layout('themes/'.(config('style')?config('style'):'material').'/layout')?>\n\n<?php view::begin('content');?>\n"
  },
  {
    "path": "view/common/search.php",
    "chars": 6651,
    "preview": "<?php view::layout('themes/'.(config('style')?config('style'):'material').'/layout')?>\n<?php \n\tfunction file_ico($item){"
  },
  {
    "path": "view/common/tips.php",
    "chars": 258,
    "preview": "<?php view::layout('themes/'.(config('style')?config('style'):'material').'/layout')?>\n\n<?php view::begin('content');?>\n"
  },
  {
    "path": "view/themes/classic/404.php",
    "chars": 3116,
    "preview": "<!DOCTYPE html>\n<html>\n\t<head>\n\t    <meta charset=\"utf-8\" />\n\t\t<title>404 Not Found</title>\n\t\t<meta charset=\"utf-8\">\n   "
  },
  {
    "path": "view/themes/classic/layout.php",
    "chars": 1433,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<title><?php _($title);?></title>\n\t<link rel=\"stylesheet\" href=\"/"
  },
  {
    "path": "view/themes/classic/list.php",
    "chars": 4541,
    "preview": "<!DOCTYPE html>\n<html>\n    <head>\n\t    <title>Index of <?php echo urldecode($path);?></title>\n        <meta charset=\"utf"
  },
  {
    "path": "view/themes/material/404.php",
    "chars": 195,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t<div class=\"mdui-typo-display-4\" style=\"margin: 100px a"
  },
  {
    "path": "view/themes/material/images/index.php",
    "chars": 598,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\" style=\"padding-top: "
  },
  {
    "path": "view/themes/material/images/layout.php",
    "chars": 2103,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale="
  },
  {
    "path": "view/themes/material/layout.php",
    "chars": 2104,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale="
  },
  {
    "path": "view/themes/material/list.php",
    "chars": 6200,
    "preview": "<?php view::layout('layout')?>\n<?php \nfunction file_ico($item){\n  $ext = strtolower(pathinfo($item['name'], PATHINFO_EXT"
  },
  {
    "path": "view/themes/material/password.php",
    "chars": 779,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\">\n\t<div class=\"mdui-c"
  },
  {
    "path": "view/themes/material/show/audio.php",
    "chars": 1274,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n<link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/np"
  },
  {
    "path": "view/themes/material/show/code.php",
    "chars": 1618,
    "preview": "<?php view::layout('layout')?>\n<?php \n\tfunction code_type($ext){\n\t\t$code_type['html'] = 'html';\n\t\t$code_type['htm'] = 'h"
  },
  {
    "path": "view/themes/material/show/doc.php",
    "chars": 290,
    "preview": "<?php \n        if ($item[\"size\"] < 10000000) {\n                $url = 'https://view.officeapps.live.com/op/view.aspx?src"
  },
  {
    "path": "view/themes/material/show/image.php",
    "chars": 930,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\">\n\t<br>\n\t<img class=\""
  },
  {
    "path": "view/themes/material/show/pdf.php",
    "chars": 1165,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t<iframe id=\"mask\" src='<?php echo str_replace('transfor"
  },
  {
    "path": "view/themes/material/show/stream.php",
    "chars": 2922,
    "preview": "<?php \nheader(\"ALLOW-CONTROL-ALLOW-ORIGIN:*\");\n$types = [\n\t'chm'=>'application/octet-stream',\n\t'ppt'=>'application/vnd.m"
  },
  {
    "path": "view/themes/material/show/video.php",
    "chars": 1431,
    "preview": "<?php view::layout('layout')?>\n<?php\n$item['thumb'] = onedrive::thumbnail($item['path']);\n?>\n<?php view::begin('content'"
  },
  {
    "path": "view/themes/material/show/video2.php",
    "chars": 1527,
    "preview": "<?php view::layout('layout')?>\n\n<?php \n//仅支持教育版和企业版\nif(strpos($item['downloadUrl'],\"sharepoint.com\") == false){\n\theader("
  },
  {
    "path": "view/themes/material/show/video5.php",
    "chars": 932,
    "preview": "<?php view::layout('layout')?>\n\n<?php \n$item['thumb'] = onedrive::thumbnail($item['path']);\n?>\n\n<?php view::begin('conte"
  },
  {
    "path": "view/themes/nexmoe/404.php",
    "chars": 195,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t<div class=\"mdui-typo-display-4\" style=\"margin: 100px a"
  },
  {
    "path": "view/themes/nexmoe/images/index.php",
    "chars": 647,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\">\n\n<div class=\"nexmoe"
  },
  {
    "path": "view/themes/nexmoe/images/layout.php",
    "chars": 1192,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale="
  },
  {
    "path": "view/themes/nexmoe/layout.php",
    "chars": 5122,
    "preview": "<!DOCTYPE html>\r\n<html>\r\n\t<head>\r\n\t\t<meta charset=\"utf-8\">\r\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial"
  },
  {
    "path": "view/themes/nexmoe/list.php",
    "chars": 11501,
    "preview": "<?php view::layout('layout')?>\n<?php \nfunction file_ico($item){\n  $ext = strtolower(pathinfo($item['name'], PATHINFO_EXT"
  },
  {
    "path": "view/themes/nexmoe/password.php",
    "chars": 758,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t\n<div class=\"mdui-container-fluid\">\n\t<div class=\"mdui-c"
  },
  {
    "path": "view/themes/nexmoe/readme.html",
    "chars": 12041,
    "preview": "\n<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale"
  },
  {
    "path": "view/themes/nexmoe/show/audio.php",
    "chars": 880,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n<div class=\"mdui-container-fluid\">\n    <div class=\"nexmo"
  },
  {
    "path": "view/themes/nexmoe/show/code.php",
    "chars": 1712,
    "preview": "<?php view::layout('layout')?>\n<?php \n\tfunction code_type($ext){\n\t\t$code_type['html'] = 'html';\n\t\t$code_type['htm'] = 'h"
  },
  {
    "path": "view/themes/nexmoe/show/doc.php",
    "chars": 134,
    "preview": "<?php \n\t$url = 'https://view.officeapps.live.com/op/view.aspx?src='.urlencode($item['downloadUrl']);\n\tview::direct($url)"
  },
  {
    "path": "view/themes/nexmoe/show/image.php",
    "chars": 971,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\n\n<div class=\"mdui-container-fluid\">\n    <div class=\"nex"
  },
  {
    "path": "view/themes/nexmoe/show/pdf.php",
    "chars": 1165,
    "preview": "<?php view::layout('layout')?>\n\n<?php view::begin('content');?>\n\t<iframe id=\"mask\" src='<?php echo str_replace('transfor"
  },
  {
    "path": "view/themes/nexmoe/show/stream.php",
    "chars": 2882,
    "preview": "<?php \n\n$types = [\n\t'chm'=>'application/octet-stream',\n\t'ppt'=>'application/vnd.ms-powerpoint',\n\t'xls'=>'application/vnd"
  },
  {
    "path": "view/themes/nexmoe/show/video.php",
    "chars": 2396,
    "preview": "<?php view::layout('layout')?>\n<?php\n$item['thumb'] = onedrive::thumbnail($item['path']);\n?>\n<?php view::begin('content'"
  },
  {
    "path": "view/themes/nexmoe/show/video2.php",
    "chars": 2774,
    "preview": "<?php view::layout('layout')?>\n\n<?php \n//仅支持教育版和企业版\nif(strpos($item['downloadUrl'],\"sharepoint.com\") == false){\n\theader("
  },
  {
    "path": "view/themes/nexmoe/show/video5.php",
    "chars": 1860,
    "preview": "<?php view::layout('layout')?>\n\n<?php \n$item['thumb'] = onedrive::thumbnail($item['path']);\n?>\n\n<?php view::begin('conte"
  },
  {
    "path": "使用及免责协议.md",
    "chars": 894,
    "preview": "用户须知:无论您是个人或组织、盈利与否、用途如何(包括以学习和研究为目的),均需仔细阅读本协议,包括免除oneindex开发者责任的免责条款及对您的权利限制。请您审阅并接受或不接受本服务条款。如您不同意本服务条款及/或oneindex开发者"
  }
]

About this extraction

This page contains the full source code of the Mintimate/OneindexM GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 87 files (471.0 KB), approximately 140.7k tokens, and a symbol index with 387 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!