Browse Source

init commit

Ubuntu 2 years ago
commit
e4af30b379
100 changed files with 13648 additions and 0 deletions
  1. 33
    0
      .env
  2. 3
    0
      .gitattributes
  3. 9
    0
      .gitignore
  4. 30
    0
      app/Console/Commands/Lion.php
  5. 46
    0
      app/Console/Kernel.php
  6. 65
    0
      app/Exceptions/Handler.php
  7. 70
    0
      app/FunMenu.php
  8. 15
    0
      app/FunMenuDetail.php
  9. 201
    0
      app/FunUserGroups.php
  10. 10
    0
      app/Functions.php
  11. 32
    0
      app/Http/Controllers/Auth/ForgotPasswordController.php
  12. 39
    0
      app/Http/Controllers/Auth/LoginController.php
  13. 71
    0
      app/Http/Controllers/Auth/RegisterController.php
  14. 39
    0
      app/Http/Controllers/Auth/ResetPasswordController.php
  15. 119
    0
      app/Http/Controllers/Backend/DataManagement/InfoManagementController.php
  16. 105
    0
      app/Http/Controllers/Backend/FunmenusController.php
  17. 108
    0
      app/Http/Controllers/Backend/FunmenusDetailController.php
  18. 17
    0
      app/Http/Controllers/Backend/IndexController.php
  19. 35
    0
      app/Http/Controllers/Backend/PasswordController.php
  20. 118
    0
      app/Http/Controllers/Backend/UsergroupsController.php
  21. 76
    0
      app/Http/Controllers/Backend/UsersController.php
  22. 13
    0
      app/Http/Controllers/Controller.php
  23. 28
    0
      app/Http/Controllers/HomeController.php
  24. 184
    0
      app/Http/Controllers/Web/AiFaceController.php
  25. 184
    0
      app/Http/Controllers/Web/Api2021Controller.php
  26. 63
    0
      app/Http/Kernel.php
  27. 15
    0
      app/Http/Middleware/AddHeaders.php
  28. 17
    0
      app/Http/Middleware/EncryptCookies.php
  29. 26
    0
      app/Http/Middleware/RedirectIfAuthenticated.php
  30. 18
    0
      app/Http/Middleware/TrimStrings.php
  31. 21
    0
      app/Http/Middleware/VerifyCsrfToken.php
  32. 152
    0
      app/Http/Services/Backend/DataManagement/InfoManagementService.php
  33. 92
    0
      app/Http/Services/CheckParamService.php
  34. 41
    0
      app/Http/Services/ConstDef/GeneralConst.php
  35. 163
    0
      app/Http/Services/Web/AiFaceService.php
  36. 114
    0
      app/Http/Services/Web/Api2021Service.php
  37. 35
    0
      app/Http/ViewComposers/LeftMenuComposer.php
  38. 14
    0
      app/Models/Web/FaceMergeToken.php
  39. 13
    0
      app/Models/Web/GeneralSettings.php
  40. 13
    0
      app/Models/Web/Info.php
  41. 14
    0
      app/Models/Web/ShareData.php
  42. 30
    0
      app/Providers/AppServiceProvider.php
  43. 30
    0
      app/Providers/AuthServiceProvider.php
  44. 21
    0
      app/Providers/BroadcastServiceProvider.php
  45. 34
    0
      app/Providers/ComposerServiceProvider.php
  46. 32
    0
      app/Providers/EventServiceProvider.php
  47. 73
    0
      app/Providers/RouteServiceProvider.php
  48. 32
    0
      app/User.php
  49. 51
    0
      artisan
  50. 67
    0
      bootstrap/app.php
  51. 17
    0
      bootstrap/autoload.php
  52. 2
    0
      bootstrap/cache/.gitignore
  53. BIN
      composer
  54. 68
    0
      composer.json
  55. 7330
    0
      composer.lock
  56. 235
    0
      config/app.php
  57. 102
    0
      config/auth.php
  58. 58
    0
      config/broadcasting.php
  59. 91
    0
      config/cache.php
  60. 108
    0
      config/database.php
  61. 68
    0
      config/filesystems.php
  62. 20
    0
      config/image.php
  63. 123
    0
      config/mail.php
  64. 85
    0
      config/queue.php
  65. 53
    0
      config/services.php
  66. 179
    0
      config/session.php
  67. 33
    0
      config/view.php
  68. 1
    0
      database/.gitignore
  69. 24
    0
      database/factories/ModelFactory.php
  70. 35
    0
      database/migrations/2014_10_12_000000_create_users_table.php
  71. 32
    0
      database/migrations/2014_10_12_100000_create_password_resets_table.php
  72. 35
    0
      database/migrations/2016_02_23_075631_create_functions_table.php
  73. 34
    0
      database/migrations/2016_02_23_080148_create_funmenu_table.php
  74. 35
    0
      database/migrations/2016_02_23_080344_create_funmenudetail_table.php
  75. 35
    0
      database/migrations/2016_02_23_080520_create_funusergroups_table.php
  76. 16
    0
      database/seeds/DatabaseSeeder.php
  77. 19
    0
      package.json
  78. 31
    0
      phpunit.xml
  79. 21
    0
      public/.htaccess
  80. 1
    0
      public/91APP/css/normalize.min.css
  81. 124
    0
      public/91APP/css/style.css
  82. BIN
      public/91APP/images/share.jpg
  83. 53
    0
      public/91APP/index.html
  84. 17
    0
      public/91APP/js/libs/TweenMax.min.js
  85. 12
    0
      public/91APP/js/libs/easing/EasePack.min.js
  86. 4
    0
      public/91APP/js/libs/jquery-1.11.1.min.js
  87. 1
    0
      public/91APP/js/libs/jquery-1.11.1.min.map
  88. 118
    0
      public/91APP/js/libs/jquery.nicescroll.min.js
  89. 11
    0
      public/91APP/js/libs/modernizr-2.6.2-respond-1.1.0.min.js
  90. 175
    0
      public/91APP/js/main.js
  91. 45
    0
      public/91APP/js/simplePage.js
  92. 32
    0
      public/91APP/js/templete.js
  93. 84
    0
      public/91APP/js/utlis.js
  94. 1
    0
      public/[Eric]photoHelper/css/normalize.min.css
  95. 124
    0
      public/[Eric]photoHelper/css/style.css
  96. BIN
      public/[Eric]photoHelper/images/demo1.jpg
  97. BIN
      public/[Eric]photoHelper/images/demo2.jpg
  98. 66
    0
      public/[Eric]photoHelper/index.html
  99. 1059
    0
      public/[Eric]photoHelper/js/exif.js
  100. 0
    0
      public/[Eric]photoHelper/js/faceFusionAPI.js

+ 33
- 0
.env View File

@@ -0,0 +1,33 @@
1
+APP_ENV=pro                                                 # 本範例用在開發環境上所以指定為 dev ,但實際情況會用在預設的線上環境需要指定 pro
2
+APP_KEY= # 在下過 php artisan key:generate 指令後,此行會更新,需要同步到所有相關設定檔
3
+APP_DEBUG=false                                             # dev 環境建議開啟,pro 環境建議關閉
4
+APP_LOG_LEVEL=info                                          # dev 環境建議指定 debug ,pro 環境建議指定 info
5
+APP_URL=https://www.pxfreshdelivery.tw/     		             # 建議使用 xxx.ogilvy.com.tw 的命名方式(另有教學會指定讓該網址生效),避免開發環境太多臨時專案都用 localhost 產生衝突
6
+APP_NAME=PXGo                                            # 可填寫程式資料夾的名字,不會被網頁的任何地方顯示
7
+
8
+DB_CONNECTION=mysql
9
+DB_HOST=
10
+DB_PORT=
11
+DB_DATABASE=
12
+DB_USERNAME=
13
+DB_PASSWORD=
14
+
15
+BROADCAST_DRIVER=log                                        # 不需修改或視情況修改
16
+CACHE_DRIVER=file                                           # 不需修改或視情況修改
17
+SESSION_DRIVER=file                                         # 不需修改或視情況修改
18
+QUEUE_DRIVER=sync                                           # 不需修改或視情況修改
19
+
20
+AWS_APP_KEY=
21
+AWS_APP_SECRET=
22
+AWS_S3_REGION=
23
+AWS_S3_BUCKET=pxgo-pro
24
+# AWS_S3_URI=https://pxgo-pro.s3.ap-northeast-1.amazonaws.com/
25
+
26
+AWS_CDN_ID=
27
+AWS_CDN_KEY=
28
+AWS_CDN_SECRET=
29
+
30
+AI_FACE_TOKEN_URL=
31
+AI_FACE_MERGE_URL=
32
+AI_FACE_CLIENT_ID=
33
+AI_FACE_CLIENT_SECRET=

+ 3
- 0
.gitattributes View File

@@ -0,0 +1,3 @@
1
+* text=auto
2
+*.css linguist-vendored
3
+*.scss linguist-vendored

+ 9
- 0
.gitignore View File

@@ -0,0 +1,9 @@
1
+/node_modules
2
+/public/storage
3
+/public/hot
4
+/storage/*.key
5
+/vendor
6
+/.idea
7
+Homestead.json
8
+Homestead.yaml
9
+.env.*

+ 30
- 0
app/Console/Commands/Lion.php View File

@@ -0,0 +1,30 @@
1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use Illuminate\Console\Command;
6
+use App\Models\Web\Info;
7
+
8
+class Lion extends Command
9
+{
10
+    
11
+    protected $signature   = 'zoo:lion {--src= : csv path} ';
12
+    protected $description = 'lion eat tiger';
13
+    private   $codeManagementDb;
14
+    
15
+    public function __construct()
16
+    {
17
+        parent::__construct();
18
+        $this->codeManagementDb = new Info();
19
+    }
20
+    
21
+    /**
22
+     * 脚本入口
23
+     */
24
+    public function handle()
25
+    {
26
+        $src = $this->option('src');
27
+        echo "I am Lion\n";
28
+    }
29
+    
30
+}

+ 46
- 0
app/Console/Kernel.php View File

@@ -0,0 +1,46 @@
1
+<?php
2
+
3
+namespace App\Console;
4
+
5
+use Illuminate\Console\Scheduling\Schedule;
6
+use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
7
+
8
+class Kernel extends ConsoleKernel
9
+{
10
+    /**
11
+     * The Artisan commands provided by your application.
12
+     *
13
+     * @var array
14
+     */
15
+    protected $commands = [
16
+        // 腳本入口
17
+        Commands\Lion::class,
18
+    ];
19
+    
20
+    /**
21
+     * Define the application's command schedule.
22
+     *
23
+     * @param \Illuminate\Console\Scheduling\Schedule $schedule
24
+     *
25
+     * @return void
26
+     */
27
+    protected function schedule(Schedule $schedule)
28
+    {
29
+        // 腳本必須有序執行
30
+        // 針對沒有玩過的人,第一次設定鬧鐘後 24 小時後
31
+        //	IF > 腳本7先執行 > 由於該任務鬧鐘還沒響 > 所以不會被腳本挑出來處理 > 腳本8接著才執行 > 因此用戶可以自己去關鬧鐘 > DONE
32
+        //	IF > 腳本8先執行 > 腳本8將提示鬧鈴且修改狀態為未關閉 > 腳本7落入 corner 將鬧鐘關閉並註記為關閉次數為1 > 出問題
33
+        $schedule->call(function () {
34
+        });
35
+    }
36
+    
37
+    /**
38
+     * Register the Closure based commands for the application.
39
+     *
40
+     * @return void
41
+     */
42
+    protected function commands()
43
+    {
44
+        require base_path('routes/console.php');
45
+    }
46
+}

+ 65
- 0
app/Exceptions/Handler.php View File

@@ -0,0 +1,65 @@
1
+<?php
2
+
3
+namespace App\Exceptions;
4
+
5
+use Exception;
6
+use Illuminate\Auth\AuthenticationException;
7
+use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
8
+
9
+class Handler extends ExceptionHandler
10
+{
11
+    /**
12
+     * A list of the exception types that should not be reported.
13
+     *
14
+     * @var array
15
+     */
16
+    protected $dontReport = [
17
+        \Illuminate\Auth\AuthenticationException::class,
18
+        \Illuminate\Auth\Access\AuthorizationException::class,
19
+        \Symfony\Component\HttpKernel\Exception\HttpException::class,
20
+        \Illuminate\Database\Eloquent\ModelNotFoundException::class,
21
+        \Illuminate\Session\TokenMismatchException::class,
22
+        \Illuminate\Validation\ValidationException::class,
23
+    ];
24
+
25
+    /**
26
+     * Report or log an exception.
27
+     *
28
+     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
29
+     *
30
+     * @param  \Exception  $exception
31
+     * @return void
32
+     */
33
+    public function report(Exception $exception)
34
+    {
35
+        parent::report($exception);
36
+    }
37
+
38
+    /**
39
+     * Render an exception into an HTTP response.
40
+     *
41
+     * @param  \Illuminate\Http\Request  $request
42
+     * @param  \Exception  $exception
43
+     * @return \Illuminate\Http\Response
44
+     */
45
+    public function render($request, Exception $exception)
46
+    {
47
+        return parent::render($request, $exception);
48
+    }
49
+
50
+    /**
51
+     * Convert an authentication exception into an unauthenticated response.
52
+     *
53
+     * @param  \Illuminate\Http\Request  $request
54
+     * @param  \Illuminate\Auth\AuthenticationException  $exception
55
+     * @return \Illuminate\Http\Response
56
+     */
57
+    protected function unauthenticated($request, AuthenticationException $exception)
58
+    {
59
+        if ($request->expectsJson()) {
60
+            return response()->json(['error' => 'Unauthenticated.'], 401);
61
+        }
62
+
63
+        return redirect()->guest(route('login'));
64
+    }
65
+}

+ 70
- 0
app/FunMenu.php View File

@@ -0,0 +1,70 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use App\User;
6
+use Illuminate\Database\Eloquent\Model;
7
+use DB;
8
+
9
+class FunMenu extends Model
10
+{
11
+    protected $table = 'funmenu';
12
+
13
+    public function leftmenu($user_id)
14
+    {
15
+        $sql = "
16
+				SELECT
17
+                    `icon` as `icon`,
18
+					`MenuName` as `menuname`,
19
+					GROUP_CONCAT(`FunName` ORDER BY `FunMenuDetailCOrder` SEPARATOR ',') AS `submenuname`,
20
+					GROUP_CONCAT(`FunLink` ORDER BY `FunMenuDetailCOrder` SEPARATOR ',') AS `submenulink`
21
+				FROM
22
+					(
23
+						SELECT
24
+							*
25
+						FROM
26
+							`v_leftmenu`
27
+						WHERE
28
+							`FunId` IN (
29
+								SELECT
30
+									`Id`
31
+								FROM
32
+									`functions` AS `Functions_1`
33
+								WHERE
34
+									INSTR(
35
+										CONCAT(
36
+											',',
37
+											(
38
+												SELECT
39
+													GROUP_CONCAT(`FunList` SEPARATOR '') AS `submenuname`
40
+												FROM
41
+													`funusergroups`
42
+												WHERE
43
+													    CONCAT(',', `UsrList`, ',') LIKE CONCAT('%,', '".$user_id."', ',%')
44
+													AND `Valid` = 1
45
+												GROUP BY
46
+													`Valid`
47
+											),
48
+											','
49
+										),
50
+										CONCAT(
51
+											',',
52
+											`Id`,
53
+											','
54
+										)
55
+									) > 0
56
+							)
57
+					) A
58
+				GROUP BY
59
+					`menuname`
60
+				ORDER BY
61
+					`FunMenuCorder`
62
+				LIMIT
63
+					0, 30
64
+				;
65
+			";
66
+
67
+        $result = DB::select($sql);
68
+        return $result;
69
+    }
70
+}

+ 15
- 0
app/FunMenuDetail.php View File

@@ -0,0 +1,15 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class FunMenuDetail extends Model
8
+{
9
+    protected $table = 'funmenudetail';
10
+
11
+    public function getFunctions()
12
+    {
13
+        return $this->hasMany('App\Functions');
14
+    }
15
+}

+ 201
- 0
app/FunUserGroups.php View File

@@ -0,0 +1,201 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+use DB;
7
+
8
+class FunUserGroups extends Model
9
+{
10
+    protected $table = 'funusergroups';
11
+    
12
+    public function selectedUsrList($id)
13
+    {
14
+        $sql = "
15
+				SELECT 
16
+					* 
17
+				FROM 
18
+					`users`
19
+				WHERE 
20
+					`id` IN (
21
+						SELECT 
22
+							`id` 
23
+						FROM 
24
+							`users` 
25
+						AS 
26
+							`Funusers_1`
27
+						WHERE 
28
+							INSTR(
29
+								CONCAT(
30
+									',', 
31
+									(
32
+										SELECT 
33
+											`UsrList` 
34
+										FROM 
35
+											`funusergroups` 
36
+										WHERE 
37
+											`id`=".$id."
38
+									), 
39
+									','
40
+								), 
41
+								CONCAT(
42
+									',', 
43
+									`id`, 
44
+									',' 
45
+								)
46
+							) > 0 
47
+					)
48
+				;
49
+			";
50
+        $result = DB::select($sql);
51
+        return $result;
52
+    }
53
+    
54
+    public function unseletedUsrList($id)
55
+    {
56
+        $sql = "
57
+				SELECT 
58
+					* 
59
+				FROM 
60
+					`users`
61
+				WHERE 
62
+					`id` Not IN (
63
+						SELECT 
64
+							`id` 
65
+						FROM 
66
+							`users` 
67
+						AS 
68
+							`Funusers_1`
69
+						WHERE 
70
+							INSTR(
71
+								CONCAT(
72
+									',', 
73
+									(
74
+										SELECT 
75
+											`UsrList` 
76
+										FROM 
77
+											`funusergroups` 
78
+										WHERE 
79
+											`id`=".$id."
80
+									), 
81
+									','
82
+								), 
83
+								CONCAT(
84
+									',', 
85
+									`id`, 
86
+									','
87
+								)
88
+							) > 0 
89
+					)
90
+				;
91
+			";
92
+        $result = DB::select($sql);
93
+        return $result;
94
+    }
95
+    
96
+    public function unseletedFunList($id)
97
+    {
98
+        $sql = "
99
+				SELECT 
100
+					* 
101
+				FROM 
102
+					`functions`
103
+				WHERE 
104
+					`id` Not IN (
105
+						SELECT 
106
+							`id` 
107
+						FROM 
108
+							`functions` 
109
+						AS 
110
+							`Functions_1`
111
+						WHERE 
112
+							INSTR(
113
+								CONCAT(
114
+									',', 
115
+									(
116
+										SELECT 
117
+											`FunList` 
118
+										FROM 
119
+											`funusergroups` 
120
+										WHERE 
121
+											`id`=".$id."
122
+									), 
123
+									','
124
+								), 
125
+								CONCAT(
126
+									',', 
127
+									`id`, 
128
+									','
129
+								)
130
+							) > 0 
131
+					)
132
+				;
133
+			";
134
+        $result = DB::select($sql);
135
+        return $result;
136
+    }
137
+    
138
+    public function seletedFunList($id)
139
+    {
140
+        $sql = "
141
+				SELECT 
142
+					* 
143
+				FROM 
144
+					`functions`
145
+				WHERE 
146
+					`id` IN (
147
+						SELECT 
148
+							`id` 
149
+						FROM 
150
+							`functions` 
151
+						AS 
152
+							`Functions_1`
153
+						WHERE 
154
+							INSTR(
155
+								CONCAT(
156
+									',', 
157
+									(
158
+										SELECT 
159
+											`FunList` 
160
+										FROM 
161
+											`funusergroups` 
162
+										WHERE 
163
+											`id`=".$id."
164
+										-- ;
165
+									), 
166
+									','
167
+								), 
168
+								CONCAT(
169
+									',', 
170
+									`id`, 
171
+									',' 
172
+								)
173
+							) > 0 
174
+					)
175
+				;
176
+			";
177
+        $result = DB::select($sql);
178
+        return $result;
179
+    }
180
+    
181
+    public function operData($id)
182
+    {
183
+        $sql = "
184
+			SELECT
185
+				`id`,
186
+				`Name`,
187
+				`Valid`,
188
+				`created_at`,
189
+				`updated_at`,
190
+				
191
+                `Oid`
192
+			FROM
193
+				`funusergroups`
194
+			WHERE
195
+				`id`='".$id."'
196
+			;
197
+		";
198
+        $result = DB::select($sql);
199
+        return $result;
200
+    }
201
+}

+ 10
- 0
app/Functions.php View File

@@ -0,0 +1,10 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class Functions extends Model
8
+{
9
+    protected $table = 'functions';
10
+}

+ 32
- 0
app/Http/Controllers/Auth/ForgotPasswordController.php View File

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
7
+
8
+class ForgotPasswordController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Password Reset Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller is responsible for handling password reset emails and
16
+    | includes a trait which assists in sending these notifications from
17
+    | your application to your users. Feel free to explore this trait.
18
+    |
19
+    */
20
+
21
+    use SendsPasswordResetEmails;
22
+
23
+    /**
24
+     * Create a new controller instance.
25
+     *
26
+     * @return void
27
+     */
28
+    public function __construct()
29
+    {
30
+        $this->middleware('guest');
31
+    }
32
+}

+ 39
- 0
app/Http/Controllers/Auth/LoginController.php View File

@@ -0,0 +1,39 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\AuthenticatesUsers;
7
+
8
+class LoginController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Login Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller handles authenticating users for the application and
16
+    | redirecting them to your home screen. The controller uses a trait
17
+    | to conveniently provide its functionality to your applications.
18
+    |
19
+    */
20
+
21
+    use AuthenticatesUsers;
22
+
23
+    /**
24
+     * Where to redirect users after login.
25
+     *
26
+     * @var string
27
+     */
28
+    protected $redirectTo = '/backend';
29
+
30
+    /**
31
+     * Create a new controller instance.
32
+     *
33
+     * @return void
34
+     */
35
+    public function __construct()
36
+    {
37
+        $this->middleware('guest', ['except' => 'logout']);
38
+    }
39
+}

+ 71
- 0
app/Http/Controllers/Auth/RegisterController.php View File

@@ -0,0 +1,71 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\User;
6
+use App\Http\Controllers\Controller;
7
+use Illuminate\Support\Facades\Validator;
8
+use Illuminate\Foundation\Auth\RegistersUsers;
9
+
10
+class RegisterController extends Controller
11
+{
12
+    /*
13
+    |--------------------------------------------------------------------------
14
+    | Register Controller
15
+    |--------------------------------------------------------------------------
16
+    |
17
+    | This controller handles the registration of new users as well as their
18
+    | validation and creation. By default this controller uses a trait to
19
+    | provide this functionality without requiring any additional code.
20
+    |
21
+    */
22
+
23
+    use RegistersUsers;
24
+
25
+    /**
26
+     * Where to redirect users after registration.
27
+     *
28
+     * @var string
29
+     */
30
+    protected $redirectTo = '/backend';
31
+
32
+    /**
33
+     * Create a new controller instance.
34
+     *
35
+     * @return void
36
+     */
37
+    public function __construct()
38
+    {
39
+        $this->middleware('guest');
40
+    }
41
+
42
+    /**
43
+     * Get a validator for an incoming registration request.
44
+     *
45
+     * @param  array  $data
46
+     * @return \Illuminate\Contracts\Validation\Validator
47
+     */
48
+    protected function validator(array $data)
49
+    {
50
+        return Validator::make($data, [
51
+            'name' => 'required|max:255',
52
+            'email' => 'required|email|max:255|unique:users',
53
+            'password' => 'required|min:6|confirmed',
54
+        ]);
55
+    }
56
+
57
+    /**
58
+     * Create a new user instance after a valid registration.
59
+     *
60
+     * @param  array  $data
61
+     * @return User
62
+     */
63
+    protected function create(array $data)
64
+    {
65
+        return User::create([
66
+            'name' => $data['name'],
67
+            'email' => $data['email'],
68
+            'password' => bcrypt($data['password']),
69
+        ]);
70
+    }
71
+}

+ 39
- 0
app/Http/Controllers/Auth/ResetPasswordController.php View File

@@ -0,0 +1,39 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Auth;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Foundation\Auth\ResetsPasswords;
7
+
8
+class ResetPasswordController extends Controller
9
+{
10
+    /*
11
+    |--------------------------------------------------------------------------
12
+    | Password Reset Controller
13
+    |--------------------------------------------------------------------------
14
+    |
15
+    | This controller is responsible for handling password reset requests
16
+    | and uses a simple trait to include this behavior. You're free to
17
+    | explore this trait and override any methods you wish to tweak.
18
+    |
19
+    */
20
+
21
+    use ResetsPasswords;
22
+
23
+    /**
24
+     * Where to redirect users after resetting their password.
25
+     *
26
+     * @var string
27
+     */
28
+    protected $redirectTo = '/backend';
29
+
30
+    /**
31
+     * Create a new controller instance.
32
+     *
33
+     * @return void
34
+     */
35
+    public function __construct()
36
+    {
37
+        $this->middleware('guest');
38
+    }
39
+}

+ 119
- 0
app/Http/Controllers/Backend/DataManagement/InfoManagementController.php View File

@@ -0,0 +1,119 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend\DataManagement;
4
+
5
+use Illuminate\Http\Request;
6
+use App\Http\Services\Backend\DataManagement\InfoManagementService;
7
+use App\Http\Controllers\Controller;
8
+use App\Http\Services\CheckParamService;
9
+
10
+class InfoManagementController extends Controller
11
+{
12
+    
13
+    // 相關私有服務層調用器宣告
14
+    private $infoManagementSv;
15
+    private $checkParamSv;
16
+    
17
+    public function __construct()
18
+    {
19
+        // 建構服務層調用器
20
+        $this->infoManagementSv = new InfoManagementService();
21
+        $this->checkParamSv = new CheckParamService();
22
+        // 時區調整
23
+        date_default_timezone_set("Asia/Taipei");
24
+    }
25
+    
26
+    public function index(Request $request)
27
+    {
28
+        // 渲染
29
+        return view('admin.DataManagement.InfoManagement');
30
+    }
31
+    
32
+    public function grid(Request $request)
33
+    {
34
+        // 取得參數
35
+        $param = $_GET;
36
+        if ($param == null) exit();
37
+        $draw = $param["draw"]; //客戶端傳來的查詢次數,無條件回傳用以核對
38
+        $orderColumn = $param["order"][0]["column"] + 1; //前端從 0 開始送,但 mysql 從 1 開始算
39
+        $orderDir = $param["order"][0]["dir"];
40
+        $start = $param["start"];   // 頁碼
41
+        $length = $param["length"]; // 一頁多大
42
+        $searchValue = $param["search"]["value"];
43
+        //客製化搜尋欄位
44
+        $sDate = explode("\n", $param["columns"][1]["search"]["value"]);
45
+        $sDateStart = $sDate[0] ?? null;
46
+        $sDateFinal = $sDate[1] ?? null;
47
+        // 驗證
48
+        if ($sDateStart == "") $sDateStart = "1900-01-01";
49
+        if ($sDateFinal == "") $sDateFinal = "2050-12-31";
50
+        //資料庫
51
+        $recordsTotal = 0;
52
+        $result = $this->infoManagementSv->getInfos(
53
+            $recordsTotal,
54
+            $orderColumn,
55
+            $orderDir,
56
+            $start,
57
+            $length,
58
+            $searchValue,
59
+            $sDateStart,
60
+            $sDateFinal
61
+        );
62
+        // 整理返回資料
63
+        $data = array();
64
+        for ($i = 0; $i < count($result); $i++) {
65
+            $data[] = array(
66
+                //一般資料
67
+                $result[ $i ]["id"],
68
+                $result[ $i ]["image_uri"],
69
+                $result[ $i ]["nickname"],
70
+                $result[ $i ]["memo"],
71
+                $result[ $i ]["hash"],
72
+                $result[ $i ]["name"],
73
+                $result[ $i ]["tel"],
74
+                $result[ $i ]["email"],
75
+                $result[ $i ]["zone"],
76
+                $result[ $i ]["cdate"],
77
+            );
78
+        }
79
+        $json = array(
80
+            "draw"            => $draw,
81
+            "recordsTotal"    => $recordsTotal,
82
+            "recordsFiltered" => $recordsTotal, //其實還是填入所有筆數,本次筆數可從陣列取得
83
+            "data"            => $data,
84
+        );
85
+        
86
+        // 返回
87
+        return json_decode(json_encode($json, JSON_NUMERIC_CHECK), true);
88
+    }
89
+    
90
+    public function export(Request $request)
91
+    {
92
+        // 取得參數
93
+        $param = $_POST;
94
+        if ($param == null) exit();
95
+        // 驗證
96
+        if ($param['sDateStart'] == "") $param['sDateStart'] = "1900-01-01";
97
+        if ($param['sDateFinal'] == "") $param['sDateFinal'] = "2050-12-31";
98
+        // 製作
99
+        $title = [
100
+            'ID',
101
+            '圖片網址',
102
+            '暱稱',
103
+            '留言',
104
+            '標籤',
105
+            '姓名',
106
+            '電話',
107
+            '信箱',
108
+            '地區',
109
+            '媒體參數1',
110
+            '媒體參數2',
111
+            '媒體參數3',
112
+            '時間',
113
+            'IP',
114
+        ];
115
+        $result = $this->infoManagementSv->getExportInfo($param);
116
+        $this->infoManagementSv->downloadExcel($title, $result, date("YmdHis") . '-REPORT');
117
+    }
118
+    
119
+}

+ 105
- 0
app/Http/Controllers/Backend/FunmenusController.php View File

@@ -0,0 +1,105 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\Http\Requests;
8
+use App\Http\Controllers\Controller;
9
+use App\FunMenu;
10
+use App\FunMenuDetail;
11
+use Redirect;
12
+use Session;
13
+use Validator;
14
+
15
+class FunmenusController extends Controller
16
+{
17
+    public function index()
18
+    {
19
+        $tables = FunMenu::All();
20
+
21
+        return view('admin.funmenus', [
22
+            'tables' => $tables,
23
+        ]);
24
+    }
25
+
26
+    public function create()
27
+    {
28
+        return view('admin.funmenusedit', [
29
+            'datas' => "",
30
+        ]);
31
+    }
32
+
33
+    public function edit($id)
34
+    {
35
+        $datas = FunMenu::find($id);
36
+        return view('admin.funmenusedit', [
37
+            'datas' => $datas,
38
+        ]);
39
+    }
40
+
41
+    public function store(Request $request)
42
+    {
43
+        $validator = Validator::make($request->all(), [
44
+            'MenuName' => 'required|max:255',
45
+            'Corder' => 'required'
46
+
47
+        ]);
48
+        if ($validator->fails()) {
49
+            return Redirect::back()
50
+            ->withErrors($validator);
51
+        }
52
+        else
53
+        {
54
+            if ($request->mode == "insert")
55
+            {
56
+                $funmenu = new FunMenu;
57
+                $funmenu->icon = $request->icon;
58
+                $funmenu->MenuName = $request->MenuName;
59
+                $funmenu->Valid = ($request->Valid == "on") ? 1 : 0;
60
+                $funmenu->Corder = $request->Corder;
61
+                $funmenu->Oid = $request->user()->id;
62
+                $funmenu->save();
63
+            }
64
+            else
65
+            {
66
+                $funmenu = FunMenu::find($request->id);
67
+                $funmenu->icon = $request->icon;
68
+                $funmenu->MenuName = $request->MenuName;
69
+                $funmenu->Valid = ($request->Valid == "on") ? 1 : 0;
70
+                $funmenu->Corder = $request->Corder;
71
+                $funmenu->Oid = $request->user()->id;
72
+                $funmenu->save();
73
+            }
74
+        }
75
+
76
+        return Redirect::back();
77
+    }
78
+
79
+    public function delete($id)
80
+    {
81
+        if ($id == 1)
82
+        {
83
+            Session::flash('msg', 'This can not be delete!!');
84
+        }
85
+        else
86
+        {
87
+            $funmenudetails = FunMenuDetail::where('FunMenuId', '=', $id);
88
+
89
+            if ($funmenudetails->count() > 0)
90
+            {
91
+                Session::flash('msg', 'Must delete functions first!!');
92
+            }
93
+            else
94
+            {
95
+                $funmenu = FunMenu::find($id);
96
+                $funmenu->delete();
97
+
98
+
99
+                $funmenudetails->delete();
100
+            }
101
+        }
102
+
103
+        return Redirect::back();
104
+    }
105
+}

+ 108
- 0
app/Http/Controllers/Backend/FunmenusDetailController.php View File

@@ -0,0 +1,108 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\Http\Requests;
8
+use App\Http\Controllers\Controller;
9
+use App\FunMenu;
10
+use App\FunMenuDetail;
11
+use App\Functions;
12
+use Redirect;
13
+use Session;
14
+
15
+class FunmenusDetailController extends Controller
16
+{
17
+    public function index($menuid)
18
+    {
19
+        $parentname = FunMenu::select('MenuName')->where('id', '=', $menuid)->get();
20
+        $funmenus = FunMenuDetail::select('FunId')->where('FunMenuId', '=', $menuid)->get();
21
+        $tables = Functions::whereIn('id', $funmenus)->get();
22
+
23
+        return view('admin.funmenusdetail', [
24
+            'parentname' => $parentname,
25
+            'tables' => $tables,
26
+            'id' => $menuid,
27
+        ]);
28
+    }
29
+
30
+    public function create($menuid)
31
+    {
32
+        return view('admin.funmenusdetailedit', [
33
+            'datas' => "",
34
+            'datas2' => "",
35
+            'id' => $menuid,
36
+        ]);
37
+    }
38
+
39
+    public function edit($menuid, $id)
40
+    {
41
+        $datas = Functions::find($id);
42
+        $datas2 = FunMenuDetail::select('id','Corder')->where('FunMenuId', '=', $menuid)->where('FunId', '=', $id)->get();
43
+
44
+        return view('admin.funmenusdetailedit', [
45
+            'datas' => $datas,
46
+            'datas2' => $datas2[0],
47
+            'id' => $menuid,
48
+        ]);
49
+    }
50
+
51
+    public function store(Request $request, $menuid)
52
+    {
53
+        if ($request->mode == "insert")
54
+        {
55
+            $function = new Functions;
56
+            $function->FunName = $request->FunName;
57
+            $function->FunLink = $request->FunLink;
58
+            $function->FunDesc = $request->FunDesc;
59
+            $function->Valid = ($request->Valid == "on") ? 1 : 0;
60
+            $function->Oid = $request->user()->id;
61
+            $function->save();
62
+
63
+            $functiondetail = new FunMenuDetail;
64
+            $functiondetail->FunMenuId = $menuid;
65
+            $functiondetail->FunId = $function->id;
66
+            $functiondetail->Valid = ($request->Valid == "on") ? 1 : 0;
67
+            $functiondetail->Corder = $request->Corder;
68
+            $functiondetail->Oid = $request->user()->id;
69
+            $functiondetail->save();
70
+        }
71
+        else
72
+        {
73
+            $function = Functions::find($request->id);
74
+            $function->FunName = $request->FunName;
75
+            $function->FunLink = $request->FunLink;
76
+            $function->FunDesc = $request->FunDesc;
77
+            $function->Valid = ($request->Valid == "on") ? 1 : 0;
78
+            $function->Oid = $request->user()->id;
79
+            $function->save();
80
+
81
+            $functiondetail = FunMenuDetail::find($request->detailid);
82
+            $functiondetail->Valid = ($request->Valid == "on") ? 1 : 0;
83
+            $functiondetail->Corder = $request->Corder;
84
+            $functiondetail->Oid = $request->user()->id;
85
+            $functiondetail->save();
86
+        }
87
+
88
+        return Redirect::back();
89
+    }
90
+
91
+    public function delete($menuid, $id)
92
+    {
93
+        if ($menuid == 1)
94
+        {
95
+            Session::flash('msg', 'This can not be delete!!');
96
+        }
97
+        else
98
+        {
99
+            $function = Functions::find($id);
100
+            $function->delete();
101
+
102
+            $funmenudetail = FunMenuDetail::where('FunId', '=', $id);
103
+            $funmenudetail->delete();
104
+        }
105
+
106
+        return Redirect::back();
107
+    }
108
+}

+ 17
- 0
app/Http/Controllers/Backend/IndexController.php View File

@@ -0,0 +1,17 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\FunMenu;
8
+use App\Http\Requests;
9
+use App\Http\Controllers\Controller;
10
+
11
+class IndexController extends Controller
12
+{
13
+    public function index()
14
+    {
15
+        return view('admin.index');
16
+    }
17
+}

+ 35
- 0
app/Http/Controllers/Backend/PasswordController.php View File

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\User;
8
+use App\FunMenu;
9
+use App\Http\Requests;
10
+use App\Http\Controllers\Controller;
11
+use Session;
12
+use Redirect;
13
+
14
+class PasswordController extends Controller
15
+{
16
+    public function index()
17
+    {
18
+        return view('admin.password');
19
+    }
20
+
21
+    public function update(Request $request)
22
+    {
23
+        $this->validate($request, [
24
+            'qpwd1' => 'required|max:255',
25
+        ]);
26
+
27
+        $user = User::find($request->user()->id);
28
+        $user->password = bcrypt($request->qpwd1);
29
+        $user->save();
30
+
31
+        Session::flash('msg', 'Update Success!');
32
+
33
+        return Redirect::back();
34
+    }
35
+}

+ 118
- 0
app/Http/Controllers/Backend/UsergroupsController.php View File

@@ -0,0 +1,118 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\FunMenu;
8
+use App\FunUserGroups;
9
+use App\Http\Requests;
10
+use App\Http\Controllers\Controller;
11
+use Redirect;
12
+
13
+class UsergroupsController extends Controller
14
+{
15
+    public function index()
16
+    {
17
+        $tables = FunUserGroups::all();
18
+
19
+        return view('admin.usergroups', [
20
+            'tables' => $tables,
21
+        ]);
22
+    }
23
+
24
+    public function delete(Request $request, FunUserGroups $id)
25
+    {
26
+        if($id->id == 1)
27
+        {
28
+            return Redirect::back()->withErrors("Admin group can not be delete!");
29
+        }
30
+        else
31
+        {
32
+            $id->delete();
33
+        }
34
+        return Redirect::back();
35
+    }
36
+
37
+    public function create(Request $request)
38
+    {
39
+        $user_name = $request->user()->name;
40
+        $user_id = $request->user()->id;
41
+
42
+        $funmenu = new FunMenu;
43
+        $result = $funmenu->leftmenu($user_id);
44
+
45
+        $usergroup = new FunUserGroups;
46
+        $seleted_usrlist = $usergroup->selectedUsrList(9999);
47
+        $unseleted_usrlist = $usergroup->unseletedUsrList(9999);
48
+        $seleted_funlist = $usergroup->seletedFunList(9999);
49
+        $unseleted_funlist = $usergroup->unseletedFunList(9999);
50
+
51
+        return view('admin.usergroupsedit', [
52
+            'leftmenu' => $result,
53
+            'username' => $user_name,
54
+            'seleted_usrlist' => $seleted_usrlist,
55
+            'unseleted_usrlist' => $unseleted_usrlist,
56
+            'seleted_funlist' => $seleted_funlist,
57
+            'unseleted_funlist' => $unseleted_funlist,
58
+            'operdata' => "",
59
+
60
+        ]);
61
+    }
62
+
63
+    public function edit(Request $request, $id)
64
+    {
65
+        $user_name = $request->user()->name;
66
+        $user_id = $request->user()->id;
67
+        $fun_id = $id;
68
+
69
+        $funmenu = new FunMenu;
70
+        $result = $funmenu->leftmenu($user_id);
71
+
72
+        $usergroup = new FunUserGroups;
73
+        $seleted_usrlist = $usergroup->selectedUsrList($fun_id);
74
+        $unseleted_usrlist = $usergroup->unseletedUsrList($fun_id);
75
+        $seleted_funlist = $usergroup->seletedFunList($fun_id);
76
+        $unseleted_funlist = $usergroup->unseletedFunList($fun_id);
77
+        $operdata = $usergroup->operData($fun_id);
78
+
79
+        return view('admin.usergroupsedit', [
80
+            'leftmenu' => $result,
81
+            'username' => $user_name,
82
+            'seleted_usrlist' => $seleted_usrlist,
83
+            'unseleted_usrlist' => $unseleted_usrlist,
84
+            'seleted_funlist' => $seleted_funlist,
85
+            'unseleted_funlist' => $unseleted_funlist,
86
+            'operdata' => $operdata,
87
+
88
+        ]);
89
+    }
90
+
91
+    public function store(Request $request)
92
+    {
93
+        if ($request->mode == "insert")
94
+        {
95
+            $usergroup = new FunUserGroups;
96
+            $usergroup->Name = $request->Name;
97
+            $usergroup->FunList = $request->hidfunlist;
98
+            $usergroup->UsrList = $request->hidusrlist;
99
+            $usergroup->Valid = ($request->Valid == "on") ? 1 : 0;
100
+            $usergroup->Oid = $request->user()->id;
101
+            $usergroup->save();
102
+
103
+            return redirect('/backend/Usergroups');
104
+        }
105
+        else
106
+        {
107
+            $usergroup = FunUserGroups::find($request->id);
108
+            $usergroup->Name = $request->Name;
109
+            $usergroup->FunList = $request->hidfunlist;
110
+            $usergroup->UsrList = $request->hidusrlist;
111
+            $usergroup->Valid = ($request->Valid == "on") ? 1 : 0;
112
+            $usergroup->Oid = $request->user()->id;
113
+            $usergroup->save();
114
+
115
+            return redirect('/backend/Usergroups');
116
+        }
117
+    }
118
+}

+ 76
- 0
app/Http/Controllers/Backend/UsersController.php View File

@@ -0,0 +1,76 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Backend;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+use App\FunMenu;
8
+use App\User;
9
+use App\Http\Requests;
10
+use App\Http\Controllers\Controller;
11
+use Redirect;
12
+
13
+class UsersController extends Controller
14
+{
15
+    public function index()
16
+    {
17
+        $tables = User::all();
18
+        
19
+        return view('admin.users', [
20
+            'tables' => $tables,
21
+        ]);
22
+    }
23
+    
24
+    public function create(Request $request)
25
+    {
26
+        return view('admin.usersedit', [
27
+            'operdata' => "",
28
+        ]);
29
+    }
30
+    
31
+    public function edit($id)
32
+    {
33
+        $usr_id = $id;
34
+        $operdata = User::find($usr_id);
35
+        
36
+        return view('admin.usersedit', [
37
+            'operdata' => $operdata,
38
+        ]);
39
+    }
40
+    
41
+    public function store(Request $request)
42
+    {
43
+        //$role = \App\Role::where('name', 'admin')->first();
44
+        
45
+        if ($request->mode == "insert") {
46
+            $user = new User;
47
+            $user->name = $request->name;
48
+            $user->email = $request->email;
49
+            $user->password = bcrypt($request->password);
50
+            $user->save();
51
+            
52
+            //$user->attachRole($role);
53
+            return redirect('/backend/Users');
54
+        } else {
55
+            $user = User::find($request->id);
56
+            $user->name = $request->name;
57
+            if ($request->password != "") {
58
+                $user->password = bcrypt($request->password);
59
+            }
60
+            $user->save();
61
+            
62
+            return redirect('/backend/Users');
63
+        }
64
+    }
65
+    
66
+    public function delete(Request $request, User $id)
67
+    {
68
+        if ($id->email == "admin@gmail.com") {
69
+            return Redirect::back()->withErrors("Administrator can not be delete!");
70
+        } else {
71
+            $id->delete();
72
+        }
73
+        
74
+        return Redirect::back();
75
+    }
76
+}

+ 13
- 0
app/Http/Controllers/Controller.php View File

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers;
4
+
5
+use Illuminate\Foundation\Bus\DispatchesJobs;
6
+use Illuminate\Routing\Controller as BaseController;
7
+use Illuminate\Foundation\Validation\ValidatesRequests;
8
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
9
+
10
+class Controller extends BaseController
11
+{
12
+    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
13
+}

+ 28
- 0
app/Http/Controllers/HomeController.php View File

@@ -0,0 +1,28 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers;
4
+
5
+use Illuminate\Http\Request;
6
+
7
+class HomeController extends Controller
8
+{
9
+    /**
10
+     * Create a new controller instance.
11
+     *
12
+     * @return void
13
+     */
14
+    public function __construct()
15
+    {
16
+        $this->middleware('auth');
17
+    }
18
+
19
+    /**
20
+     * Show the application dashboard.
21
+     *
22
+     * @return \Illuminate\Http\Response
23
+     */
24
+    public function index()
25
+    {
26
+        return view('home');
27
+    }
28
+}

+ 184
- 0
app/Http/Controllers/Web/AiFaceController.php View File

@@ -0,0 +1,184 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Web;
4
+
5
+use App\Http\Controllers\Controller;
6
+use App\Http\Services\Web\AiFaceService;
7
+use Illuminate\Http\Request;
8
+use Illuminate\Support\Facades\Validator;
9
+use Intervention\Image\ImageManagerStatic as Image;
10
+use Illuminate\Support\Facades\Storage;
11
+use Illuminate\Http\File;
12
+use Log;
13
+
14
+class AiFaceController extends Controller
15
+{
16
+    
17
+    private $aiFaceSv;
18
+    
19
+    public function __construct()
20
+    {
21
+        $this->aiFaceSv = new AiFaceService();
22
+
23
+    }
24
+
25
+    // 人臉融合
26
+    public function faceMerge(Request $request)
27
+    {
28
+        $preData = $request->all();
29
+        $accessToken = '';
30
+        $today = date("Y-m-d");
31
+        
32
+        $tokenData = $this->aiFaceSv->getTokenData();
33
+        
34
+        if (!isset($tokenData)) {
35
+            
36
+            $accessToken = $this->aiFaceSv->getAccessToken()->access_token;
37
+            // \Log::info('1111 accessToken: '.$accessToken);
38
+        
39
+            $this->aiFaceSv->setTokenByDay($accessToken,'insert');
40
+
41
+        } else if (isset($tokenData)&&($tokenData->updateDate!=$today)) {
42
+
43
+            $accessToken = $this->aiFaceSv->getAccessToken()->access_token;
44
+            // \Log::info('2222 accessToken: '.$accessToken);
45
+
46
+            $this->aiFaceSv->setTokenByDay($accessToken,'update');
47
+
48
+        } else {
49
+
50
+            $accessToken = $tokenData->accessToken;
51
+            // \Log::info('3333 accessToken: '.$accessToken);
52
+
53
+        }
54
+        // \Log::info('accessToken: '.$accessToken);
55
+        $data = $this->aiFaceSv->getMergeData($accessToken, $preData);
56
+
57
+        return response()->json($data);
58
+    }
59
+    
60
+    // save string to db
61
+    public function saveData(Request $request)
62
+    {
63
+        $title = $request->input('title', 'test title');
64
+        $desc = $request->input('desc', 'test description');
65
+
66
+        $shareId = $this->aiFaceSv->getShareId();
67
+        $shareId += 1;
68
+
69
+        $imageName = $shareId.'.jpg';
70
+
71
+        $this->aiFaceSv->saveShareData($shareId, $title, $desc, $imageName);
72
+
73
+        $data = [
74
+            'id' => $shareId,
75
+        ];
76
+
77
+        return $data;
78
+    }
79
+
80
+    // save image to server
81
+    public function saveImg(Request $request)
82
+    {
83
+        $id = $request->input('id', '');
84
+        $imageO = $request->input('image', '');
85
+        
86
+        // \Log::info('imageO: '.$imageO);
87
+        // \Log::info('id: '.$id);
88
+        
89
+        $s3Path = $this->savePhotoToS3($id, $imageO);
90
+
91
+        // 儲存圖片並產生網址 - 儲存到 local
92
+        
93
+        if (!file_exists('faceMergeImg')) mkdir('faceMergeImg', 0777, true);
94
+
95
+        $imageName = $id.'.jpg';
96
+
97
+        $imgPath = public_path('faceMergeImg/' . $imageName);
98
+
99
+        $imgObj = Image::make($imageO)->save($imgPath);
100
+        $imgUrl = url('faceMergeImg/' . $imageName);
101
+
102
+        // \Log::info('s3Path: '.$s3Path);
103
+
104
+        $data = [
105
+            'imgUrl' => $s3Path,
106
+        ];
107
+
108
+        return $data;
109
+    }
110
+
111
+    // get meta info from db to front
112
+    public function getMeta(Request $request)
113
+    {
114
+        $id = $request->input('id', '');
115
+        $kol = $request->input('kol', '');
116
+
117
+        $shareData = $this->aiFaceSv->getShareData($id);
118
+        // \Log::info($shareData);
119
+        
120
+        return view('shareToFacebook', [
121
+            'webTitle' => $shareData['title'],
122
+            'webDesc' => $shareData['desc'],
123
+            'imagePath' => url('faceMergeImg/' . $shareData['imageName']),
124
+            'kol' => $kol,
125
+        ]);
126
+
127
+    }
128
+
129
+    /**
130
+     * 儲存圖片到 S3
131
+     */
132
+    private function savePhotoToS3($id, $photo)
133
+    {
134
+        $folder = 'faceMergeImg';
135
+        // \Log::info('folder: '.$folder);
136
+        
137
+        // 儲存路徑
138
+        // 原圖
139
+        $imgNameOrig = $id . '-orig.jpg';
140
+        
141
+        $imgPathOrig = public_path('faceMergeImg/' . $imgNameOrig);
142
+        // 縮圖
143
+        $imgName = str_replace('-orig', '', $imgNameOrig);
144
+        $imgPath = str_replace('-orig', '', $imgPathOrig);
145
+        // 暫存本機端
146
+        $imgObj = Image::make($photo)->save($imgPath);
147
+        
148
+
149
+        // 儲存 S3
150
+        $s3Path = Storage::disk('s3')->putFileAs($folder, new File($imgPath), $imgName);
151
+        $s3Url = Storage::disk('s3')->url($s3Path);
152
+
153
+        unlink($imgPath);
154
+        // unlink($imgPathOrig);
155
+
156
+        return $s3Url;
157
+    }
158
+
159
+    protected function validateInput($rules, $messages)
160
+    {
161
+        $result = true;
162
+        $err_msg = "";
163
+
164
+        $validate = Validator::make(request()->all(), $rules, $messages);
165
+
166
+        if ($validate->fails()) {
167
+            $result = false;
168
+            $err = $validate->errors();
169
+            foreach ($err->all() as $item) {
170
+                $err_msg .= $item . "\n";
171
+            }
172
+        }
173
+
174
+        return (object)[
175
+            'result' => $result,
176
+            'errMsg' => $err_msg
177
+        ];
178
+    }
179
+    public function test()
180
+    {
181
+        return '123';
182
+    }
183
+
184
+}

+ 184
- 0
app/Http/Controllers/Web/Api2021Controller.php View File

@@ -0,0 +1,184 @@
1
+<?php
2
+
3
+namespace App\Http\Controllers\Web;
4
+
5
+use App\Http\Controllers\Controller;
6
+use Illuminate\Http\Request;
7
+use App\Http\Services\Web\Api2021Service;
8
+use Illuminate\Support\Facades\Validator;
9
+use App\Http\Services\ConstDef\GeneralConst;
10
+use App\Http\Services\CheckParamService;
11
+use Gregwar\Captcha\CaptchaBuilder;
12
+use Aws\CloudFront;
13
+use Illuminate\Support\Str;
14
+use Ramsey\Uuid\Uuid;
15
+
16
+class Api2021Controller extends Controller
17
+{
18
+    
19
+    private $aSv;
20
+    private $checkParamSv;
21
+    private $captcha;
22
+    
23
+    public function __construct()
24
+    {
25
+        session_start();
26
+        $this->aSv = new Api2021Service();
27
+        $this->checkParamSv = new CheckParamService();
28
+        $this->captcha = new CaptchaBuilder();
29
+        $this->captcha->build();
30
+    }
31
+    
32
+    public function setdoc(Request $request)
33
+    {
34
+        // 參數驗證
35
+        $messages = [
36
+            'doc.required' => '圖片必填',
37
+        ];
38
+        $validate = Validator::make($request->all(), [
39
+            'doc' => 'required',
40
+        ], $messages);
41
+        if ($validate->fails()) {
42
+            $err = $validate->errors();
43
+            $err_msg = "";
44
+            foreach ($err->all() as $item) {
45
+                $err_msg .= $item . "\n";
46
+            }
47
+            
48
+            return response()->json(["succ" => false, "err" => $err_msg]);
49
+        } else {
50
+            $doc = $request->input('doc', '');
51
+            $doc = explode(',', $doc);
52
+            $doc = base64_decode($doc[1]);
53
+        }
54
+        $data = $this->aSv->setdoc($doc);
55
+        
56
+        // 返回
57
+        return response()->json(["succ" => true, "err" => '', "data" => $data]);
58
+    }
59
+    
60
+    public function setinfo(Request $request)
61
+    {
62
+        // 參數驗證
63
+        $messages = [
64
+            'image_uri.nullable'    => '',
65
+            'image_uri.regex'       => '圖片路徑格式錯誤',
66
+            'nickname.required'     => '暱稱必填',
67
+            'nickname.max'          => '暱稱最多64字', // 格式的一半
68
+            'memo.nullable'         => '',
69
+            'memo.max'              => '留言最多1024字', // 格式的一半
70
+            'hash.nullable'         => '',
71
+            'hash.max'              => 'TAG最多64字', // 格式的一半
72
+            'name.required'         => '姓名必填',
73
+            'name.max'              => '姓名最多32字', // 格式的一半
74
+            'tel.required'          => '電話必填',
75
+            'tel.max'               => '電話最多32字',
76
+            'email.required'        => '信箱必填',
77
+            'email.max'             => '信箱最多128字',
78
+            'email.email'           => '信箱格式錯誤',
79
+            'zone.required'         => '地區必填',
80
+            'zone.max'              => '地區最多16字', // 格式的一半
81
+            'utm_source.nullable'   => '',
82
+            'utm_source.max'        => 'utm_source 20字以內',
83
+            'utm_medium.nullable'   => '',
84
+            'utm_medium.max'        => 'utm_medium 20字以內',
85
+            'utm_campaign.nullable' => '',
86
+            'utm_campaign.max'      => 'utm_campaign 20字以內',
87
+        ];
88
+        $validate = Validator::make($request->all(), [
89
+            'image_uri'    => ['regex:/^pr(e|o)\/202(1|2)-[0-9]{2}-[0-9]{2}\/[0-9]{10}\.jpg$/'],
90
+            'nickname'     => 'max:128',
91
+            'memo'         => 'max:2048',
92
+            'hash'         => 'max:128',
93
+            'name'         => 'required|max:64',
94
+            'tel'          => 'required|max:32',
95
+            'email'        => 'required|max:128|email',
96
+            'zone'         => 'required|max:32',
97
+            'utm_source'   => 'nullable|max:20',
98
+            'utm_medium'   => 'nullable|max:20',
99
+            'utm_campaign' => 'nullable|max:20',
100
+        ], $messages);
101
+        if ($validate->fails()) {
102
+            $err = $validate->errors();
103
+            $err_msg = "";
104
+            foreach ($err->all() as $item) {
105
+                $err_msg .= $item . "\n";
106
+            }
107
+            
108
+            return response()->json(["succ" => false, "err" => $err_msg]);
109
+        } else {
110
+            $info = [
111
+                'image_uri'    => $request->input('image_uri', ''),
112
+                'nickname'     => $request->input('nickname', '') ?? '',
113
+                'memo'         => $request->input('memo', ''),
114
+                'hash'         => $request->input('hash', ''),
115
+                'name'         => $request->input('name', ''),
116
+                'tel'          => $request->input('tel', ''),
117
+                'email'        => $request->input('email', ''),
118
+                'zone'         => $request->input('zone', ''),
119
+                'utm_source'   => $request->input('utm_source', ''),
120
+                'utm_medium'   => $request->input('utm_medium', ''),
121
+                'utm_campaign' => $request->input('utm_campaign', ''),
122
+            ];
123
+        }
124
+        // 業務邏輯: 保存訊息
125
+        $this->aSv->setinfo($info);
126
+        
127
+        // 返回
128
+        return response()->json(["succ" => true, "err" => '']);
129
+    }
130
+    
131
+    public function counterGet($type)
132
+    {
133
+        // 業務邏輯: 保存訊息
134
+        $cnt = $this->aSv->counterGet($type);
135
+        
136
+        // 返回
137
+        return response()->json(["succ" => true, "err" => '', "cnt" => $cnt]);
138
+    }
139
+    
140
+    public function counterSet($type)
141
+    {
142
+        // 業務邏輯: 設定訊息
143
+        $this->aSv->counterSet($type);
144
+        
145
+        // 返回
146
+        return response()->json(["succ" => true, "err" => '']);
147
+    }
148
+    
149
+    public function reset()
150
+    {
151
+        $this->aSv->reset();
152
+        
153
+        // 返回
154
+        return response()->json(["succ" => true, "err" => '']);
155
+    }
156
+
157
+    public function cdnInvalidation(Request $request)
158
+    {
159
+        $path = $request->input('path');
160
+
161
+        $client = new CloudFront\CloudFrontClient([
162
+            'region'  => env('AWS_S3_REGION'),
163
+            'version' => 'latest',
164
+            'credentials' => [
165
+                'key'    => env('AWS_CDN_KEY'),
166
+                'secret' => env('AWS_CDN_SECRET'),
167
+            ],
168
+        ]);
169
+
170
+        $result = $client->createInvalidation([
171
+            'DistributionId' => env('AWS_CDN_ID'),
172
+            'InvalidationBatch' => [
173
+                'CallerReference' => time() . Uuid::uuid4()->toString(),
174
+                'Paths' => [
175
+                    'Items' => [$path],
176
+                    'Quantity' => 1,
177
+                ],
178
+            ],
179
+        ]);
180
+
181
+        return '進行中,根據檔案數量請等待數秒至數分鐘不等。';
182
+    }
183
+
184
+}

+ 63
- 0
app/Http/Kernel.php View File

@@ -0,0 +1,63 @@
1
+<?php
2
+
3
+namespace App\Http;
4
+
5
+use Illuminate\Foundation\Http\Kernel as HttpKernel;
6
+
7
+class Kernel extends HttpKernel
8
+{
9
+    /**
10
+     * The application's global HTTP middleware stack.
11
+     *
12
+     * These middleware are run during every request to your application.
13
+     *
14
+     * @var array
15
+     */
16
+    protected $middleware = [
17
+        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
18
+        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
19
+        \App\Http\Middleware\TrimStrings::class,
20
+        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
21
+        \App\Http\Middleware\AddHeaders::class,
22
+
23
+    ];
24
+
25
+    /**
26
+     * The application's route middleware groups.
27
+     *
28
+     * @var array
29
+     */
30
+    protected $middlewareGroups = [
31
+        'web' => [
32
+            \App\Http\Middleware\EncryptCookies::class,
33
+            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
34
+            \Illuminate\Session\Middleware\StartSession::class,
35
+            // \Illuminate\Session\Middleware\AuthenticateSession::class,
36
+            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
37
+            \App\Http\Middleware\VerifyCsrfToken::class,
38
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
39
+            \App\Http\Middleware\AddHeaders::class,
40
+        ],
41
+
42
+        'api' => [
43
+            'throttle:60,1',
44
+            'bindings',
45
+        ],
46
+    ];
47
+
48
+    /**
49
+     * The application's route middleware.
50
+     *
51
+     * These middleware may be assigned to groups or used individually.
52
+     *
53
+     * @var array
54
+     */
55
+    protected $routeMiddleware = [
56
+        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
57
+        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
58
+        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
59
+        'can' => \Illuminate\Auth\Middleware\Authorize::class,
60
+        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
61
+        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
62
+    ];
63
+}

+ 15
- 0
app/Http/Middleware/AddHeaders.php View File

@@ -0,0 +1,15 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Closure;
6
+
7
+class AddHeaders
8
+{
9
+    public function handle($request, Closure $next)
10
+    {
11
+        $response = $next($request);
12
+        $response->header('Access-Control-Allow-Origin', '*'); // 允許跨域
13
+        return $response;
14
+    }
15
+}

+ 17
- 0
app/Http/Middleware/EncryptCookies.php View File

@@ -0,0 +1,17 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
6
+
7
+class EncryptCookies extends BaseEncrypter
8
+{
9
+    /**
10
+     * The names of the cookies that should not be encrypted.
11
+     *
12
+     * @var array
13
+     */
14
+    protected $except = [
15
+        //
16
+    ];
17
+}

+ 26
- 0
app/Http/Middleware/RedirectIfAuthenticated.php View File

@@ -0,0 +1,26 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Closure;
6
+use Illuminate\Support\Facades\Auth;
7
+
8
+class RedirectIfAuthenticated
9
+{
10
+    /**
11
+     * Handle an incoming request.
12
+     *
13
+     * @param  \Illuminate\Http\Request  $request
14
+     * @param  \Closure  $next
15
+     * @param  string|null  $guard
16
+     * @return mixed
17
+     */
18
+    public function handle($request, Closure $next, $guard = null)
19
+    {
20
+        if (Auth::guard($guard)->check()) {
21
+            return redirect('/backend');
22
+        }
23
+
24
+        return $next($request);
25
+    }
26
+}

+ 18
- 0
app/Http/Middleware/TrimStrings.php View File

@@ -0,0 +1,18 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Illuminate\Foundation\Http\Middleware\TrimStrings as BaseTrimmer;
6
+
7
+class TrimStrings extends BaseTrimmer
8
+{
9
+    /**
10
+     * The names of the attributes that should not be trimmed.
11
+     *
12
+     * @var array
13
+     */
14
+    protected $except = [
15
+        'password',
16
+        'password_confirmation',
17
+    ];
18
+}

+ 21
- 0
app/Http/Middleware/VerifyCsrfToken.php View File

@@ -0,0 +1,21 @@
1
+<?php
2
+
3
+namespace App\Http\Middleware;
4
+
5
+use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
6
+
7
+class VerifyCsrfToken extends BaseVerifier
8
+{
9
+    /**
10
+     * The URIs that should be excluded from CSRF verification.
11
+     *
12
+     * @var array
13
+     */
14
+    protected $except = [
15
+        '*export',
16
+        '*setinfo',
17
+        '*setdoc',
18
+        '*counter/*',
19
+        'web/*',
20
+    ];
21
+}

+ 152
- 0
app/Http/Services/Backend/DataManagement/InfoManagementService.php View File

@@ -0,0 +1,152 @@
1
+<?php
2
+
3
+namespace App\Http\Services\Backend\DataManagement;
4
+
5
+use App\Http\Services\ConstDef\GeneralConst;
6
+use App\Models\Web\Info;
7
+use PhpOffice\PhpSpreadsheet\IOFactory;
8
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
9
+
10
+class InfoManagementService
11
+{
12
+    // 相關私有 model 調用器宣告
13
+    private $infoManagementDb;
14
+    
15
+    public function __construct()
16
+    {
17
+        // 建構 model 調用器
18
+        $this->infoManagementDb = new Info();
19
+    }
20
+    
21
+    public function getInfos(
22
+        &$cnt = 0,
23
+        $orderColumn,
24
+        $orderDir,
25
+        $start,
26
+        $length,
27
+        $searchValue,
28
+        $sDateStart,
29
+        $sDateFinal
30
+    )
31
+    {
32
+        $infos = $this->infoManagementDb
33
+            ->select([
34
+                'id',
35
+                \DB::raw("
36
+                    (CASE
37
+                        WHEN image_uri <> '' THEN
38
+                            CONCAT(
39
+                                '<a href=\"" . env('AWS_S3_URI') . "', image_uri, '\" target=\"_blank\">',
40
+                                '<img src=\"" . env('AWS_S3_URI') . "', image_uri, '\" width=\"100\" height=\"100\">',
41
+                                '</a>'
42
+                            )
43
+                         ELSE 'X'
44
+                    END) as image_uri
45
+                "),
46
+                'nickname',
47
+                'memo',
48
+                'hash',
49
+                'name',
50
+                'tel',
51
+                'email',
52
+                'zone',
53
+                'cdate',
54
+            ]);
55
+        // 過濾搜尋條件
56
+        if ($sDateStart != '') $infos = $infos->where('cdate', '>=', $sDateStart . ' 00:00:00');
57
+        if ($sDateFinal != '') $infos = $infos->where('cdate', '<=', $sDateFinal . ' 23:59:59');
58
+        // 取總筆數
59
+        $cnt = $infos->count();
60
+        // 排序
61
+        $infos = $infos
62
+            ->orderByRaw((int)$orderColumn . ' ' . $orderDir);
63
+        // 彙整
64
+        // 分頁
65
+        $infos = $infos
66
+            ->skip($start)->take($length);
67
+        // 實際取資料
68
+        $infos = $infos
69
+            ->get()
70
+            ->toArray();
71
+        
72
+        // 整理返回值並返回
73
+        return $infos;
74
+    }
75
+    
76
+    public function getExportInfo($param)
77
+    {
78
+        $infos = $this->infoManagementDb
79
+            ->select([
80
+                'id',
81
+                \DB::raw("
82
+                    (CASE
83
+                        WHEN image_uri <> '' THEN
84
+                            CONCAT(
85
+                                '" . env('AWS_S3_URI') . "', image_uri
86
+                            )
87
+                         ELSE 'X'
88
+                    END) as image_uri
89
+                "),
90
+                'nickname',
91
+                'memo',
92
+                'hash',
93
+                'name',
94
+                'tel',
95
+                'email',
96
+                'zone',
97
+                'utm_source',
98
+                'utm_medium',
99
+                'utm_campaign',
100
+                'cdate',
101
+                'ip',
102
+            ]);
103
+        // 過濾搜尋條件
104
+        if ($param["sDateStart"] != '') $infos = $infos->where('cdate', '>=', $param["sDateStart"] . ' 00:00:00');
105
+        if ($param["sDateFinal"] != '') $infos = $infos->where('cdate', '<=', $param["sDateFinal"] . ' 23:59:59');
106
+        // 實際取資料
107
+        $infos = $infos
108
+            ->get()
109
+            ->toArray();
110
+        
111
+        // 整理返回值並返回
112
+        return $infos;
113
+    }
114
+    
115
+    public function downloadExcel($titles = [], $datas = [], $fileName = 'simple')
116
+    {
117
+        $spreadsheet = new Spreadsheet();
118
+        ini_set('memory_limit', '1024M');
119
+        ini_set("max_execution_time", "600");
120
+        $spreadsheet->getActiveSheet()
121
+            ->fromArray(
122
+                $titles, // The data to set
123
+                null, // Array values with this value will not be set
124
+                'A1' // Top left coordinate of the worksheet range where we want to set these values (default is A1)
125
+            );
126
+        
127
+        $spreadsheet->getActiveSheet()
128
+            ->fromArray(
129
+                $datas, // The data to set
130
+                null, // Array values with this value will not be set
131
+                'A2' // Top left coordinate of the worksheet range where we want to set these values (default is A1)
132
+            );
133
+        
134
+        // Redirect output to a client’s web browser (Xlsx)
135
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
136
+        header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"');
137
+        header('Cache-Control: max-age=0');
138
+        // If you're serving to IE 9, then the following may be needed
139
+        header('Cache-Control: max-age=1');
140
+        
141
+        // If you're serving to IE over SSL, then the following may be needed
142
+        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
143
+        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
144
+        header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
145
+        header('Pragma: public'); // HTTP/1.0
146
+        
147
+        $writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
148
+        $writer->save('php://output');
149
+        exit;
150
+    }
151
+    
152
+}

+ 92
- 0
app/Http/Services/CheckParamService.php View File

@@ -0,0 +1,92 @@
1
+<?php
2
+
3
+namespace App\Http\Services;
4
+
5
+use DateTime;
6
+
7
+class CheckParamService
8
+{
9
+    
10
+    public function __construct()
11
+    {
12
+    }
13
+    
14
+    public function LenMToN($str, $m, $n)
15
+    {
16
+        if (mb_strlen($str) >= $m && mb_strlen($str) <= $n) {
17
+            return true;
18
+        } else {
19
+            return false;
20
+        }
21
+    }
22
+    
23
+    public function isascii($str)
24
+    {
25
+        if (mb_detect_encoding($str) == "ASCII") {
26
+            return true;
27
+        } else {
28
+            return false;
29
+        }
30
+    }
31
+    
32
+    public function isengnum($str)
33
+    {
34
+        return (preg_match("/^[a-zA-Z0-9]+$/", $str) == 1);
35
+    }
36
+    
37
+    public function isnum($str)
38
+    {
39
+        return (preg_match("/^[0-9]+$/", $str) == 1);
40
+    }
41
+    
42
+    public function isPhone($str)
43
+    {
44
+        return (preg_match("/^09[0-9]{8}$/", $str));
45
+    }
46
+    
47
+    public function isImei($imei)
48
+    {
49
+        // Should be 15 digits
50
+        if (strlen($imei) != 15 || !ctype_digit($imei))
51
+            return false;
52
+        // Get digits
53
+        $digits = str_split($imei);
54
+        // Remove last digit, and store it
55
+        $imei_last = array_pop($digits);
56
+        // Create log
57
+        $log = array();
58
+        // Loop through digits
59
+        foreach ($digits as $key => $n) {
60
+            // If key is odd, then count is even
61
+            if ($key & 1) {
62
+                // Get double digits
63
+                $double = str_split($n * 2);
64
+                // Sum double digits
65
+                $n = array_sum($double);
66
+            }
67
+            // Append log
68
+            $log[] = $n;
69
+        }
70
+        // Sum log & multiply by 9
71
+        $sum = array_sum($log) * 9;
72
+        
73
+        // Compare the last digit with $imei_last
74
+        return substr($sum, -1) == $imei_last;
75
+    }
76
+    
77
+    public function validateDate($date, $format = 'Y-m-d H:i:s')
78
+    {
79
+        $d = DateTime::createFromFormat($format, $date);
80
+        
81
+        return $d && $d->format($format) == $date;
82
+    }
83
+    
84
+    public function RemoveChars($str, $chars)
85
+    {
86
+        $chars = str_split($chars, 1);
87
+        for ($i = 0; $i < count($chars); $i++) $str = str_replace($chars[ $i ], "", $str);
88
+        
89
+        return $str;
90
+    }
91
+    
92
+}

+ 41
- 0
app/Http/Services/ConstDef/GeneralConst.php View File

@@ -0,0 +1,41 @@
1
+<?php
2
+
3
+namespace App\Http\Services\ConstDef;
4
+
5
+class GeneralConst
6
+{
7
+    
8
+    const GENDER_MALE   = 'M';
9
+    const GENDER_FEMALE = 'F';
10
+    public static $genderArr = array(
11
+        self::GENDER_MALE,
12
+        self::GENDER_FEMALE,
13
+    );
14
+    public static $genderMap = array(
15
+        self::GENDER_MALE   => "男",
16
+        self::GENDER_FEMALE => "女",
17
+    );
18
+    
19
+    const EDU_TYPE_GRAD = 'G';
20
+    const EDU_TYPE_FAIL = 'F';
21
+    public static $edutypeArr = array(
22
+        self::EDU_TYPE_GRAD,
23
+        self::EDU_TYPE_FAIL,
24
+    );
25
+    public static $edutypeMap = array(
26
+        self::EDU_TYPE_GRAD => "畢業",
27
+        self::EDU_TYPE_FAIL => "肄業",
28
+    );
29
+    
30
+    const SELECTION_YES = 'Y';
31
+    const SELECTION_NO  = 'N';
32
+    public static $selectionArr = array(
33
+        self::SELECTION_YES,
34
+        self::SELECTION_NO,
35
+    );
36
+    public static $selectionMap = array(
37
+        self::SELECTION_YES => "是",
38
+        self::SELECTION_NO  => "否",
39
+    );
40
+    
41
+}

+ 163
- 0
app/Http/Services/Web/AiFaceService.php View File

@@ -0,0 +1,163 @@
1
+<?php
2
+
3
+namespace App\Http\Services\Web;
4
+
5
+use App\Models\Web\FaceMergeToken;
6
+use App\Models\Web\ShareData;
7
+
8
+use DB;
9
+use GuzzleHttp\Client;
10
+
11
+class AiFaceService
12
+{
13
+    protected $faceMergeTokenDb;
14
+    protected $shareDataDb;
15
+    
16
+    public function __construct()
17
+    {
18
+        $this->faceMergeTokenDb = new FaceMergeToken();
19
+        $this->shareDataDb = new ShareData();
20
+        
21
+    }
22
+    
23
+    public function getTokenData()
24
+    {
25
+
26
+        $res = $this->faceMergeTokenDb
27
+            ->select([
28
+                '*'
29
+            ])
30
+            ->first();
31
+
32
+        // \Log::info($res);
33
+
34
+        // 整理返回值並返回
35
+        return $res;
36
+    }
37
+
38
+    public function getAccessToken()
39
+    {
40
+        // \Log::info('service start!');
41
+        
42
+        $param = [
43
+            'grant_type'    => 'client_credentials',
44
+            'client_id'     => config('services.ai_face.client_id'),
45
+            'client_secret' => config('services.ai_face.client_secret'),
46
+        ];
47
+        
48
+        $url = config('services.ai_face.token_url') . '?' . http_build_query($param);
49
+
50
+        $client = new Client();
51
+        
52
+        $response = $client->request('POST', $url);
53
+        
54
+        // \Log::info('url: '.$url);
55
+        // \Log::info('client_id: '.config('services.ai_face.client_id'));
56
+        // \Log::info('client_secret: '.config('services.ai_face.client_secret'));
57
+        
58
+        return json_decode($response->getBody());
59
+        
60
+    }
61
+    
62
+    public function setTokenByDay($accessToken, $type)
63
+    {
64
+        // DB::enableQueryLog();
65
+        if ($type=='insert') {
66
+            $this->faceMergeTokenDb
67
+                ->insert([
68
+                    'accessToken' => $accessToken,
69
+                    'updateDate' => date("Y-m-d"),
70
+                    'updateTime' => date("H:i:s"),
71
+                ]);
72
+        } else if ($type=='update') {
73
+            $this->faceMergeTokenDb
74
+                ->where('id', '1')
75
+                ->update([
76
+                    'accessToken' => $accessToken,
77
+                    'updateDate' => date("Y-m-d"),
78
+                    'updateTime' => date("H:i:s"),
79
+                ]);
80
+        }
81
+            
82
+        
83
+        // \Log::debug(DB::getQueryLog());
84
+    }
85
+    
86
+    public function getMergeData($accessToken, $preData)
87
+    {
88
+
89
+        $param = [
90
+            'access_token'    => $accessToken,
91
+        ];
92
+
93
+        $headers = [
94
+            'Content-Type'    => 'application/json',
95
+        ];
96
+
97
+        $url = config('services.ai_face.merge_url') . '?' . http_build_query($param);
98
+
99
+        $client = new Client();
100
+        
101
+        $response = $client->request('POST', $url , [
102
+                'headers' => $headers,
103
+                'body'    => json_encode($preData),
104
+            ]);
105
+            
106
+        if ($response->getStatusCode()==200) {
107
+            $res=json_decode($response->getBody(),true);
108
+        }
109
+        else
110
+            Log::error('error: '.$response->getStatusCode());
111
+
112
+        
113
+        return json_decode($response->getBody());
114
+        
115
+    }
116
+    
117
+    public function getShareId()
118
+    {
119
+
120
+        $id = $this->shareDataDb
121
+                ->select([
122
+                    'id'
123
+                ])
124
+                ->orderBy('id', 'desc')
125
+                ->first();
126
+                // ->toArray()
127
+        if (!$id) {
128
+            $id['id'] = '0';
129
+        }
130
+        // \Log::debug(print_r($id,true));
131
+        return $id['id'];
132
+    }
133
+
134
+    public function saveShareData($shareId, $title, $desc, $imageName)
135
+    {
136
+        
137
+        $this->shareDataDb
138
+            ->insert([
139
+                'id' => $shareId,
140
+                'title' => $title,
141
+                'desc' => $desc,
142
+                'imageName' => $imageName,
143
+                'createDate' => date("Y-m-d H:i:s"),
144
+            ]);
145
+        
146
+    }
147
+    
148
+    public function getShareData($shareId)
149
+    {
150
+        $res = $this->shareDataDb
151
+        ->select([
152
+            '*'
153
+        ])
154
+        ->where('id', '=', $shareId)
155
+        ->first();
156
+        // ->toArray()
157
+        
158
+        // 整理返回值並返回
159
+        return $res;
160
+
161
+    }
162
+
163
+}

+ 114
- 0
app/Http/Services/Web/Api2021Service.php View File

@@ -0,0 +1,114 @@
1
+<?php
2
+
3
+namespace App\Http\Services\Web;
4
+
5
+use Exception;
6
+use App\Http\Services\ConstDef\GeneralConst;
7
+use Illuminate\Support\Facades\DB;
8
+use App\Models\Web\Info;
9
+use App\Models\Web\GeneralSettings;
10
+use Aws\S3\S3Client;
11
+
12
+class Api2021Service
13
+{
14
+    
15
+    private $infoDb;
16
+    private $gsDb;
17
+    private $basedir;
18
+    private $s3;
19
+    
20
+    public function __construct()
21
+    {
22
+        date_default_timezone_set("Asia/Taipei");
23
+        $this->infoDb = new Info();
24
+        $this->gsDb = new GeneralSettings();
25
+        $this->basedir = preg_replace('/\/app\/.*/', '/public/', __DIR__);
26
+        $this->s3 = new S3Client([
27
+            'credentials' => [
28
+                'key'    => env('AWS_APP_KEY'),
29
+                'secret' => env('AWS_APP_SECRET'),
30
+            ],
31
+            'region'      => env('AWS_S3_REGION'),
32
+            'version'     => 'latest',
33
+        ]);
34
+    }
35
+    
36
+    public function setdoc($data)
37
+    {
38
+        $path = env('APP_ENV') . '/' . date("Y-m-d") . '/' . time() . '.jpg';
39
+        $this->s3->putObject([
40
+            'ACL'         => 'public-read',
41
+            'Body'        => $data,
42
+            'Bucket'      => env('AWS_S3_BUCKET'),
43
+            'ContentType' => 'image/jpeg ',
44
+            'Key'         => $path,
45
+        ]);
46
+        
47
+        return $path;
48
+    }
49
+    
50
+    public function setinfo($info)
51
+    {
52
+        $info['cdate'] = date("Y-m-d H:i:s");
53
+        $info['ip'] = $this->getUserIP();
54
+        $this->infoDb->insert($info);
55
+        // 計數
56
+        if ($info['image_uri'] != '') {
57
+            // 掃臉
58
+            $this->gsDb->where('key', 'counter_a')->update(['value' => DB::raw("value+1")]);
59
+        } else {
60
+            // 留言
61
+            $this->gsDb->where('key', 'counter_b')->update(['value' => DB::raw("value+1")]);
62
+        }
63
+        
64
+        return true;
65
+    }
66
+    
67
+    public function counterGet($type)
68
+    {
69
+        $counter = $this->gsDb->select(['value'])->where('key', '=', 'counter_' . $type)->first();
70
+        $counter = (isset($counter)) ? $counter->toArray() : [];
71
+        $counter = (count($counter) > 0) ? (int)$counter['value'] : 0;
72
+        
73
+        return $counter;
74
+    }
75
+    
76
+    public function counterSet($type)
77
+    {
78
+        $this->gsDb->where('key', 'counter_' . $type)->update(['value' => DB::raw("value+1")]);
79
+        
80
+        return true;
81
+    }
82
+    
83
+    public function reset()
84
+    {
85
+        DB::select(DB::raw("truncate table infos;"));
86
+        DB::update(DB::raw("update general_settings set value=0 where 1=1;"));
87
+        
88
+        return true;
89
+    }
90
+    
91
+    public function getUserIP()
92
+    {
93
+        $ipaddress = '';
94
+        if (isset($_SERVER['HTTP_CLIENT_IP']))
95
+            $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
96
+        else if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
97
+            $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
98
+        else if (isset($_SERVER['HTTP_X_FORWARDED']))
99
+            $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
100
+        else if (isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
101
+            $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
102
+        else if (isset($_SERVER['HTTP_FORWARDED_FOR']))
103
+            $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
104
+        else if (isset($_SERVER['HTTP_FORWARDED']))
105
+            $ipaddress = $_SERVER['HTTP_FORWARDED'];
106
+        else if (isset($_SERVER['REMOTE_ADDR']))
107
+            $ipaddress = $_SERVER['REMOTE_ADDR'];
108
+        else
109
+            $ipaddress = 'UNKNOWN';
110
+        
111
+        return $ipaddress;
112
+    }
113
+    
114
+}

+ 35
- 0
app/Http/ViewComposers/LeftMenuComposer.php View File

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+namespace App\Http\ViewComposers;
4
+
5
+use Illuminate\Http\Request;
6
+use Illuminate\View\View;
7
+use App\FunMenu;
8
+use Auth;
9
+
10
+class LeftMenuComposer {
11
+
12
+    protected $user_id;
13
+    protected $user_name;
14
+
15
+    public function __construct()
16
+    {
17
+        if (Auth::check()) {
18
+            // 這個使用者已經登入...
19
+            $user = Auth::user();
20
+
21
+            $this->user_id = $user->id;
22
+            $this->user_name = $user->name;
23
+        } else {
24
+            $this->user_id = 0;
25
+            $this->user_name = "Guest";
26
+        }
27
+    }
28
+
29
+    public function compose(View $view)
30
+    {
31
+        $funmenu = new FunMenu;
32
+        $result = $funmenu->leftmenu($this->user_id);
33
+        $view->with(['leftmenu' => $result, 'username' => $this->user_name]);
34
+    }
35
+}

+ 14
- 0
app/Models/Web/FaceMergeToken.php View File

@@ -0,0 +1,14 @@
1
+<?php
2
+
3
+namespace App\Models\Web;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class FaceMergeToken extends Model
8
+{
9
+    protected $connection = 'mysql';                  // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'faceMergeToken';
11
+    protected $primaryKey = 'id';                     // PK 的欄位名稱
12
+    public    $timestamps = false;                    // 保持 false
13
+
14
+}

+ 13
- 0
app/Models/Web/GeneralSettings.php View File

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Models\Web;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class GeneralSettings extends Model
8
+{
9
+    protected $connection = 'mysql';                         // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'general_settings';
11
+    protected $primaryKey = 'id';                     // PK 的欄位名稱
12
+    public    $timestamps = false;                           // 保持 false
13
+}

+ 13
- 0
app/Models/Web/Info.php View File

@@ -0,0 +1,13 @@
1
+<?php
2
+
3
+namespace App\Models\Web;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class Info extends Model
8
+{
9
+    protected $connection = 'mysql';                         // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'infos';
11
+    protected $primaryKey = 'id';                     // PK 的欄位名稱
12
+    public    $timestamps = false;                           // 保持 false
13
+}

+ 14
- 0
app/Models/Web/ShareData.php View File

@@ -0,0 +1,14 @@
1
+<?php
2
+
3
+namespace App\Models\Web;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class ShareData extends Model
8
+{
9
+    protected $connection = 'mysql';                  // 參照 config/database.php 的連線名稱
10
+    protected $table      = 'shareData';
11
+    protected $primaryKey = 'id';                     // PK 的欄位名稱
12
+    public    $timestamps = false;                    // 保持 false
13
+
14
+}

+ 30
- 0
app/Providers/AppServiceProvider.php View File

@@ -0,0 +1,30 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\ServiceProvider;
6
+use Illuminate\Support\Facades\Schema;
7
+
8
+class AppServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * Bootstrap any application services.
12
+     *
13
+     * @return void
14
+     */
15
+    public function boot()
16
+    {
17
+        //
18
+		Schema::defaultStringLength(191);
19
+    }
20
+
21
+    /**
22
+     * Register any application services.
23
+     *
24
+     * @return void
25
+     */
26
+    public function register()
27
+    {
28
+        //
29
+    }
30
+}

+ 30
- 0
app/Providers/AuthServiceProvider.php View File

@@ -0,0 +1,30 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\Facades\Gate;
6
+use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
7
+
8
+class AuthServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * The policy mappings for the application.
12
+     *
13
+     * @var array
14
+     */
15
+    protected $policies = [
16
+        'App\Model' => 'App\Policies\ModelPolicy',
17
+    ];
18
+
19
+    /**
20
+     * Register any authentication / authorization services.
21
+     *
22
+     * @return void
23
+     */
24
+    public function boot()
25
+    {
26
+        $this->registerPolicies();
27
+
28
+        //
29
+    }
30
+}

+ 21
- 0
app/Providers/BroadcastServiceProvider.php View File

@@ -0,0 +1,21 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\ServiceProvider;
6
+use Illuminate\Support\Facades\Broadcast;
7
+
8
+class BroadcastServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * Bootstrap any application services.
12
+     *
13
+     * @return void
14
+     */
15
+    public function boot()
16
+    {
17
+        Broadcast::routes();
18
+
19
+        require base_path('routes/channels.php');
20
+    }
21
+}

+ 34
- 0
app/Providers/ComposerServiceProvider.php View File

@@ -0,0 +1,34 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use View;
6
+use Illuminate\Support\ServiceProvider;
7
+use Illuminate\Http\Request;
8
+
9
+class ComposerServiceProvider extends ServiceProvider
10
+{
11
+    /**
12
+     * Bootstrap the application services.
13
+     *
14
+     * @return void
15
+     */
16
+    public function boot()
17
+    {
18
+        //
19
+        //dd('something2');
20
+        View::composer(['admin.index', 'admin.uc.leftmenu', 'admin.uc.header'], 'App\Http\ViewComposers\LeftMenuComposer');
21
+        //view()->composer(['admin.index', 'admin.uc.leftmenu', 'admin.uc.header'], 'App\Http\ViewComposers\LeftMenuComposer');
22
+        //$this->app['view']->composer(['admin.index', 'admin.uc.leftmenu', 'admin.uc.header'], 'App\Http\ViewComposers\LeftMenuComposer');
23
+    }
24
+
25
+    /**
26
+     * Register the application services.
27
+     *
28
+     * @return void
29
+     */
30
+    public function register()
31
+    {
32
+        //
33
+    }
34
+}

+ 32
- 0
app/Providers/EventServiceProvider.php View File

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\Facades\Event;
6
+use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
7
+
8
+class EventServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * The event listener mappings for the application.
12
+     *
13
+     * @var array
14
+     */
15
+    protected $listen = [
16
+        'App\Events\SomeEvent' => [
17
+            'App\Listeners\EventListener',
18
+        ],
19
+    ];
20
+
21
+    /**
22
+     * Register any events for your application.
23
+     *
24
+     * @return void
25
+     */
26
+    public function boot()
27
+    {
28
+        parent::boot();
29
+
30
+        //
31
+    }
32
+}

+ 73
- 0
app/Providers/RouteServiceProvider.php View File

@@ -0,0 +1,73 @@
1
+<?php
2
+
3
+namespace App\Providers;
4
+
5
+use Illuminate\Support\Facades\Route;
6
+use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
7
+
8
+class RouteServiceProvider extends ServiceProvider
9
+{
10
+    /**
11
+     * This namespace is applied to your controller routes.
12
+     *
13
+     * In addition, it is set as the URL generator's root namespace.
14
+     *
15
+     * @var string
16
+     */
17
+    protected $namespace = 'App\Http\Controllers';
18
+
19
+    /**
20
+     * Define your route model bindings, pattern filters, etc.
21
+     *
22
+     * @return void
23
+     */
24
+    public function boot()
25
+    {
26
+        //
27
+
28
+        parent::boot();
29
+    }
30
+
31
+    /**
32
+     * Define the routes for the application.
33
+     *
34
+     * @return void
35
+     */
36
+    public function map()
37
+    {
38
+        $this->mapApiRoutes();
39
+
40
+        $this->mapWebRoutes();
41
+
42
+        //
43
+    }
44
+
45
+    /**
46
+     * Define the "web" routes for the application.
47
+     *
48
+     * These routes all receive session state, CSRF protection, etc.
49
+     *
50
+     * @return void
51
+     */
52
+    protected function mapWebRoutes()
53
+    {
54
+        Route::middleware('web')
55
+             ->namespace($this->namespace)
56
+             ->group(base_path('routes/web.php'));
57
+    }
58
+
59
+    /**
60
+     * Define the "api" routes for the application.
61
+     *
62
+     * These routes are typically stateless.
63
+     *
64
+     * @return void
65
+     */
66
+    protected function mapApiRoutes()
67
+    {
68
+        Route::prefix('api')
69
+             ->middleware('api')
70
+             ->namespace($this->namespace)
71
+             ->group(base_path('routes/api.php'));
72
+    }
73
+}

+ 32
- 0
app/User.php View File

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Notifications\Notifiable;
6
+use Illuminate\Foundation\Auth\User as Authenticatable;
7
+
8
+class User extends Authenticatable
9
+{
10
+    use Notifiable;
11
+
12
+    /**
13
+     * The attributes that are mass assignable.
14
+     *
15
+     * @var array
16
+     */
17
+    protected $fillable = [
18
+        'name',
19
+        'email',
20
+        'password',
21
+    ];
22
+
23
+    /**
24
+     * The attributes that should be hidden for arrays.
25
+     *
26
+     * @var array
27
+     */
28
+    protected $hidden = [
29
+        'password',
30
+        'remember_token',
31
+    ];
32
+}

+ 51
- 0
artisan View File

@@ -0,0 +1,51 @@
1
+#!/usr/bin/env php
2
+<?php
3
+
4
+/*
5
+|--------------------------------------------------------------------------
6
+| Register The Auto Loader
7
+|--------------------------------------------------------------------------
8
+|
9
+| Composer provides a convenient, automatically generated class loader
10
+| for our application. We just need to utilize it! We'll require it
11
+| into the script here so that we do not have to worry about the
12
+| loading of any our classes "manually". Feels great to relax.
13
+|
14
+*/
15
+
16
+require __DIR__.'/bootstrap/autoload.php';
17
+
18
+$app = require_once __DIR__.'/bootstrap/app.php';
19
+
20
+/*
21
+|--------------------------------------------------------------------------
22
+| Run The Artisan Application
23
+|--------------------------------------------------------------------------
24
+|
25
+| When we run the console application, the current CLI command will be
26
+| executed in this console and the response sent back to a terminal
27
+| or another output device for the developers. Here goes nothing!
28
+|
29
+*/
30
+
31
+$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
32
+
33
+$status = $kernel->handle(
34
+    $input = new Symfony\Component\Console\Input\ArgvInput,
35
+    new Symfony\Component\Console\Output\ConsoleOutput
36
+);
37
+
38
+/*
39
+|--------------------------------------------------------------------------
40
+| Shutdown The Application
41
+|--------------------------------------------------------------------------
42
+|
43
+| Once Artisan has finished running. We will fire off the shutdown events
44
+| so that any final work may be done by the application before we shut
45
+| down the process. This is the last thing to happen to the request.
46
+|
47
+*/
48
+
49
+$kernel->terminate($input, $status);
50
+
51
+exit($status);

+ 67
- 0
bootstrap/app.php View File

@@ -0,0 +1,67 @@
1
+<?php
2
+
3
+/*
4
+|--------------------------------------------------------------------------
5
+| Create The Application
6
+|--------------------------------------------------------------------------
7
+|
8
+| The first thing we will do is create a new Laravel application instance
9
+| which serves as the "glue" for all the components of Laravel, and is
10
+| the IoC container for the system binding all of the various parts.
11
+|
12
+*/
13
+
14
+$app = new Illuminate\Foundation\Application(
15
+    realpath(__DIR__.'/../')
16
+);
17
+
18
+/*
19
+|--------------------------------------------------------------------------
20
+| Bind Important Interfaces
21
+|--------------------------------------------------------------------------
22
+|
23
+| Next, we need to bind some important interfaces into the container so
24
+| we will be able to resolve them when needed. The kernels serve the
25
+| incoming requests to this application from both the web and CLI.
26
+|
27
+*/
28
+
29
+$app->singleton(
30
+    Illuminate\Contracts\Http\Kernel::class,
31
+    App\Http\Kernel::class
32
+);
33
+
34
+$app->singleton(
35
+    Illuminate\Contracts\Console\Kernel::class,
36
+    App\Console\Kernel::class
37
+);
38
+
39
+$app->singleton(
40
+    Illuminate\Contracts\Debug\ExceptionHandler::class,
41
+    App\Exceptions\Handler::class
42
+);
43
+
44
+/*
45
+|--------------------------------------------------------------------------
46
+| Return The Application
47
+|--------------------------------------------------------------------------
48
+|
49
+| This script returns the application instance. The instance is given to
50
+| the calling script so we can separate the building of the instances
51
+| from the actual running of the application and sending responses.
52
+|
53
+*/
54
+
55
+// 環境偵測(需要事先在 php.ini 中做好相關設定,若線上環境不支援修改則直接套用預設的 .env)
56
+$ore = 'pre';
57
+$compare = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : __DIR__;
58
+// 正式站新網址
59
+$ore = (str_replace('www.', '', $compare) != $compare) ? 'pro' : $ore;
60
+// 測試站
61
+$ore = (str_replace('demo.', '', $compare) != $compare) ? 'pre' : $ore;
62
+if(!defined('APP_MODE')){
63
+    define('APP_MODE', $ore);
64
+}
65
+$app->loadEnvironmentFrom('.env.'.$ore);
66
+
67
+return $app;

+ 17
- 0
bootstrap/autoload.php View File

@@ -0,0 +1,17 @@
1
+<?php
2
+
3
+define('LARAVEL_START', microtime(true));
4
+
5
+/*
6
+|--------------------------------------------------------------------------
7
+| Register The Composer Auto Loader
8
+|--------------------------------------------------------------------------
9
+|
10
+| Composer provides a convenient, automatically generated class loader
11
+| for our application. We just need to utilize it! We'll require it
12
+| into the script here so that we do not have to worry about the
13
+| loading of any our classes "manually". Feels great to relax.
14
+|
15
+*/
16
+
17
+require __DIR__.'/../vendor/autoload.php';

+ 2
- 0
bootstrap/cache/.gitignore View File

@@ -0,0 +1,2 @@
1
+*
2
+!.gitignore

BIN
composer View File


+ 68
- 0
composer.json View File

@@ -0,0 +1,68 @@
1
+{
2
+  "name": "laravel/laravel",
3
+  "description": "The Laravel Framework.",
4
+  "keywords": [
5
+    "framework",
6
+    "laravel"
7
+  ],
8
+  "license": "MIT",
9
+  "type": "project",
10
+  "require": {
11
+    "php": ">=7.4.1",
12
+    "aws/aws-sdk-php-laravel": "~3.0",
13
+    "google/cloud-vision": "^1.3",
14
+    "gregwar/captcha": "^1.1",
15
+    "intervention/image": "^2.3",
16
+    "laravel/framework": "5.5.*",
17
+    "laravel/tinker": "~1.0",
18
+    "league/flysystem-aws-s3-v3": "~1.0",
19
+    "phpoffice/phpspreadsheet": "^1.17",
20
+    "ext-bcmath": "*"
21
+  },
22
+  "require-dev": {
23
+    "fzaninotto/faker": "~1.4",
24
+    "mockery/mockery": "0.9.*",
25
+    "phpunit/phpunit": "~6.0",
26
+    "filp/whoops": "~2.0"
27
+  },
28
+  "autoload": {
29
+    "classmap": [
30
+      "database"
31
+    ],
32
+    "psr-4": {
33
+      "App\\": "app/"
34
+    }
35
+  },
36
+  "autoload-dev": {
37
+    "psr-4": {
38
+      "Tests\\": "tests/"
39
+    }
40
+  },
41
+  "scripts": {
42
+    "post-root-package-install": [
43
+      "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
44
+    ],
45
+    "post-create-project-cmd": [
46
+      "php artisan key:generate"
47
+    ],
48
+    "post-install-cmd": [
49
+      "Illuminate\\Foundation\\ComposerScripts::postInstall",
50
+      "php artisan optimize"
51
+    ],
52
+    "post-update-cmd": [
53
+      "Illuminate\\Foundation\\ComposerScripts::postUpdate",
54
+      "php artisan optimize"
55
+    ],
56
+    "post-autoload-dump": [
57
+      "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
58
+      "@php artisan package:discover"
59
+    ]
60
+  },
61
+  "config": {
62
+    "preferred-install": "dist",
63
+    "sort-packages": true,
64
+    "allow-plugins": {
65
+      "kylekatarnls/update-helper": true
66
+    }
67
+  }
68
+}

+ 7330
- 0
composer.lock
File diff suppressed because it is too large
View File


+ 235
- 0
config/app.php View File

@@ -0,0 +1,235 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Application Name
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This value is the name of your application. This value is used when the
11
+    | framework needs to place the application's name in a notification or
12
+    | any other location as required by the application or its packages.
13
+    */
14
+
15
+    'name' => 'Laravel',
16
+
17
+    /*
18
+    |--------------------------------------------------------------------------
19
+    | Application Environment
20
+    |--------------------------------------------------------------------------
21
+    |
22
+    | This value determines the "environment" your application is currently
23
+    | running in. This may determine how you prefer to configure various
24
+    | services your application utilizes. Set this in your ".env" file.
25
+    |
26
+    */
27
+
28
+    'env' => env('APP_ENV', 'production'),
29
+
30
+    /*
31
+    |--------------------------------------------------------------------------
32
+    | Application Debug Mode
33
+    |--------------------------------------------------------------------------
34
+    |
35
+    | When your application is in debug mode, detailed error messages with
36
+    | stack traces will be shown on every error that occurs within your
37
+    | application. If disabled, a simple generic error page is shown.
38
+    |
39
+    */
40
+
41
+    'debug' => env('APP_DEBUG', false),
42
+
43
+    /*
44
+    |--------------------------------------------------------------------------
45
+    | Application URL
46
+    |--------------------------------------------------------------------------
47
+    |
48
+    | This URL is used by the console to properly generate URLs when using
49
+    | the Artisan command line tool. You should set this to the root of
50
+    | your application so that it is used when running Artisan tasks.
51
+    |
52
+    */
53
+
54
+    'url' => env('APP_URL', 'http://localhost'),
55
+
56
+    /*
57
+    |--------------------------------------------------------------------------
58
+    | Application Timezone
59
+    |--------------------------------------------------------------------------
60
+    |
61
+    | Here you may specify the default timezone for your application, which
62
+    | will be used by the PHP date and date-time functions. We have gone
63
+    | ahead and set this to a sensible default for you out of the box.
64
+    |
65
+    */
66
+
67
+    'timezone' => 'Asia/Taipei',
68
+
69
+    /*
70
+    |--------------------------------------------------------------------------
71
+    | Application Locale Configuration
72
+    |--------------------------------------------------------------------------
73
+    |
74
+    | The application locale determines the default locale that will be used
75
+    | by the translation service provider. You are free to set this value
76
+    | to any of the locales which will be supported by the application.
77
+    |
78
+    */
79
+
80
+    'locale' => 'zh-TW',
81
+
82
+    /*
83
+    |--------------------------------------------------------------------------
84
+    | Application Fallback Locale
85
+    |--------------------------------------------------------------------------
86
+    |
87
+    | The fallback locale determines the locale to use when the current one
88
+    | is not available. You may change the value to correspond to any of
89
+    | the language folders that are provided through your application.
90
+    |
91
+    */
92
+
93
+    'fallback_locale' => 'en',
94
+
95
+    /*
96
+    |--------------------------------------------------------------------------
97
+    | Encryption Key
98
+    |--------------------------------------------------------------------------
99
+    |
100
+    | This key is used by the Illuminate encrypter service and should be set
101
+    | to a random, 32 character string, otherwise these encrypted strings
102
+    | will not be safe. Please do this before deploying an application!
103
+    |
104
+    */
105
+
106
+    'key' => env('APP_KEY'),
107
+
108
+    'cipher' => 'AES-256-CBC',
109
+
110
+    /*
111
+    |--------------------------------------------------------------------------
112
+    | Logging Configuration
113
+    |--------------------------------------------------------------------------
114
+    |
115
+    | Here you may configure the log settings for your application. Out of
116
+    | the box, Laravel uses the Monolog PHP logging library. This gives
117
+    | you a variety of powerful log handlers / formatters to utilize.
118
+    |
119
+    | Available Settings: "single", "daily", "syslog", "errorlog"
120
+    |
121
+    */
122
+
123
+    'log' => env('APP_LOG', 'single'),
124
+
125
+    'log_level' => env('APP_LOG_LEVEL', 'debug'),
126
+
127
+    /*
128
+    |--------------------------------------------------------------------------
129
+    | Autoloaded Service Providers
130
+    |--------------------------------------------------------------------------
131
+    |
132
+    | The service providers listed here will be automatically loaded on the
133
+    | request to your application. Feel free to add your own services to
134
+    | this array to grant expanded functionality to your applications.
135
+    |
136
+    */
137
+
138
+    'providers' => [
139
+
140
+        /*
141
+         * Laravel Framework Service Providers...
142
+         */
143
+        Illuminate\Auth\AuthServiceProvider::class,
144
+        Illuminate\Broadcasting\BroadcastServiceProvider::class,
145
+        Illuminate\Bus\BusServiceProvider::class,
146
+        Illuminate\Cache\CacheServiceProvider::class,
147
+        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
148
+        Illuminate\Cookie\CookieServiceProvider::class,
149
+        Illuminate\Database\DatabaseServiceProvider::class,
150
+        Illuminate\Encryption\EncryptionServiceProvider::class,
151
+        Illuminate\Filesystem\FilesystemServiceProvider::class,
152
+        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
153
+        Illuminate\Hashing\HashServiceProvider::class,
154
+        Illuminate\Mail\MailServiceProvider::class,
155
+        Illuminate\Notifications\NotificationServiceProvider::class,
156
+        Illuminate\Pagination\PaginationServiceProvider::class,
157
+        Illuminate\Pipeline\PipelineServiceProvider::class,
158
+        Illuminate\Queue\QueueServiceProvider::class,
159
+        Illuminate\Redis\RedisServiceProvider::class,
160
+        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
161
+        Illuminate\Session\SessionServiceProvider::class,
162
+        Illuminate\Translation\TranslationServiceProvider::class,
163
+        Illuminate\Validation\ValidationServiceProvider::class,
164
+        Illuminate\View\ViewServiceProvider::class,
165
+
166
+        /*
167
+         * Package Service Providers...
168
+         */
169
+        Laravel\Tinker\TinkerServiceProvider::class,
170
+
171
+        /*
172
+         * Application Service Providers...
173
+         */
174
+        App\Providers\AppServiceProvider::class,
175
+        App\Providers\AuthServiceProvider::class,
176
+        // App\Providers\BroadcastServiceProvider::class,
177
+        App\Providers\EventServiceProvider::class,
178
+        App\Providers\RouteServiceProvider::class,
179
+
180
+        App\Providers\ComposerServiceProvider::class,
181
+        Intervention\Image\ImageServiceProvider::class,
182
+
183
+    ],
184
+
185
+    /*
186
+    |--------------------------------------------------------------------------
187
+    | Class Aliases
188
+    |--------------------------------------------------------------------------
189
+    |
190
+    | This array of class aliases will be registered when this application
191
+    | is started. However, feel free to register as many as you wish as
192
+    | the aliases are "lazy" loaded so they don't hinder performance.
193
+    |
194
+    */
195
+
196
+    'aliases' => [
197
+
198
+        'App' => Illuminate\Support\Facades\App::class,
199
+        'Artisan' => Illuminate\Support\Facades\Artisan::class,
200
+        'Auth' => Illuminate\Support\Facades\Auth::class,
201
+        'Blade' => Illuminate\Support\Facades\Blade::class,
202
+        'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
203
+        'Bus' => Illuminate\Support\Facades\Bus::class,
204
+        'Cache' => Illuminate\Support\Facades\Cache::class,
205
+        'Config' => Illuminate\Support\Facades\Config::class,
206
+        'Cookie' => Illuminate\Support\Facades\Cookie::class,
207
+        'Crypt' => Illuminate\Support\Facades\Crypt::class,
208
+        'DB' => Illuminate\Support\Facades\DB::class,
209
+        'Eloquent' => Illuminate\Database\Eloquent\Model::class,
210
+        'Event' => Illuminate\Support\Facades\Event::class,
211
+        'File' => Illuminate\Support\Facades\File::class,
212
+        'Gate' => Illuminate\Support\Facades\Gate::class,
213
+        'Hash' => Illuminate\Support\Facades\Hash::class,
214
+        'Lang' => Illuminate\Support\Facades\Lang::class,
215
+        'Log' => Illuminate\Support\Facades\Log::class,
216
+        'Mail' => Illuminate\Support\Facades\Mail::class,
217
+        'Notification' => Illuminate\Support\Facades\Notification::class,
218
+        'Password' => Illuminate\Support\Facades\Password::class,
219
+        'Queue' => Illuminate\Support\Facades\Queue::class,
220
+        'Redirect' => Illuminate\Support\Facades\Redirect::class,
221
+        'Redis' => Illuminate\Support\Facades\Redis::class,
222
+        'Request' => Illuminate\Support\Facades\Request::class,
223
+        'Response' => Illuminate\Support\Facades\Response::class,
224
+        'Route' => Illuminate\Support\Facades\Route::class,
225
+        'Schema' => Illuminate\Support\Facades\Schema::class,
226
+        'Session' => Illuminate\Support\Facades\Session::class,
227
+        'Storage' => Illuminate\Support\Facades\Storage::class,
228
+        'URL' => Illuminate\Support\Facades\URL::class,
229
+        'Validator' => Illuminate\Support\Facades\Validator::class,
230
+        'View' => Illuminate\Support\Facades\View::class,
231
+        'Image' => Intervention\Image\Facades\Image::class,
232
+
233
+    ],
234
+
235
+];

+ 102
- 0
config/auth.php View File

@@ -0,0 +1,102 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Authentication Defaults
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default authentication "guard" and password
11
+    | reset options for your application. You may change these defaults
12
+    | as required, but they're a perfect start for most applications.
13
+    |
14
+    */
15
+
16
+    'defaults' => [
17
+        'guard' => 'web',
18
+        'passwords' => 'users',
19
+    ],
20
+
21
+    /*
22
+    |--------------------------------------------------------------------------
23
+    | Authentication Guards
24
+    |--------------------------------------------------------------------------
25
+    |
26
+    | Next, you may define every authentication guard for your application.
27
+    | Of course, a great default configuration has been defined for you
28
+    | here which uses session storage and the Eloquent user provider.
29
+    |
30
+    | All authentication drivers have a user provider. This defines how the
31
+    | users are actually retrieved out of your database or other storage
32
+    | mechanisms used by this application to persist your user's data.
33
+    |
34
+    | Supported: "session", "token"
35
+    |
36
+    */
37
+
38
+    'guards' => [
39
+        'web' => [
40
+            'driver' => 'session',
41
+            'provider' => 'users',
42
+        ],
43
+
44
+        'api' => [
45
+            'driver' => 'token',
46
+            'provider' => 'users',
47
+        ],
48
+    ],
49
+
50
+    /*
51
+    |--------------------------------------------------------------------------
52
+    | User Providers
53
+    |--------------------------------------------------------------------------
54
+    |
55
+    | All authentication drivers have a user provider. This defines how the
56
+    | users are actually retrieved out of your database or other storage
57
+    | mechanisms used by this application to persist your user's data.
58
+    |
59
+    | If you have multiple user tables or models you may configure multiple
60
+    | sources which represent each model / table. These sources may then
61
+    | be assigned to any extra authentication guards you have defined.
62
+    |
63
+    | Supported: "database", "eloquent"
64
+    |
65
+    */
66
+
67
+    'providers' => [
68
+        'users' => [
69
+            'driver' => 'eloquent',
70
+            'model' => App\User::class,
71
+        ],
72
+
73
+        // 'users' => [
74
+        //     'driver' => 'database',
75
+        //     'table' => 'users',
76
+        // ],
77
+    ],
78
+
79
+    /*
80
+    |--------------------------------------------------------------------------
81
+    | Resetting Passwords
82
+    |--------------------------------------------------------------------------
83
+    |
84
+    | You may specify multiple password reset configurations if you have more
85
+    | than one user table or model in the application and you want to have
86
+    | separate password reset settings based on the specific user types.
87
+    |
88
+    | The expire time is the number of minutes that the reset token should be
89
+    | considered valid. This security feature keeps tokens short-lived so
90
+    | they have less time to be guessed. You may change this as needed.
91
+    |
92
+    */
93
+
94
+    'passwords' => [
95
+        'users' => [
96
+            'provider' => 'users',
97
+            'table' => 'password_resets',
98
+            'expire' => 60,
99
+        ],
100
+    ],
101
+
102
+];

+ 58
- 0
config/broadcasting.php View File

@@ -0,0 +1,58 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Broadcaster
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default broadcaster that will be used by the
11
+    | framework when an event needs to be broadcast. You may set this to
12
+    | any of the connections defined in the "connections" array below.
13
+    |
14
+    | Supported: "pusher", "redis", "log", "null"
15
+    |
16
+    */
17
+
18
+    'default' => env('BROADCAST_DRIVER', 'null'),
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Broadcast Connections
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | Here you may define all of the broadcast connections that will be used
26
+    | to broadcast events to other systems or over websockets. Samples of
27
+    | each available type of connection are provided inside this array.
28
+    |
29
+    */
30
+
31
+    'connections' => [
32
+
33
+        'pusher' => [
34
+            'driver' => 'pusher',
35
+            'key' => env('PUSHER_APP_KEY'),
36
+            'secret' => env('PUSHER_APP_SECRET'),
37
+            'app_id' => env('PUSHER_APP_ID'),
38
+            'options' => [
39
+                //
40
+            ],
41
+        ],
42
+
43
+        'redis' => [
44
+            'driver' => 'redis',
45
+            'connection' => 'default',
46
+        ],
47
+
48
+        'log' => [
49
+            'driver' => 'log',
50
+        ],
51
+
52
+        'null' => [
53
+            'driver' => 'null',
54
+        ],
55
+
56
+    ],
57
+
58
+];

+ 91
- 0
config/cache.php View File

@@ -0,0 +1,91 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Cache Store
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default cache connection that gets used while
11
+    | using this caching library. This connection is used when another is
12
+    | not explicitly specified when executing a given caching function.
13
+    |
14
+    | Supported: "apc", "array", "database", "file", "memcached", "redis"
15
+    |
16
+    */
17
+
18
+    'default' => env('CACHE_DRIVER', 'file'),
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Cache Stores
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | Here you may define all of the cache "stores" for your application as
26
+    | well as their drivers. You may even define multiple stores for the
27
+    | same cache driver to group types of items stored in your caches.
28
+    |
29
+    */
30
+
31
+    'stores' => [
32
+
33
+        'apc' => [
34
+            'driver' => 'apc',
35
+        ],
36
+
37
+        'array' => [
38
+            'driver' => 'array',
39
+        ],
40
+
41
+        'database' => [
42
+            'driver' => 'database',
43
+            'table' => 'cache',
44
+            'connection' => null,
45
+        ],
46
+
47
+        'file' => [
48
+            'driver' => 'file',
49
+            'path' => storage_path('framework/cache/data'),
50
+        ],
51
+
52
+        'memcached' => [
53
+            'driver' => 'memcached',
54
+            'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
55
+            'sasl' => [
56
+                env('MEMCACHED_USERNAME'),
57
+                env('MEMCACHED_PASSWORD'),
58
+            ],
59
+            'options' => [
60
+                // Memcached::OPT_CONNECT_TIMEOUT  => 2000,
61
+            ],
62
+            'servers' => [
63
+                [
64
+                    'host' => env('MEMCACHED_HOST', '127.0.0.1'),
65
+                    'port' => env('MEMCACHED_PORT', 11211),
66
+                    'weight' => 100,
67
+                ],
68
+            ],
69
+        ],
70
+
71
+        'redis' => [
72
+            'driver' => 'redis',
73
+            'connection' => 'default',
74
+        ],
75
+
76
+    ],
77
+
78
+    /*
79
+    |--------------------------------------------------------------------------
80
+    | Cache Key Prefix
81
+    |--------------------------------------------------------------------------
82
+    |
83
+    | When utilizing a RAM based store such as APC or Memcached, there might
84
+    | be other applications utilizing the same cache. So, we'll specify a
85
+    | value to get prefixed to all our keys so we can avoid collisions.
86
+    |
87
+    */
88
+
89
+    'prefix' => 'laravel',
90
+
91
+];

+ 108
- 0
config/database.php View File

@@ -0,0 +1,108 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Database Connection Name
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Here you may specify which of the database connections below you wish
11
+    | to use as your default connection for all database work. Of course
12
+    | you may use many connections at once using the Database library.
13
+    |
14
+    */
15
+
16
+    'default' => env('DB_CONNECTION', 'mysql'),
17
+
18
+    /*
19
+    |--------------------------------------------------------------------------
20
+    | Database Connections
21
+    |--------------------------------------------------------------------------
22
+    |
23
+    | Here are each of the database connections setup for your application.
24
+    | Of course, examples of configuring each database platform that is
25
+    | supported by Laravel is shown below to make development simple.
26
+    |
27
+    |
28
+    | All database work in Laravel is done through the PHP PDO facilities
29
+    | so make sure you have the driver for your particular database of
30
+    | choice installed on your machine before you begin development.
31
+    |
32
+    */
33
+
34
+    'connections' => [
35
+
36
+        'sqlite' => [
37
+            'driver' => 'sqlite',
38
+            'database' => env('DB_DATABASE', database_path('database.sqlite')),
39
+            'prefix' => '',
40
+        ],
41
+
42
+        'mysql' => [
43
+            'driver' => 'mysql',
44
+            'host' => env('DB_HOST', '127.0.0.1'),
45
+            'port' => env('DB_PORT', '3306'),
46
+            'database' => env('DB_DATABASE', 'forge'),
47
+            'username' => env('DB_USERNAME', 'forge'),
48
+            'password' => env('DB_PASSWORD', ''),
49
+            'charset' => 'utf8mb4',
50
+            'collation' => 'utf8mb4_unicode_ci',
51
+            'prefix' => '',
52
+            'strict' => false, # 設置 false 避免後台選單的複合 SQL 造成 only_full_group_by 權限問題
53
+            'engine' => null,
54
+        ],
55
+
56
+        'pgsql' => [
57
+            'driver' => 'pgsql',
58
+            'host' => env('DB_HOST', '127.0.0.1'),
59
+            'port' => env('DB_PORT', '5432'),
60
+            'database' => env('DB_DATABASE', 'forge'),
61
+            'username' => env('DB_USERNAME', 'forge'),
62
+            'password' => env('DB_PASSWORD', ''),
63
+            'charset' => 'utf8',
64
+            'prefix' => '',
65
+            'schema' => 'public',
66
+            'sslmode' => 'prefer',
67
+        ],
68
+
69
+    ],
70
+
71
+    /*
72
+    |--------------------------------------------------------------------------
73
+    | Migration Repository Table
74
+    |--------------------------------------------------------------------------
75
+    |
76
+    | This table keeps track of all the migrations that have already run for
77
+    | your application. Using this information, we can determine which of
78
+    | the migrations on disk haven't actually been run in the database.
79
+    |
80
+    */
81
+
82
+    'migrations' => 'migrations',
83
+
84
+    /*
85
+    |--------------------------------------------------------------------------
86
+    | Redis Databases
87
+    |--------------------------------------------------------------------------
88
+    |
89
+    | Redis is an open source, fast, and advanced key-value store that also
90
+    | provides a richer set of commands than a typical key-value systems
91
+    | such as APC or Memcached. Laravel makes it easy to dig right in.
92
+    |
93
+    */
94
+
95
+    'redis' => [
96
+
97
+        'client' => 'predis',
98
+
99
+        'default' => [
100
+            'host' => env('REDIS_HOST', '127.0.0.1'),
101
+            'password' => env('REDIS_PASSWORD', null),
102
+            'port' => env('REDIS_PORT', 6379),
103
+            'database' => 0,
104
+        ],
105
+
106
+    ],
107
+
108
+];

+ 68
- 0
config/filesystems.php View File

@@ -0,0 +1,68 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Filesystem Disk
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Here you may specify the default filesystem disk that should be used
11
+    | by the framework. The "local" disk, as well as a variety of cloud
12
+    | based disks are available to your application. Just store away!
13
+    |
14
+    */
15
+
16
+    'default' => 'local',
17
+
18
+    /*
19
+    |--------------------------------------------------------------------------
20
+    | Default Cloud Filesystem Disk
21
+    |--------------------------------------------------------------------------
22
+    |
23
+    | Many applications store files both locally and in the cloud. For this
24
+    | reason, you may specify a default "cloud" driver here. This driver
25
+    | will be bound as the Cloud disk implementation in the container.
26
+    |
27
+    */
28
+
29
+    'cloud' => 's3',
30
+
31
+    /*
32
+    |--------------------------------------------------------------------------
33
+    | Filesystem Disks
34
+    |--------------------------------------------------------------------------
35
+    |
36
+    | Here you may configure as many filesystem "disks" as you wish, and you
37
+    | may even configure multiple disks of the same driver. Defaults have
38
+    | been setup for each driver as an example of the required options.
39
+    |
40
+    | Supported Drivers: "local", "ftp", "s3", "rackspace"
41
+    |
42
+    */
43
+
44
+    'disks' => [
45
+
46
+        'local' => [
47
+            'driver' => 'local',
48
+            'root' => storage_path('app'),
49
+        ],
50
+
51
+        'public' => [
52
+            'driver' => 'local',
53
+            'root' => storage_path('app/public'),
54
+            'url' => env('APP_URL').'/storage',
55
+            'visibility' => 'public',
56
+        ],
57
+
58
+        's3' => [
59
+            'driver' => 's3',
60
+            'key' => env('AWS_APP_KEY'),
61
+            'secret' => env('AWS_APP_SECRET'),
62
+            'region' => env('AWS_S3_REGION'),
63
+            'bucket' => env('AWS_S3_BUCKET'),
64
+        ],
65
+
66
+    ],
67
+
68
+];

+ 20
- 0
config/image.php View File

@@ -0,0 +1,20 @@
1
+<?php
2
+
3
+return array(
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Image Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Intervention Image supports "GD Library" and "Imagick" to process images
11
+    | internally. You may choose one of them according to your PHP
12
+    | configuration. By default PHP's "GD Library" implementation is used.
13
+    |
14
+    | Supported: "gd", "imagick"
15
+    |
16
+    */
17
+
18
+    'driver' => 'gd'
19
+
20
+);

+ 123
- 0
config/mail.php View File

@@ -0,0 +1,123 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Mail Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Laravel supports both SMTP and PHP's "mail" function as drivers for the
11
+    | sending of e-mail. You may specify which one you're using throughout
12
+    | your application here. By default, Laravel is setup for SMTP mail.
13
+    |
14
+    | Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
15
+    |            "sparkpost", "log", "array"
16
+    |
17
+    */
18
+
19
+    'driver' => env('MAIL_DRIVER', 'smtp'),
20
+
21
+    /*
22
+    |--------------------------------------------------------------------------
23
+    | SMTP Host Address
24
+    |--------------------------------------------------------------------------
25
+    |
26
+    | Here you may provide the host address of the SMTP server used by your
27
+    | applications. A default option is provided that is compatible with
28
+    | the Mailgun mail service which will provide reliable deliveries.
29
+    |
30
+    */
31
+
32
+    'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
33
+
34
+    /*
35
+    |--------------------------------------------------------------------------
36
+    | SMTP Host Port
37
+    |--------------------------------------------------------------------------
38
+    |
39
+    | This is the SMTP port used by your application to deliver e-mails to
40
+    | users of the application. Like the host we have set this value to
41
+    | stay compatible with the Mailgun e-mail application by default.
42
+    |
43
+    */
44
+
45
+    'port' => env('MAIL_PORT', 587),
46
+
47
+    /*
48
+    |--------------------------------------------------------------------------
49
+    | Global "From" Address
50
+    |--------------------------------------------------------------------------
51
+    |
52
+    | You may wish for all e-mails sent by your application to be sent from
53
+    | the same address. Here, you may specify a name and address that is
54
+    | used globally for all e-mails that are sent by your application.
55
+    |
56
+    */
57
+
58
+    'from' => [
59
+        'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
60
+        'name' => env('MAIL_FROM_NAME', 'Example'),
61
+    ],
62
+
63
+    /*
64
+    |--------------------------------------------------------------------------
65
+    | E-Mail Encryption Protocol
66
+    |--------------------------------------------------------------------------
67
+    |
68
+    | Here you may specify the encryption protocol that should be used when
69
+    | the application send e-mail messages. A sensible default using the
70
+    | transport layer security protocol should provide great security.
71
+    |
72
+    */
73
+
74
+    'encryption' => env('MAIL_ENCRYPTION', 'tls'),
75
+
76
+    /*
77
+    |--------------------------------------------------------------------------
78
+    | SMTP Server Username
79
+    |--------------------------------------------------------------------------
80
+    |
81
+    | If your SMTP server requires a username for authentication, you should
82
+    | set it here. This will get used to authenticate with your server on
83
+    | connection. You may also set the "password" value below this one.
84
+    |
85
+    */
86
+
87
+    'username' => env('MAIL_USERNAME'),
88
+
89
+    'password' => env('MAIL_PASSWORD'),
90
+
91
+    /*
92
+    |--------------------------------------------------------------------------
93
+    | Sendmail System Path
94
+    |--------------------------------------------------------------------------
95
+    |
96
+    | When using the "sendmail" driver to send e-mails, we will need to know
97
+    | the path to where Sendmail lives on this server. A default path has
98
+    | been provided here, which will work well on most of your systems.
99
+    |
100
+    */
101
+
102
+    'sendmail' => '/usr/sbin/sendmail -bs',
103
+
104
+    /*
105
+    |--------------------------------------------------------------------------
106
+    | Markdown Mail Settings
107
+    |--------------------------------------------------------------------------
108
+    |
109
+    | If you are using Markdown based email rendering, you may configure your
110
+    | theme and component paths here, allowing you to customize the design
111
+    | of the emails. Or, you may simply stick with the Laravel defaults!
112
+    |
113
+    */
114
+
115
+    'markdown' => [
116
+        'theme' => 'default',
117
+
118
+        'paths' => [
119
+            resource_path('views/vendor/mail'),
120
+        ],
121
+    ],
122
+
123
+];

+ 85
- 0
config/queue.php View File

@@ -0,0 +1,85 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Queue Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Laravel's queue API supports an assortment of back-ends via a single
11
+    | API, giving you convenient access to each back-end using the same
12
+    | syntax for each one. Here you may set the default queue driver.
13
+    |
14
+    | Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null"
15
+    |
16
+    */
17
+
18
+    'default' => env('QUEUE_DRIVER', 'sync'),
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Queue Connections
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | Here you may configure the connection information for each server that
26
+    | is used by your application. A default configuration has been added
27
+    | for each back-end shipped with Laravel. You are free to add more.
28
+    |
29
+    */
30
+
31
+    'connections' => [
32
+
33
+        'sync' => [
34
+            'driver' => 'sync',
35
+        ],
36
+
37
+        'database' => [
38
+            'driver' => 'database',
39
+            'table' => 'jobs',
40
+            'queue' => 'default',
41
+            'retry_after' => 90,
42
+        ],
43
+
44
+        'beanstalkd' => [
45
+            'driver' => 'beanstalkd',
46
+            'host' => 'localhost',
47
+            'queue' => 'default',
48
+            'retry_after' => 90,
49
+        ],
50
+
51
+        'sqs' => [
52
+            'driver' => 'sqs',
53
+            'key' => 'your-public-key',
54
+            'secret' => 'your-secret-key',
55
+            'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id',
56
+            'queue' => 'your-queue-name',
57
+            'region' => 'us-east-1',
58
+        ],
59
+
60
+        'redis' => [
61
+            'driver' => 'redis',
62
+            'connection' => 'default',
63
+            'queue' => 'default',
64
+            'retry_after' => 90,
65
+        ],
66
+
67
+    ],
68
+
69
+    /*
70
+    |--------------------------------------------------------------------------
71
+    | Failed Queue Jobs
72
+    |--------------------------------------------------------------------------
73
+    |
74
+    | These options configure the behavior of failed queue job logging so you
75
+    | can control which database and table are used to store the jobs that
76
+    | have failed. You may change them to any database / table you wish.
77
+    |
78
+    */
79
+
80
+    'failed' => [
81
+        'database' => env('DB_CONNECTION', 'mysql'),
82
+        'table' => 'failed_jobs',
83
+    ],
84
+
85
+];

+ 53
- 0
config/services.php View File

@@ -0,0 +1,53 @@
1
+<?php
2
+
3
+return [
4
+    
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Third Party Services
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This file is for storing the credentials for third party services such
11
+    | as Stripe, Mailgun, SparkPost and others. This file provides a sane
12
+    | default location for this type of information, allowing packages
13
+    | to have a conventional place to find your various credentials.
14
+    |
15
+    */
16
+    
17
+    'mailgun' => [
18
+        'domain' => env('MAILGUN_DOMAIN'),
19
+        'secret' => env('MAILGUN_SECRET'),
20
+    ],
21
+    
22
+    'ses' => [
23
+        'key'    => env('SES_KEY'),
24
+        'secret' => env('SES_SECRET'),
25
+        'region' => 'us-east-1',
26
+    ],
27
+    
28
+    'sparkpost' => [
29
+        'secret' => env('SPARKPOST_SECRET'),
30
+    ],
31
+    
32
+    'stripe' => [
33
+        'model'  => App\User::class,
34
+        'key'    => env('STRIPE_KEY'),
35
+        'secret' => env('STRIPE_SECRET'),
36
+    ],
37
+    
38
+    'line' => [
39
+        'line_login_channel_id' => env('LINE_LOGIN_CHANNEL_ID'),
40
+        'line_login_secret'     => env('LINE_LOGIN_SECRET'),
41
+        'authorize_base_url'    => 'https://access.line.me/oauth2/v2.1/authorize',
42
+        'get_token_url'         => 'https://api.line.me/oauth2/v2.1/token',
43
+        'get_user_profile_url'  => 'https://api.line.me/v2/profile',
44
+    ],
45
+
46
+    'ai_face' => [
47
+        'token_url' => env('AI_FACE_TOKEN_URL'),
48
+        'merge_url' => env('AI_FACE_MERGE_URL'),
49
+        'client_id' => env('AI_FACE_CLIENT_ID'),
50
+        'client_secret' => env('AI_FACE_CLIENT_SECRET'),
51
+    ]
52
+
53
+];

+ 179
- 0
config/session.php View File

@@ -0,0 +1,179 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | Default Session Driver
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | This option controls the default session "driver" that will be used on
11
+    | requests. By default, we will use the lightweight native driver but
12
+    | you may specify any of the other wonderful drivers provided here.
13
+    |
14
+    | Supported: "file", "cookie", "database", "apc",
15
+    |            "memcached", "redis", "array"
16
+    |
17
+    */
18
+
19
+    'driver' => env('SESSION_DRIVER', 'file'),
20
+
21
+    /*
22
+    |--------------------------------------------------------------------------
23
+    | Session Lifetime
24
+    |--------------------------------------------------------------------------
25
+    |
26
+    | Here you may specify the number of minutes that you wish the session
27
+    | to be allowed to remain idle before it expires. If you want them
28
+    | to immediately expire on the browser closing, set that option.
29
+    |
30
+    */
31
+
32
+    'lifetime' => 120,
33
+
34
+    'expire_on_close' => false,
35
+
36
+    /*
37
+    |--------------------------------------------------------------------------
38
+    | Session Encryption
39
+    |--------------------------------------------------------------------------
40
+    |
41
+    | This option allows you to easily specify that all of your session data
42
+    | should be encrypted before it is stored. All encryption will be run
43
+    | automatically by Laravel and you can use the Session like normal.
44
+    |
45
+    */
46
+
47
+    'encrypt' => false,
48
+
49
+    /*
50
+    |--------------------------------------------------------------------------
51
+    | Session File Location
52
+    |--------------------------------------------------------------------------
53
+    |
54
+    | When using the native session driver, we need a location where session
55
+    | files may be stored. A default has been set for you but a different
56
+    | location may be specified. This is only needed for file sessions.
57
+    |
58
+    */
59
+
60
+    'files' => storage_path('framework/sessions'),
61
+
62
+    /*
63
+    |--------------------------------------------------------------------------
64
+    | Session Database Connection
65
+    |--------------------------------------------------------------------------
66
+    |
67
+    | When using the "database" or "redis" session drivers, you may specify a
68
+    | connection that should be used to manage these sessions. This should
69
+    | correspond to a connection in your database configuration options.
70
+    |
71
+    */
72
+
73
+    'connection' => null,
74
+
75
+    /*
76
+    |--------------------------------------------------------------------------
77
+    | Session Database Table
78
+    |--------------------------------------------------------------------------
79
+    |
80
+    | When using the "database" session driver, you may specify the table we
81
+    | should use to manage the sessions. Of course, a sensible default is
82
+    | provided for you; however, you are free to change this as needed.
83
+    |
84
+    */
85
+
86
+    'table' => 'sessions',
87
+
88
+    /*
89
+    |--------------------------------------------------------------------------
90
+    | Session Cache Store
91
+    |--------------------------------------------------------------------------
92
+    |
93
+    | When using the "apc" or "memcached" session drivers, you may specify a
94
+    | cache store that should be used for these sessions. This value must
95
+    | correspond with one of the application's configured cache stores.
96
+    |
97
+    */
98
+
99
+    'store' => null,
100
+
101
+    /*
102
+    |--------------------------------------------------------------------------
103
+    | Session Sweeping Lottery
104
+    |--------------------------------------------------------------------------
105
+    |
106
+    | Some session drivers must manually sweep their storage location to get
107
+    | rid of old sessions from storage. Here are the chances that it will
108
+    | happen on a given request. By default, the odds are 2 out of 100.
109
+    |
110
+    */
111
+
112
+    'lottery' => [2, 100],
113
+
114
+    /*
115
+    |--------------------------------------------------------------------------
116
+    | Session Cookie Name
117
+    |--------------------------------------------------------------------------
118
+    |
119
+    | Here you may change the name of the cookie used to identify a session
120
+    | instance by ID. The name specified here will get used every time a
121
+    | new session cookie is created by the framework for every driver.
122
+    |
123
+    */
124
+
125
+    'cookie' => 'laravel_session',
126
+
127
+    /*
128
+    |--------------------------------------------------------------------------
129
+    | Session Cookie Path
130
+    |--------------------------------------------------------------------------
131
+    |
132
+    | The session cookie path determines the path for which the cookie will
133
+    | be regarded as available. Typically, this will be the root path of
134
+    | your application but you are free to change this when necessary.
135
+    |
136
+    */
137
+
138
+    'path' => '/',
139
+
140
+    /*
141
+    |--------------------------------------------------------------------------
142
+    | Session Cookie Domain
143
+    |--------------------------------------------------------------------------
144
+    |
145
+    | Here you may change the domain of the cookie used to identify a session
146
+    | in your application. This will determine which domains the cookie is
147
+    | available to in your application. A sensible default has been set.
148
+    |
149
+    */
150
+
151
+    'domain' => env('SESSION_DOMAIN', null),
152
+
153
+    /*
154
+    |--------------------------------------------------------------------------
155
+    | HTTPS Only Cookies
156
+    |--------------------------------------------------------------------------
157
+    |
158
+    | By setting this option to true, session cookies will only be sent back
159
+    | to the server if the browser has a HTTPS connection. This will keep
160
+    | the cookie from being sent to you if it can not be done securely.
161
+    |
162
+    */
163
+
164
+    'secure' => env('SESSION_SECURE_COOKIE', false),
165
+
166
+    /*
167
+    |--------------------------------------------------------------------------
168
+    | HTTP Access Only
169
+    |--------------------------------------------------------------------------
170
+    |
171
+    | Setting this value to true will prevent JavaScript from accessing the
172
+    | value of the cookie and the cookie will only be accessible through
173
+    | the HTTP protocol. You are free to modify this option if needed.
174
+    |
175
+    */
176
+
177
+    'http_only' => true,
178
+
179
+];

+ 33
- 0
config/view.php View File

@@ -0,0 +1,33 @@
1
+<?php
2
+
3
+return [
4
+
5
+    /*
6
+    |--------------------------------------------------------------------------
7
+    | View Storage Paths
8
+    |--------------------------------------------------------------------------
9
+    |
10
+    | Most templating systems load templates from disk. Here you may specify
11
+    | an array of paths that should be checked for your views. Of course
12
+    | the usual Laravel view path has already been registered for you.
13
+    |
14
+    */
15
+
16
+    'paths' => [
17
+        resource_path('views'),
18
+    ],
19
+
20
+    /*
21
+    |--------------------------------------------------------------------------
22
+    | Compiled View Path
23
+    |--------------------------------------------------------------------------
24
+    |
25
+    | This option determines where all the compiled Blade templates will be
26
+    | stored for your application. Typically, this is within the storage
27
+    | directory. However, as usual, you are free to change this value.
28
+    |
29
+    */
30
+
31
+    'compiled' => realpath(storage_path('framework/views')),
32
+
33
+];

+ 1
- 0
database/.gitignore View File

@@ -0,0 +1 @@
1
+*.sqlite

+ 24
- 0
database/factories/ModelFactory.php View File

@@ -0,0 +1,24 @@
1
+<?php
2
+
3
+/*
4
+|--------------------------------------------------------------------------
5
+| Model Factories
6
+|--------------------------------------------------------------------------
7
+|
8
+| Here you may define all of your model factories. Model factories give
9
+| you a convenient way to create models for testing and seeding your
10
+| database. Just tell the factory how a default model should look.
11
+|
12
+*/
13
+
14
+/** @var \Illuminate\Database\Eloquent\Factory $factory */
15
+$factory->define(App\User::class, function (Faker\Generator $faker) {
16
+    static $password;
17
+
18
+    return [
19
+        'name' => $faker->name,
20
+        'email' => $faker->unique()->safeEmail,
21
+        'password' => $password ?: $password = bcrypt('secret'),
22
+        'remember_token' => str_random(10),
23
+    ];
24
+});

+ 35
- 0
database/migrations/2014_10_12_000000_create_users_table.php View File

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Support\Facades\Schema;
4
+use Illuminate\Database\Schema\Blueprint;
5
+use Illuminate\Database\Migrations\Migration;
6
+
7
+class CreateUsersTable extends Migration
8
+{
9
+    /**
10
+     * Run the migrations.
11
+     *
12
+     * @return void
13
+     */
14
+    public function up()
15
+    {
16
+        Schema::create('users', function (Blueprint $table) {
17
+            $table->increments('id');
18
+            $table->string('name');
19
+            $table->string('email')->unique();
20
+            $table->string('password');
21
+            $table->rememberToken();
22
+            $table->timestamps();
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::dropIfExists('users');
34
+    }
35
+}

+ 32
- 0
database/migrations/2014_10_12_100000_create_password_resets_table.php View File

@@ -0,0 +1,32 @@
1
+<?php
2
+
3
+use Illuminate\Support\Facades\Schema;
4
+use Illuminate\Database\Schema\Blueprint;
5
+use Illuminate\Database\Migrations\Migration;
6
+
7
+class CreatePasswordResetsTable extends Migration
8
+{
9
+    /**
10
+     * Run the migrations.
11
+     *
12
+     * @return void
13
+     */
14
+    public function up()
15
+    {
16
+        Schema::create('password_resets', function (Blueprint $table) {
17
+            $table->string('email')->index();
18
+            $table->string('token')->index();
19
+            $table->timestamp('created_at')->nullable();
20
+        });
21
+    }
22
+
23
+    /**
24
+     * Reverse the migrations.
25
+     *
26
+     * @return void
27
+     */
28
+    public function down()
29
+    {
30
+        Schema::dropIfExists('password_resets');
31
+    }
32
+}

+ 35
- 0
database/migrations/2016_02_23_075631_create_functions_table.php View File

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunctionsTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('functions', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->string('FunName');
18
+            $table->string('FunLink');
19
+            $table->string('FunDesc');
20
+            $table->integer('Valid');
21
+            $table->timestamps();
22
+            $table->integer('Oid');
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::drop('functions');
34
+    }
35
+}

+ 34
- 0
database/migrations/2016_02_23_080148_create_funmenu_table.php View File

@@ -0,0 +1,34 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunmenuTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('funmenu', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->string('MenuName');
18
+            $table->integer('Valid');
19
+            $table->integer('Corder');
20
+            $table->timestamps();
21
+            $table->integer('Oid');
22
+        });
23
+    }
24
+
25
+    /**
26
+     * Reverse the migrations.
27
+     *
28
+     * @return void
29
+     */
30
+    public function down()
31
+    {
32
+        Schema::drop('funmenu');
33
+    }
34
+}

+ 35
- 0
database/migrations/2016_02_23_080344_create_funmenudetail_table.php View File

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunmenudetailTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('funmenudetail', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->integer('FunMenuId');
18
+            $table->integer('FunId');
19
+            $table->integer('Valid');
20
+            $table->integer('Corder');
21
+            $table->timestamps();
22
+            $table->integer('Oid');
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::drop('funmenudetail');
34
+    }
35
+}

+ 35
- 0
database/migrations/2016_02_23_080520_create_funusergroups_table.php View File

@@ -0,0 +1,35 @@
1
+<?php
2
+
3
+use Illuminate\Database\Schema\Blueprint;
4
+use Illuminate\Database\Migrations\Migration;
5
+
6
+class CreateFunusergroupsTable extends Migration
7
+{
8
+    /**
9
+     * Run the migrations.
10
+     *
11
+     * @return void
12
+     */
13
+    public function up()
14
+    {
15
+        Schema::create('funusergroups', function (Blueprint $table) {
16
+            $table->increments('id');
17
+            $table->string('Name');
18
+            $table->string('FunList');
19
+            $table->string('UsrList');
20
+            $table->integer('Valid');
21
+            $table->timestamps();
22
+            $table->integer('Oid');
23
+        });
24
+    }
25
+
26
+    /**
27
+     * Reverse the migrations.
28
+     *
29
+     * @return void
30
+     */
31
+    public function down()
32
+    {
33
+        Schema::drop('funusergroups');
34
+    }
35
+}

+ 16
- 0
database/seeds/DatabaseSeeder.php View File

@@ -0,0 +1,16 @@
1
+<?php
2
+
3
+use Illuminate\Database\Seeder;
4
+
5
+class DatabaseSeeder extends Seeder
6
+{
7
+    /**
8
+     * Run the database seeds.
9
+     *
10
+     * @return void
11
+     */
12
+    public function run()
13
+    {
14
+        // $this->call(UsersTableSeeder::class);
15
+    }
16
+}

+ 19
- 0
package.json View File

@@ -0,0 +1,19 @@
1
+{
2
+  "private": true,
3
+  "scripts": {
4
+    "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
5
+    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
6
+    "watch-poll": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --watch-poll --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
7
+    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
8
+    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
9
+  },
10
+  "devDependencies": {
11
+    "axios": "^0.15.3",
12
+    "bootstrap-sass": "^3.3.7",
13
+    "cross-env": "^3.2.3",
14
+    "jquery": "^3.1.1",
15
+    "laravel-mix": "^0.8.3",
16
+    "lodash": "^4.17.4",
17
+    "vue": "^2.1.10"
18
+  }
19
+}

+ 31
- 0
phpunit.xml View File

@@ -0,0 +1,31 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<phpunit backupGlobals="false"
3
+         backupStaticAttributes="false"
4
+         bootstrap="bootstrap/autoload.php"
5
+         colors="true"
6
+         convertErrorsToExceptions="true"
7
+         convertNoticesToExceptions="true"
8
+         convertWarningsToExceptions="true"
9
+         processIsolation="false"
10
+         stopOnFailure="false">
11
+    <testsuites>
12
+        <testsuite name="Feature Tests">
13
+            <directory suffix="Test.php">./tests/Feature</directory>
14
+        </testsuite>
15
+
16
+        <testsuite name="Unit Tests">
17
+            <directory suffix="Test.php">./tests/Unit</directory>
18
+        </testsuite>
19
+    </testsuites>
20
+    <filter>
21
+        <whitelist processUncoveredFilesFromWhitelist="true">
22
+            <directory suffix=".php">./app</directory>
23
+        </whitelist>
24
+    </filter>
25
+    <php>
26
+        <env name="APP_ENV" value="testing"/>
27
+        <env name="CACHE_DRIVER" value="array"/>
28
+        <env name="SESSION_DRIVER" value="array"/>
29
+        <env name="QUEUE_DRIVER" value="sync"/>
30
+    </php>
31
+</phpunit>

+ 21
- 0
public/.htaccess View File

@@ -0,0 +1,21 @@
1
+<IfModule mod_rewrite.c>
2
+    <IfModule mod_negotiation.c>
3
+        Options -MultiViews
4
+    </IfModule>
5
+
6
+    RewriteEngine On
7
+
8
+    # Redirect Trailing Slashes If Not A Folder...
9
+#    RewriteCond %{REQUEST_URI} !^/main/
10
+    RewriteCond %{REQUEST_FILENAME} !-d
11
+    RewriteRule ^(.*)/$ /$1 [L,R=301]
12
+
13
+    # Handle Front Controller...
14
+    RewriteCond %{REQUEST_FILENAME} !-d
15
+    RewriteCond %{REQUEST_FILENAME} !-f
16
+    RewriteRule ^ index.php [L]
17
+
18
+    # Handle Authorization Header
19
+    RewriteCond %{HTTP:Authorization} .
20
+    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
21
+</IfModule>

+ 1
- 0
public/91APP/css/normalize.min.css View File

@@ -0,0 +1 @@
1
+/*! normalize.css v1.1.2 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}

+ 124
- 0
public/91APP/css/style.css View File

@@ -0,0 +1,124 @@
1
+@charset "UTF-8";
2
+/**
3
+ *
4
+ * @authors Eric Hsiao
5
+ *
6
+ */
7
+
8
+/* ==========================================================================
9
+   HTML5 Boilerplate styles - h5bp.com (generated via initializr.com)
10
+   ========================================================================== */
11
+
12
+.chromeframe {
13
+    margin: 0.2em 0;
14
+    background: #ccc;
15
+    color: #000;
16
+    padding: 0.2em 0;
17
+}
18
+
19
+/* ==========================================================================
20
+   Content class
21
+   ========================================================================== */
22
+
23
+html,
24
+body {
25
+  margin:0;
26
+  padding:0;
27
+  height:100%;
28
+}
29
+
30
+#wrapper {
31
+  min-height:100%;
32
+  position:relative;
33
+}
34
+
35
+#header {
36
+  background:#ededed;
37
+  padding-top:10px; /* fixed h1 */
38
+}
39
+
40
+#content {
41
+  padding-bottom:100px; /* Height of the footer element */
42
+}
43
+
44
+#footer {
45
+  background:#666;
46
+  width:100%;
47
+  height:100px;
48
+  position:absolute;
49
+  bottom:0;
50
+  left:0;
51
+}
52
+
53
+/* ==========================================================================
54
+   Responsive class
55
+   ========================================================================== */
56
+
57
+
58
+@media only screen and (max-width: 640px) {
59
+
60
+
61
+}
62
+
63
+
64
+/* ==========================================================================
65
+   Helper classes
66
+   ========================================================================== */
67
+
68
+.ir {
69
+    background-color: transparent;
70
+    border: 0;
71
+    overflow: hidden;
72
+    *text-indent: -9999px;
73
+}
74
+
75
+.ir:before {
76
+    content: "";
77
+    display: block;
78
+    width: 0;
79
+    height: 150%;
80
+}
81
+
82
+.hidden {
83
+    display: none !important;
84
+    visibility: hidden;
85
+}
86
+
87
+.visuallyhidden {
88
+    border: 0;
89
+    clip: rect(0 0 0 0);
90
+    height: 1px;
91
+    margin: -1px;
92
+    overflow: hidden;
93
+    padding: 0;
94
+    position: absolute;
95
+    width: 1px;
96
+}
97
+
98
+.visuallyhidden.focusable:active,
99
+.visuallyhidden.focusable:focus {
100
+    clip: auto;
101
+    height: auto;
102
+    margin: 0;
103
+    overflow: visible;
104
+    position: static;
105
+    width: auto;
106
+}
107
+
108
+.invisible {
109
+    visibility: hidden;
110
+}
111
+
112
+.clearfix:before,
113
+.clearfix:after {
114
+    content: " ";
115
+    display: table;
116
+}
117
+
118
+.clearfix:after {
119
+    clear: both;
120
+}
121
+
122
+.clearfix {
123
+    *zoom: 1;
124
+}

BIN
public/91APP/images/share.jpg View File


+ 53
- 0
public/91APP/index.html View File

@@ -0,0 +1,53 @@
1
+<!DOCTYPE html>
2
+<!--[if IE 6]><html class="ie6 lte9 lte8 lte7" lang="zh-tw"><![endif]-->
3
+<!--[if IE 8]><html class="ie8 lte9 lte8" lang="zh-tw"><![endif]-->
4
+<!--[if IE 9]><html class="ie9 lte9" lang="zh-tw"><![endif]-->
5
+<!--[if IE 7]><html class="ie7 lte9 lte8 lte7" lang="zh-tw"><![endif]-->
6
+<!--[if !(IE 6) | !(IE 7) | !(IE 8) | !(IE 9)  ]><!--><html  lang="zh-tw"><!--<![endif]-->
7
+    <head>
8
+        <meta charset="utf-8">
9
+        <meta content-language="zh-TW">
10
+        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
11
+        <meta name="description" content="">
12
+        <meta name="viewport" content="width=1000,initial-scale=1,maximum-scale=1,user-scalable=0">
13
+        <meta property="og:title" content=""/>
14
+        <meta property="og:description" content=""/>
15
+        <meta property="og:url" content=""/>
16
+        <meta property="og:image" content=""/>
17
+
18
+         <title></title>
19
+
20
+        <link rel="stylesheet" href="css/normalize.min.css">
21
+        <link rel="stylesheet" href="css/style.css">
22
+        <script src="js/libs/modernizr-2.6.2-respond-1.1.0.min.js"></script>
23
+
24
+        <style>
25
+          #content{
26
+            max-width: 400px;
27
+            word-break: break-all;
28
+          }
29
+        </style>
30
+    </head>
31
+    <body>
32
+
33
+        <div id="wrapper">
34
+            <div id="header">
35
+                <h1>header</h1>
36
+            </div><!-- #header -->
37
+
38
+            <div id="content">
39
+                <h1>content</h1>
40
+            </div><!-- #content -->
41
+
42
+            <div id="footer">
43
+                <h1>footer</h1>
44
+            </div><!-- #footer -->
45
+
46
+        </div><!-- #wrapper -->
47
+
48
+        <script src="js/libs/jquery-1.11.1.min.js"></script>
49
+        <script src="js/utlis.js"></script>
50
+        <script src="js/main.js"></script>
51
+
52
+    </body>
53
+</html>

+ 17
- 0
public/91APP/js/libs/TweenMax.min.js
File diff suppressed because it is too large
View File


+ 12
- 0
public/91APP/js/libs/easing/EasePack.min.js View File

@@ -0,0 +1,12 @@
1
+/*!
2
+ * VERSION: beta 1.15.2
3
+ * DATE: 2015-01-27
4
+ * UPDATES AND DOCS AT: http://greensock.com
5
+ *
6
+ * @license Copyright (c) 2008-2015, GreenSock. All rights reserved.
7
+ * This work is subject to the terms at http://greensock.com/standard-license or for
8
+ * Club GreenSock members, the software agreement that was issued with your membership.
9
+ * 
10
+ * @author: Jack Doyle, jack@greensock.com
11
+ **/
12
+var _gsScope="undefined"!=typeof module&&module.exports&&"undefined"!=typeof global?global:this||window;(_gsScope._gsQueue||(_gsScope._gsQueue=[])).push(function(){"use strict";_gsScope._gsDefine("easing.Back",["easing.Ease"],function(t){var e,i,s,r=_gsScope.GreenSockGlobals||_gsScope,n=r.com.greensock,a=2*Math.PI,o=Math.PI/2,h=n._class,l=function(e,i){var s=h("easing."+e,function(){},!0),r=s.prototype=new t;return r.constructor=s,r.getRatio=i,s},_=t.register||function(){},u=function(t,e,i,s){var r=h("easing."+t,{easeOut:new e,easeIn:new i,easeInOut:new s},!0);return _(r,t),r},c=function(t,e,i){this.t=t,this.v=e,i&&(this.next=i,i.prev=this,this.c=i.v-e,this.gap=i.t-t)},p=function(e,i){var s=h("easing."+e,function(t){this._p1=t||0===t?t:1.70158,this._p2=1.525*this._p1},!0),r=s.prototype=new t;return r.constructor=s,r.getRatio=i,r.config=function(t){return new s(t)},s},f=u("Back",p("BackOut",function(t){return(t-=1)*t*((this._p1+1)*t+this._p1)+1}),p("BackIn",function(t){return t*t*((this._p1+1)*t-this._p1)}),p("BackInOut",function(t){return 1>(t*=2)?.5*t*t*((this._p2+1)*t-this._p2):.5*((t-=2)*t*((this._p2+1)*t+this._p2)+2)})),m=h("easing.SlowMo",function(t,e,i){e=e||0===e?e:.7,null==t?t=.7:t>1&&(t=1),this._p=1!==t?e:0,this._p1=(1-t)/2,this._p2=t,this._p3=this._p1+this._p2,this._calcEnd=i===!0},!0),d=m.prototype=new t;return d.constructor=m,d.getRatio=function(t){var e=t+(.5-t)*this._p;return this._p1>t?this._calcEnd?1-(t=1-t/this._p1)*t:e-(t=1-t/this._p1)*t*t*t*e:t>this._p3?this._calcEnd?1-(t=(t-this._p3)/this._p1)*t:e+(t-e)*(t=(t-this._p3)/this._p1)*t*t*t:this._calcEnd?1:e},m.ease=new m(.7,.7),d.config=m.config=function(t,e,i){return new m(t,e,i)},e=h("easing.SteppedEase",function(t){t=t||1,this._p1=1/t,this._p2=t+1},!0),d=e.prototype=new t,d.constructor=e,d.getRatio=function(t){return 0>t?t=0:t>=1&&(t=.999999999),(this._p2*t>>0)*this._p1},d.config=e.config=function(t){return new e(t)},i=h("easing.RoughEase",function(e){e=e||{};for(var i,s,r,n,a,o,h=e.taper||"none",l=[],_=0,u=0|(e.points||20),p=u,f=e.randomize!==!1,m=e.clamp===!0,d=e.template instanceof t?e.template:null,g="number"==typeof e.strength?.4*e.strength:.4;--p>-1;)i=f?Math.random():1/u*p,s=d?d.getRatio(i):i,"none"===h?r=g:"out"===h?(n=1-i,r=n*n*g):"in"===h?r=i*i*g:.5>i?(n=2*i,r=.5*n*n*g):(n=2*(1-i),r=.5*n*n*g),f?s+=Math.random()*r-.5*r:p%2?s+=.5*r:s-=.5*r,m&&(s>1?s=1:0>s&&(s=0)),l[_++]={x:i,y:s};for(l.sort(function(t,e){return t.x-e.x}),o=new c(1,1,null),p=u;--p>-1;)a=l[p],o=new c(a.x,a.y,o);this._prev=new c(0,0,0!==o.t?o:o.next)},!0),d=i.prototype=new t,d.constructor=i,d.getRatio=function(t){var e=this._prev;if(t>e.t){for(;e.next&&t>=e.t;)e=e.next;e=e.prev}else for(;e.prev&&e.t>=t;)e=e.prev;return this._prev=e,e.v+(t-e.t)/e.gap*e.c},d.config=function(t){return new i(t)},i.ease=new i,u("Bounce",l("BounceOut",function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}),l("BounceIn",function(t){return 1/2.75>(t=1-t)?1-7.5625*t*t:2/2.75>t?1-(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1-(7.5625*(t-=2.25/2.75)*t+.9375):1-(7.5625*(t-=2.625/2.75)*t+.984375)}),l("BounceInOut",function(t){var e=.5>t;return t=e?1-2*t:2*t-1,t=1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375,e?.5*(1-t):.5*t+.5})),u("Circ",l("CircOut",function(t){return Math.sqrt(1-(t-=1)*t)}),l("CircIn",function(t){return-(Math.sqrt(1-t*t)-1)}),l("CircInOut",function(t){return 1>(t*=2)?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)})),s=function(e,i,s){var r=h("easing."+e,function(t,e){this._p1=t>=1?t:1,this._p2=(e||s)/(1>t?t:1),this._p3=this._p2/a*(Math.asin(1/this._p1)||0),this._p2=a/this._p2},!0),n=r.prototype=new t;return n.constructor=r,n.getRatio=i,n.config=function(t,e){return new r(t,e)},r},u("Elastic",s("ElasticOut",function(t){return this._p1*Math.pow(2,-10*t)*Math.sin((t-this._p3)*this._p2)+1},.3),s("ElasticIn",function(t){return-(this._p1*Math.pow(2,10*(t-=1))*Math.sin((t-this._p3)*this._p2))},.3),s("ElasticInOut",function(t){return 1>(t*=2)?-.5*this._p1*Math.pow(2,10*(t-=1))*Math.sin((t-this._p3)*this._p2):.5*this._p1*Math.pow(2,-10*(t-=1))*Math.sin((t-this._p3)*this._p2)+1},.45)),u("Expo",l("ExpoOut",function(t){return 1-Math.pow(2,-10*t)}),l("ExpoIn",function(t){return Math.pow(2,10*(t-1))-.001}),l("ExpoInOut",function(t){return 1>(t*=2)?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*(t-1)))})),u("Sine",l("SineOut",function(t){return Math.sin(t*o)}),l("SineIn",function(t){return-Math.cos(t*o)+1}),l("SineInOut",function(t){return-.5*(Math.cos(Math.PI*t)-1)})),h("easing.EaseLookup",{find:function(e){return t.map[e]}},!0),_(r.SlowMo,"SlowMo","ease,"),_(i,"RoughEase","ease,"),_(e,"SteppedEase","ease,"),f},!0)}),_gsScope._gsDefine&&_gsScope._gsQueue.pop()();

+ 4
- 0
public/91APP/js/libs/jquery-1.11.1.min.js
File diff suppressed because it is too large
View File


+ 1
- 0
public/91APP/js/libs/jquery-1.11.1.min.map
File diff suppressed because it is too large
View File


+ 118
- 0
public/91APP/js/libs/jquery.nicescroll.min.js View File

@@ -0,0 +1,118 @@
1
+/* jquery.nicescroll 3.6.0 InuYaksa*2014 MIT http://nicescroll.areaaperta.com */(function(f){"function"===typeof define&&define.amd?define(["jquery"],f):f(jQuery)})(function(f){var y=!1,D=!1,N=0,O=2E3,x=0,H=["webkit","ms","moz","o"],s=window.requestAnimationFrame||!1,t=window.cancelAnimationFrame||!1;if(!s)for(var P in H){var E=H[P];s||(s=window[E+"RequestAnimationFrame"]);t||(t=window[E+"CancelAnimationFrame"]||window[E+"CancelRequestAnimationFrame"])}var v=window.MutationObserver||window.WebKitMutationObserver||!1,I={zindex:"auto",cursoropacitymin:0,cursoropacitymax:1,cursorcolor:"#424242",
2
+cursorwidth:"5px",cursorborder:"1px solid #fff",cursorborderradius:"5px",scrollspeed:60,mousescrollstep:24,touchbehavior:!1,hwacceleration:!0,usetransition:!0,boxzoom:!1,dblclickzoom:!0,gesturezoom:!0,grabcursorenabled:!0,autohidemode:!0,background:"",iframeautoresize:!0,cursorminheight:32,preservenativescrolling:!0,railoffset:!1,railhoffset:!1,bouncescroll:!0,spacebarenabled:!0,railpadding:{top:0,right:0,left:0,bottom:0},disableoutline:!0,horizrailenabled:!0,railalign:"right",railvalign:"bottom",
3
+enabletranslate3d:!0,enablemousewheel:!0,enablekeyboard:!0,smoothscroll:!0,sensitiverail:!0,enablemouselockapi:!0,cursorfixedheight:!1,directionlockdeadzone:6,hidecursordelay:400,nativeparentscrolling:!0,enablescrollonselection:!0,overflowx:!0,overflowy:!0,cursordragspeed:.3,rtlmode:"auto",cursordragontouch:!1,oneaxismousemode:"auto",scriptpath:function(){var f=document.getElementsByTagName("script"),f=f[f.length-1].src.split("?")[0];return 0<f.split("/").length?f.split("/").slice(0,-1).join("/")+
4
+"/":""}(),preventmultitouchscrolling:!0},F=!1,Q=function(){if(F)return F;var f=document.createElement("DIV"),c=f.style,h=navigator.userAgent,m=navigator.platform,d={haspointerlock:"pointerLockElement"in document||"webkitPointerLockElement"in document||"mozPointerLockElement"in document};d.isopera="opera"in window;d.isopera12=d.isopera&&"getUserMedia"in navigator;d.isoperamini="[object OperaMini]"===Object.prototype.toString.call(window.operamini);d.isie="all"in document&&"attachEvent"in f&&!d.isopera;
5
+d.isieold=d.isie&&!("msInterpolationMode"in c);d.isie7=d.isie&&!d.isieold&&(!("documentMode"in document)||7==document.documentMode);d.isie8=d.isie&&"documentMode"in document&&8==document.documentMode;d.isie9=d.isie&&"performance"in window&&9<=document.documentMode;d.isie10=d.isie&&"performance"in window&&10==document.documentMode;d.isie11="msRequestFullscreen"in f&&11<=document.documentMode;d.isie9mobile=/iemobile.9/i.test(h);d.isie9mobile&&(d.isie9=!1);d.isie7mobile=!d.isie9mobile&&d.isie7&&/iemobile/i.test(h);
6
+d.ismozilla="MozAppearance"in c;d.iswebkit="WebkitAppearance"in c;d.ischrome="chrome"in window;d.ischrome22=d.ischrome&&d.haspointerlock;d.ischrome26=d.ischrome&&"transition"in c;d.cantouch="ontouchstart"in document.documentElement||"ontouchstart"in window;d.hasmstouch=window.MSPointerEvent||!1;d.hasw3ctouch=window.PointerEvent||!1;d.ismac=/^mac$/i.test(m);d.isios=d.cantouch&&/iphone|ipad|ipod/i.test(m);d.isios4=d.isios&&!("seal"in Object);d.isios7=d.isios&&"webkitHidden"in document;d.isandroid=/android/i.test(h);
7
+d.haseventlistener="addEventListener"in f;d.trstyle=!1;d.hastransform=!1;d.hastranslate3d=!1;d.transitionstyle=!1;d.hastransition=!1;d.transitionend=!1;m=["transform","msTransform","webkitTransform","MozTransform","OTransform"];for(h=0;h<m.length;h++)if("undefined"!=typeof c[m[h]]){d.trstyle=m[h];break}d.hastransform=!!d.trstyle;d.hastransform&&(c[d.trstyle]="translate3d(1px,2px,3px)",d.hastranslate3d=/translate3d/.test(c[d.trstyle]));d.transitionstyle=!1;d.prefixstyle="";d.transitionend=!1;for(var m=
8
+"transition webkitTransition msTransition MozTransition OTransition OTransition KhtmlTransition".split(" "),n=" -webkit- -ms- -moz- -o- -o -khtml-".split(" "),p="transitionend webkitTransitionEnd msTransitionEnd transitionend otransitionend oTransitionEnd KhtmlTransitionEnd".split(" "),h=0;h<m.length;h++)if(m[h]in c){d.transitionstyle=m[h];d.prefixstyle=n[h];d.transitionend=p[h];break}d.ischrome26&&(d.prefixstyle=n[1]);d.hastransition=d.transitionstyle;a:{h=["-webkit-grab","-moz-grab","grab"];if(d.ischrome&&
9
+!d.ischrome22||d.isie)h=[];for(m=0;m<h.length;m++)if(n=h[m],c.cursor=n,c.cursor==n){c=n;break a}c="url(//mail.google.com/mail/images/2/openhand.cur),n-resize"}d.cursorgrabvalue=c;d.hasmousecapture="setCapture"in f;d.hasMutationObserver=!1!==v;return F=d},R=function(k,c){function h(){var b=a.doc.css(e.trstyle);return b&&"matrix"==b.substr(0,6)?b.replace(/^.*\((.*)\)$/g,"$1").replace(/px/g,"").split(/, +/):!1}function m(){var b=a.win;if("zIndex"in b)return b.zIndex();for(;0<b.length&&9!=b[0].nodeType;){var g=
10
+b.css("zIndex");if(!isNaN(g)&&0!=g)return parseInt(g);b=b.parent()}return!1}function d(b,g,q){g=b.css(g);b=parseFloat(g);return isNaN(b)?(b=w[g]||0,q=3==b?q?a.win.outerHeight()-a.win.innerHeight():a.win.outerWidth()-a.win.innerWidth():1,a.isie8&&b&&(b+=1),q?b:0):b}function n(b,g,q,c){a._bind(b,g,function(a){a=a?a:window.event;var c={original:a,target:a.target||a.srcElement,type:"wheel",deltaMode:"MozMousePixelScroll"==a.type?0:1,deltaX:0,deltaZ:0,preventDefault:function(){a.preventDefault?a.preventDefault():
11
+a.returnValue=!1;return!1},stopImmediatePropagation:function(){a.stopImmediatePropagation?a.stopImmediatePropagation():a.cancelBubble=!0}};"mousewheel"==g?(c.deltaY=-.025*a.wheelDelta,a.wheelDeltaX&&(c.deltaX=-.025*a.wheelDeltaX)):c.deltaY=a.detail;return q.call(b,c)},c)}function p(b,g,c){var d,e;0==b.deltaMode?(d=-Math.floor(a.opt.mousescrollstep/54*b.deltaX),e=-Math.floor(a.opt.mousescrollstep/54*b.deltaY)):1==b.deltaMode&&(d=-Math.floor(b.deltaX*a.opt.mousescrollstep),e=-Math.floor(b.deltaY*a.opt.mousescrollstep));
12
+g&&a.opt.oneaxismousemode&&0==d&&e&&(d=e,e=0,c&&(0>d?a.getScrollLeft()>=a.page.maxw:0>=a.getScrollLeft())&&(e=d,d=0));d&&(a.scrollmom&&a.scrollmom.stop(),a.lastdeltax+=d,a.debounced("mousewheelx",function(){var b=a.lastdeltax;a.lastdeltax=0;a.rail.drag||a.doScrollLeftBy(b)},15));if(e){if(a.opt.nativeparentscrolling&&c&&!a.ispage&&!a.zoomactive)if(0>e){if(a.getScrollTop()>=a.page.maxh)return!0}else if(0>=a.getScrollTop())return!0;a.scrollmom&&a.scrollmom.stop();a.lastdeltay+=e;a.debounced("mousewheely",
13
+function(){var b=a.lastdeltay;a.lastdeltay=0;a.rail.drag||a.doScrollBy(b)},15)}b.stopImmediatePropagation();return b.preventDefault()}var a=this;this.version="3.6.0";this.name="nicescroll";this.me=c;this.opt={doc:f("body"),win:!1};f.extend(this.opt,I);this.opt.snapbackspeed=80;if(k)for(var G in a.opt)"undefined"!=typeof k[G]&&(a.opt[G]=k[G]);this.iddoc=(this.doc=a.opt.doc)&&this.doc[0]?this.doc[0].id||"":"";this.ispage=/^BODY|HTML/.test(a.opt.win?a.opt.win[0].nodeName:this.doc[0].nodeName);this.haswrapper=
14
+!1!==a.opt.win;this.win=a.opt.win||(this.ispage?f(window):this.doc);this.docscroll=this.ispage&&!this.haswrapper?f(window):this.win;this.body=f("body");this.iframe=this.isfixed=this.viewport=!1;this.isiframe="IFRAME"==this.doc[0].nodeName&&"IFRAME"==this.win[0].nodeName;this.istextarea="TEXTAREA"==this.win[0].nodeName;this.forcescreen=!1;this.canshowonmouseevent="scroll"!=a.opt.autohidemode;this.page=this.view=this.onzoomout=this.onzoomin=this.onscrollcancel=this.onscrollend=this.onscrollstart=this.onclick=
15
+this.ongesturezoom=this.onkeypress=this.onmousewheel=this.onmousemove=this.onmouseup=this.onmousedown=!1;this.scroll={x:0,y:0};this.scrollratio={x:0,y:0};this.cursorheight=20;this.scrollvaluemax=0;this.isrtlmode="auto"==this.opt.rtlmode?"rtl"==(this.win[0]==window?this.body:this.win).css("direction"):!0===this.opt.rtlmode;this.observerbody=this.observerremover=this.observer=this.scrollmom=this.scrollrunning=!1;do this.id="ascrail"+O++;while(document.getElementById(this.id));this.hasmousefocus=this.hasfocus=
16
+this.zoomactive=this.zoom=this.selectiondrag=this.cursorfreezed=this.cursor=this.rail=!1;this.visibility=!0;this.hidden=this.locked=this.railslocked=!1;this.cursoractive=!0;this.wheelprevented=!1;this.overflowx=a.opt.overflowx;this.overflowy=a.opt.overflowy;this.nativescrollingarea=!1;this.checkarea=0;this.events=[];this.saved={};this.delaylist={};this.synclist={};this.lastdeltay=this.lastdeltax=0;this.detected=Q();var e=f.extend({},this.detected);this.ishwscroll=(this.canhwscroll=e.hastransform&&
17
+a.opt.hwacceleration)&&a.haswrapper;this.hasreversehr=this.isrtlmode&&!e.iswebkit;this.istouchcapable=!1;!e.cantouch||e.isios||e.isandroid||!e.iswebkit&&!e.ismozilla||(this.istouchcapable=!0,e.cantouch=!1);a.opt.enablemouselockapi||(e.hasmousecapture=!1,e.haspointerlock=!1);this.debounced=function(b,g,c){var d=a.delaylist[b];a.delaylist[b]=g;d||setTimeout(function(){var g=a.delaylist[b];a.delaylist[b]=!1;g.call(a)},c)};var r=!1;this.synched=function(b,g){a.synclist[b]=g;(function(){r||(s(function(){r=
18
+!1;for(var b in a.synclist){var g=a.synclist[b];g&&g.call(a);a.synclist[b]=!1}}),r=!0)})();return b};this.unsynched=function(b){a.synclist[b]&&(a.synclist[b]=!1)};this.css=function(b,g){for(var c in g)a.saved.css.push([b,c,b.css(c)]),b.css(c,g[c])};this.scrollTop=function(b){return"undefined"==typeof b?a.getScrollTop():a.setScrollTop(b)};this.scrollLeft=function(b){return"undefined"==typeof b?a.getScrollLeft():a.setScrollLeft(b)};var A=function(a,g,c,d,e,f,h){this.st=a;this.ed=g;this.spd=c;this.p1=
19
+d||0;this.p2=e||1;this.p3=f||0;this.p4=h||1;this.ts=(new Date).getTime();this.df=this.ed-this.st};A.prototype={B2:function(a){return 3*a*a*(1-a)},B3:function(a){return 3*a*(1-a)*(1-a)},B4:function(a){return(1-a)*(1-a)*(1-a)},getNow:function(){var a=1-((new Date).getTime()-this.ts)/this.spd,g=this.B2(a)+this.B3(a)+this.B4(a);return 0>a?this.ed:this.st+Math.round(this.df*g)},update:function(a,g){this.st=this.getNow();this.ed=a;this.spd=g;this.ts=(new Date).getTime();this.df=this.ed-this.st;return this}};
20
+if(this.ishwscroll){this.doc.translate={x:0,y:0,tx:"0px",ty:"0px"};e.hastranslate3d&&e.isios&&this.doc.css("-webkit-backface-visibility","hidden");this.getScrollTop=function(b){if(!b){if(b=h())return 16==b.length?-b[13]:-b[5];if(a.timerscroll&&a.timerscroll.bz)return a.timerscroll.bz.getNow()}return a.doc.translate.y};this.getScrollLeft=function(b){if(!b){if(b=h())return 16==b.length?-b[12]:-b[4];if(a.timerscroll&&a.timerscroll.bh)return a.timerscroll.bh.getNow()}return a.doc.translate.x};this.notifyScrollEvent=
21
+function(a){var g=document.createEvent("UIEvents");g.initUIEvent("scroll",!1,!0,window,1);g.niceevent=!0;a.dispatchEvent(g)};var K=this.isrtlmode?1:-1;e.hastranslate3d&&a.opt.enabletranslate3d?(this.setScrollTop=function(b,g){a.doc.translate.y=b;a.doc.translate.ty=-1*b+"px";a.doc.css(e.trstyle,"translate3d("+a.doc.translate.tx+","+a.doc.translate.ty+",0px)");g||a.notifyScrollEvent(a.win[0])},this.setScrollLeft=function(b,g){a.doc.translate.x=b;a.doc.translate.tx=b*K+"px";a.doc.css(e.trstyle,"translate3d("+
22
+a.doc.translate.tx+","+a.doc.translate.ty+",0px)");g||a.notifyScrollEvent(a.win[0])}):(this.setScrollTop=function(b,g){a.doc.translate.y=b;a.doc.translate.ty=-1*b+"px";a.doc.css(e.trstyle,"translate("+a.doc.translate.tx+","+a.doc.translate.ty+")");g||a.notifyScrollEvent(a.win[0])},this.setScrollLeft=function(b,g){a.doc.translate.x=b;a.doc.translate.tx=b*K+"px";a.doc.css(e.trstyle,"translate("+a.doc.translate.tx+","+a.doc.translate.ty+")");g||a.notifyScrollEvent(a.win[0])})}else this.getScrollTop=
23
+function(){return a.docscroll.scrollTop()},this.setScrollTop=function(b){return a.docscroll.scrollTop(b)},this.getScrollLeft=function(){return a.detected.ismozilla&&a.isrtlmode?Math.abs(a.docscroll.scrollLeft()):a.docscroll.scrollLeft()},this.setScrollLeft=function(b){return a.docscroll.scrollLeft(a.detected.ismozilla&&a.isrtlmode?-b:b)};this.getTarget=function(a){return a?a.target?a.target:a.srcElement?a.srcElement:!1:!1};this.hasParent=function(a,g){if(!a)return!1;for(var c=a.target||a.srcElement||
24
+a||!1;c&&c.id!=g;)c=c.parentNode||!1;return!1!==c};var w={thin:1,medium:3,thick:5};this.getDocumentScrollOffset=function(){return{top:window.pageYOffset||document.documentElement.scrollTop,left:window.pageXOffset||document.documentElement.scrollLeft}};this.getOffset=function(){if(a.isfixed){var b=a.win.offset(),g=a.getDocumentScrollOffset();b.top-=g.top;b.left-=g.left;return b}b=a.win.offset();if(!a.viewport)return b;g=a.viewport.offset();return{top:b.top-g.top,left:b.left-g.left}};this.updateScrollBar=
25
+function(b){if(a.ishwscroll)a.rail.css({height:a.win.innerHeight()-(a.opt.railpadding.top+a.opt.railpadding.bottom)}),a.railh&&a.railh.css({width:a.win.innerWidth()-(a.opt.railpadding.left+a.opt.railpadding.right)});else{var g=a.getOffset(),c=g.top,e=g.left-(a.opt.railpadding.left+a.opt.railpadding.right),c=c+d(a.win,"border-top-width",!0),e=e+(a.rail.align?a.win.outerWidth()-d(a.win,"border-right-width")-a.rail.width:d(a.win,"border-left-width")),f=a.opt.railoffset;f&&(f.top&&(c+=f.top),a.rail.align&&
26
+f.left&&(e+=f.left));a.railslocked||a.rail.css({top:c,left:e,height:(b?b.h:a.win.innerHeight())-(a.opt.railpadding.top+a.opt.railpadding.bottom)});a.zoom&&a.zoom.css({top:c+1,left:1==a.rail.align?e-20:e+a.rail.width+4});if(a.railh&&!a.railslocked){c=g.top;e=g.left;if(f=a.opt.railhoffset)f.top&&(c+=f.top),f.left&&(e+=f.left);b=a.railh.align?c+d(a.win,"border-top-width",!0)+a.win.innerHeight()-a.railh.height:c+d(a.win,"border-top-width",!0);e+=d(a.win,"border-left-width");a.railh.css({top:b-(a.opt.railpadding.top+
27
+a.opt.railpadding.bottom),left:e,width:a.railh.width})}}};this.doRailClick=function(b,g,c){var e;a.railslocked||(a.cancelEvent(b),g?(g=c?a.doScrollLeft:a.doScrollTop,e=c?(b.pageX-a.railh.offset().left-a.cursorwidth/2)*a.scrollratio.x:(b.pageY-a.rail.offset().top-a.cursorheight/2)*a.scrollratio.y,g(e)):(g=c?a.doScrollLeftBy:a.doScrollBy,e=c?a.scroll.x:a.scroll.y,b=c?b.pageX-a.railh.offset().left:b.pageY-a.rail.offset().top,c=c?a.view.w:a.view.h,g(e>=b?c:-c)))};a.hasanimationframe=s;a.hascancelanimationframe=
28
+t;a.hasanimationframe?a.hascancelanimationframe||(t=function(){a.cancelAnimationFrame=!0}):(s=function(a){return setTimeout(a,15-Math.floor(+new Date/1E3)%16)},t=clearInterval);this.init=function(){a.saved.css=[];if(e.isie7mobile||e.isoperamini)return!0;e.hasmstouch&&a.css(a.ispage?f("html"):a.win,{"-ms-touch-action":"none"});a.zindex="auto";a.zindex=a.ispage||"auto"!=a.opt.zindex?a.opt.zindex:m()||"auto";!a.ispage&&"auto"!=a.zindex&&a.zindex>x&&(x=a.zindex);a.isie&&0==a.zindex&&"auto"==a.opt.zindex&&
29
+(a.zindex="auto");if(!a.ispage||!e.cantouch&&!e.isieold&&!e.isie9mobile){var b=a.docscroll;a.ispage&&(b=a.haswrapper?a.win:a.doc);e.isie9mobile||a.css(b,{"overflow-y":"hidden"});a.ispage&&e.isie7&&("BODY"==a.doc[0].nodeName?a.css(f("html"),{"overflow-y":"hidden"}):"HTML"==a.doc[0].nodeName&&a.css(f("body"),{"overflow-y":"hidden"}));!e.isios||a.ispage||a.haswrapper||a.css(f("body"),{"-webkit-overflow-scrolling":"touch"});var g=f(document.createElement("div"));g.css({position:"relative",top:0,"float":"right",
30
+width:a.opt.cursorwidth,height:"0px","background-color":a.opt.cursorcolor,border:a.opt.cursorborder,"background-clip":"padding-box","-webkit-border-radius":a.opt.cursorborderradius,"-moz-border-radius":a.opt.cursorborderradius,"border-radius":a.opt.cursorborderradius});g.hborder=parseFloat(g.outerHeight()-g.innerHeight());g.addClass("nicescroll-cursors");a.cursor=g;var c=f(document.createElement("div"));c.attr("id",a.id);c.addClass("nicescroll-rails nicescroll-rails-vr");var d,h,k=["left","right",
31
+"top","bottom"],J;for(J in k)h=k[J],(d=a.opt.railpadding[h])?c.css("padding-"+h,d+"px"):a.opt.railpadding[h]=0;c.append(g);c.width=Math.max(parseFloat(a.opt.cursorwidth),g.outerWidth());c.css({width:c.width+"px",zIndex:a.zindex,background:a.opt.background,cursor:"default"});c.visibility=!0;c.scrollable=!0;c.align="left"==a.opt.railalign?0:1;a.rail=c;g=a.rail.drag=!1;!a.opt.boxzoom||a.ispage||e.isieold||(g=document.createElement("div"),a.bind(g,"click",a.doZoom),a.bind(g,"mouseenter",function(){a.zoom.css("opacity",
32
+a.opt.cursoropacitymax)}),a.bind(g,"mouseleave",function(){a.zoom.css("opacity",a.opt.cursoropacitymin)}),a.zoom=f(g),a.zoom.css({cursor:"pointer","z-index":a.zindex,backgroundImage:"url("+a.opt.scriptpath+"zoomico.png)",height:18,width:18,backgroundPosition:"0px 0px"}),a.opt.dblclickzoom&&a.bind(a.win,"dblclick",a.doZoom),e.cantouch&&a.opt.gesturezoom&&(a.ongesturezoom=function(b){1.5<b.scale&&a.doZoomIn(b);.8>b.scale&&a.doZoomOut(b);return a.cancelEvent(b)},a.bind(a.win,"gestureend",a.ongesturezoom)));
33
+a.railh=!1;var l;a.opt.horizrailenabled&&(a.css(b,{"overflow-x":"hidden"}),g=f(document.createElement("div")),g.css({position:"absolute",top:0,height:a.opt.cursorwidth,width:"0px","background-color":a.opt.cursorcolor,border:a.opt.cursorborder,"background-clip":"padding-box","-webkit-border-radius":a.opt.cursorborderradius,"-moz-border-radius":a.opt.cursorborderradius,"border-radius":a.opt.cursorborderradius}),e.isieold&&g.css({overflow:"hidden"}),g.wborder=parseFloat(g.outerWidth()-g.innerWidth()),
34
+g.addClass("nicescroll-cursors"),a.cursorh=g,l=f(document.createElement("div")),l.attr("id",a.id+"-hr"),l.addClass("nicescroll-rails nicescroll-rails-hr"),l.height=Math.max(parseFloat(a.opt.cursorwidth),g.outerHeight()),l.css({height:l.height+"px",zIndex:a.zindex,background:a.opt.background}),l.append(g),l.visibility=!0,l.scrollable=!0,l.align="top"==a.opt.railvalign?0:1,a.railh=l,a.railh.drag=!1);a.ispage?(c.css({position:"fixed",top:"0px",height:"100%"}),c.align?c.css({right:"0px"}):c.css({left:"0px"}),
35
+a.body.append(c),a.railh&&(l.css({position:"fixed",left:"0px",width:"100%"}),l.align?l.css({bottom:"0px"}):l.css({top:"0px"}),a.body.append(l))):(a.ishwscroll?("static"==a.win.css("position")&&a.css(a.win,{position:"relative"}),b="HTML"==a.win[0].nodeName?a.body:a.win,f(b).scrollTop(0).scrollLeft(0),a.zoom&&(a.zoom.css({position:"absolute",top:1,right:0,"margin-right":c.width+4}),b.append(a.zoom)),c.css({position:"absolute",top:0}),c.align?c.css({right:0}):c.css({left:0}),b.append(c),l&&(l.css({position:"absolute",
36
+left:0,bottom:0}),l.align?l.css({bottom:0}):l.css({top:0}),b.append(l))):(a.isfixed="fixed"==a.win.css("position"),b=a.isfixed?"fixed":"absolute",a.isfixed||(a.viewport=a.getViewport(a.win[0])),a.viewport&&(a.body=a.viewport,0==/fixed|absolute/.test(a.viewport.css("position"))&&a.css(a.viewport,{position:"relative"})),c.css({position:b}),a.zoom&&a.zoom.css({position:b}),a.updateScrollBar(),a.body.append(c),a.zoom&&a.body.append(a.zoom),a.railh&&(l.css({position:b}),a.body.append(l))),e.isios&&a.css(a.win,
37
+{"-webkit-tap-highlight-color":"rgba(0,0,0,0)","-webkit-touch-callout":"none"}),e.isie&&a.opt.disableoutline&&a.win.attr("hideFocus","true"),e.iswebkit&&a.opt.disableoutline&&a.win.css({outline:"none"}));!1===a.opt.autohidemode?(a.autohidedom=!1,a.rail.css({opacity:a.opt.cursoropacitymax}),a.railh&&a.railh.css({opacity:a.opt.cursoropacitymax})):!0===a.opt.autohidemode||"leave"===a.opt.autohidemode?(a.autohidedom=f().add(a.rail),e.isie8&&(a.autohidedom=a.autohidedom.add(a.cursor)),a.railh&&(a.autohidedom=
38
+a.autohidedom.add(a.railh)),a.railh&&e.isie8&&(a.autohidedom=a.autohidedom.add(a.cursorh))):"scroll"==a.opt.autohidemode?(a.autohidedom=f().add(a.rail),a.railh&&(a.autohidedom=a.autohidedom.add(a.railh))):"cursor"==a.opt.autohidemode?(a.autohidedom=f().add(a.cursor),a.railh&&(a.autohidedom=a.autohidedom.add(a.cursorh))):"hidden"==a.opt.autohidemode&&(a.autohidedom=!1,a.hide(),a.railslocked=!1);if(e.isie9mobile)a.scrollmom=new L(a),a.onmangotouch=function(){var b=a.getScrollTop(),c=a.getScrollLeft();
39
+if(b==a.scrollmom.lastscrolly&&c==a.scrollmom.lastscrollx)return!0;var g=b-a.mangotouch.sy,e=c-a.mangotouch.sx;if(0!=Math.round(Math.sqrt(Math.pow(e,2)+Math.pow(g,2)))){var d=0>g?-1:1,f=0>e?-1:1,q=+new Date;a.mangotouch.lazy&&clearTimeout(a.mangotouch.lazy);80<q-a.mangotouch.tm||a.mangotouch.dry!=d||a.mangotouch.drx!=f?(a.scrollmom.stop(),a.scrollmom.reset(c,b),a.mangotouch.sy=b,a.mangotouch.ly=b,a.mangotouch.sx=c,a.mangotouch.lx=c,a.mangotouch.dry=d,a.mangotouch.drx=f,a.mangotouch.tm=q):(a.scrollmom.stop(),
40
+a.scrollmom.update(a.mangotouch.sx-e,a.mangotouch.sy-g),a.mangotouch.tm=q,g=Math.max(Math.abs(a.mangotouch.ly-b),Math.abs(a.mangotouch.lx-c)),a.mangotouch.ly=b,a.mangotouch.lx=c,2<g&&(a.mangotouch.lazy=setTimeout(function(){a.mangotouch.lazy=!1;a.mangotouch.dry=0;a.mangotouch.drx=0;a.mangotouch.tm=0;a.scrollmom.doMomentum(30)},100)))}},c=a.getScrollTop(),l=a.getScrollLeft(),a.mangotouch={sy:c,ly:c,dry:0,sx:l,lx:l,drx:0,lazy:!1,tm:0},a.bind(a.docscroll,"scroll",a.onmangotouch);else{if(e.cantouch||
41
+a.istouchcapable||a.opt.touchbehavior||e.hasmstouch){a.scrollmom=new L(a);a.ontouchstart=function(b){if(b.pointerType&&2!=b.pointerType&&"touch"!=b.pointerType)return!1;a.hasmoving=!1;if(!a.railslocked){var c;if(e.hasmstouch)for(c=b.target?b.target:!1;c;){var g=f(c).getNiceScroll();if(0<g.length&&g[0].me==a.me)break;if(0<g.length)return!1;if("DIV"==c.nodeName&&c.id==a.id)break;c=c.parentNode?c.parentNode:!1}a.cancelScroll();if((c=a.getTarget(b))&&/INPUT/i.test(c.nodeName)&&/range/i.test(c.type))return a.stopPropagation(b);
42
+!("clientX"in b)&&"changedTouches"in b&&(b.clientX=b.changedTouches[0].clientX,b.clientY=b.changedTouches[0].clientY);a.forcescreen&&(g=b,b={original:b.original?b.original:b},b.clientX=g.screenX,b.clientY=g.screenY);a.rail.drag={x:b.clientX,y:b.clientY,sx:a.scroll.x,sy:a.scroll.y,st:a.getScrollTop(),sl:a.getScrollLeft(),pt:2,dl:!1};if(a.ispage||!a.opt.directionlockdeadzone)a.rail.drag.dl="f";else{var g=f(window).width(),d=f(window).height(),q=Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),
43
+h=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight),d=Math.max(0,h-d),g=Math.max(0,q-g);a.rail.drag.ck=!a.rail.scrollable&&a.railh.scrollable?0<d?"v":!1:a.rail.scrollable&&!a.railh.scrollable?0<g?"h":!1:!1;a.rail.drag.ck||(a.rail.drag.dl="f")}a.opt.touchbehavior&&a.isiframe&&e.isie&&(g=a.win.position(),a.rail.drag.x+=g.left,a.rail.drag.y+=g.top);a.hasmoving=!1;a.lastmouseup=!1;a.scrollmom.reset(b.clientX,b.clientY);if(!e.cantouch&&!this.istouchcapable&&!b.pointerType){if(!c||
44
+!/INPUT|SELECT|TEXTAREA/i.test(c.nodeName))return!a.ispage&&e.hasmousecapture&&c.setCapture(),a.opt.touchbehavior?(c.onclick&&!c._onclick&&(c._onclick=c.onclick,c.onclick=function(b){if(a.hasmoving)return!1;c._onclick.call(this,b)}),a.cancelEvent(b)):a.stopPropagation(b);/SUBMIT|CANCEL|BUTTON/i.test(f(c).attr("type"))&&(pc={tg:c,click:!1},a.preventclick=pc)}}};a.ontouchend=function(b){if(!a.rail.drag)return!0;if(2==a.rail.drag.pt){if(b.pointerType&&2!=b.pointerType&&"touch"!=b.pointerType)return!1;
45
+a.scrollmom.doMomentum();a.rail.drag=!1;if(a.hasmoving&&(a.lastmouseup=!0,a.hideCursor(),e.hasmousecapture&&document.releaseCapture(),!e.cantouch))return a.cancelEvent(b)}else if(1==a.rail.drag.pt)return a.onmouseup(b)};var n=a.opt.touchbehavior&&a.isiframe&&!e.hasmousecapture;a.ontouchmove=function(b,c){if(!a.rail.drag||b.targetTouches&&a.opt.preventmultitouchscrolling&&1<b.targetTouches.length||b.pointerType&&2!=b.pointerType&&"touch"!=b.pointerType)return!1;if(2==a.rail.drag.pt){if(e.cantouch&&
46
+e.isios&&"undefined"==typeof b.original)return!0;a.hasmoving=!0;a.preventclick&&!a.preventclick.click&&(a.preventclick.click=a.preventclick.tg.onclick||!1,a.preventclick.tg.onclick=a.onpreventclick);b=f.extend({original:b},b);"changedTouches"in b&&(b.clientX=b.changedTouches[0].clientX,b.clientY=b.changedTouches[0].clientY);if(a.forcescreen){var g=b;b={original:b.original?b.original:b};b.clientX=g.screenX;b.clientY=g.screenY}var d,g=d=0;n&&!c&&(d=a.win.position(),g=-d.left,d=-d.top);var q=b.clientY+
47
+d;d=q-a.rail.drag.y;var h=b.clientX+g,u=h-a.rail.drag.x,k=a.rail.drag.st-d;a.ishwscroll&&a.opt.bouncescroll?0>k?k=Math.round(k/2):k>a.page.maxh&&(k=a.page.maxh+Math.round((k-a.page.maxh)/2)):(0>k&&(q=k=0),k>a.page.maxh&&(k=a.page.maxh,q=0));var l;a.railh&&a.railh.scrollable&&(l=a.isrtlmode?u-a.rail.drag.sl:a.rail.drag.sl-u,a.ishwscroll&&a.opt.bouncescroll?0>l?l=Math.round(l/2):l>a.page.maxw&&(l=a.page.maxw+Math.round((l-a.page.maxw)/2)):(0>l&&(h=l=0),l>a.page.maxw&&(l=a.page.maxw,h=0)));g=!1;if(a.rail.drag.dl)g=
48
+!0,"v"==a.rail.drag.dl?l=a.rail.drag.sl:"h"==a.rail.drag.dl&&(k=a.rail.drag.st);else{d=Math.abs(d);var u=Math.abs(u),z=a.opt.directionlockdeadzone;if("v"==a.rail.drag.ck){if(d>z&&u<=.3*d)return a.rail.drag=!1,!0;u>z&&(a.rail.drag.dl="f",f("body").scrollTop(f("body").scrollTop()))}else if("h"==a.rail.drag.ck){if(u>z&&d<=.3*u)return a.rail.drag=!1,!0;d>z&&(a.rail.drag.dl="f",f("body").scrollLeft(f("body").scrollLeft()))}}a.synched("touchmove",function(){a.rail.drag&&2==a.rail.drag.pt&&(a.prepareTransition&&
49
+a.prepareTransition(0),a.rail.scrollable&&a.setScrollTop(k),a.scrollmom.update(h,q),a.railh&&a.railh.scrollable?(a.setScrollLeft(l),a.showCursor(k,l)):a.showCursor(k),e.isie10&&document.selection.clear())});e.ischrome&&a.istouchcapable&&(g=!1);if(g)return a.cancelEvent(b)}else if(1==a.rail.drag.pt)return a.onmousemove(b)}}a.onmousedown=function(b,c){if(!a.rail.drag||1==a.rail.drag.pt){if(a.railslocked)return a.cancelEvent(b);a.cancelScroll();a.rail.drag={x:b.clientX,y:b.clientY,sx:a.scroll.x,sy:a.scroll.y,
50
+pt:1,hr:!!c};var g=a.getTarget(b);!a.ispage&&e.hasmousecapture&&g.setCapture();a.isiframe&&!e.hasmousecapture&&(a.saved.csspointerevents=a.doc.css("pointer-events"),a.css(a.doc,{"pointer-events":"none"}));a.hasmoving=!1;return a.cancelEvent(b)}};a.onmouseup=function(b){if(a.rail.drag){if(1!=a.rail.drag.pt)return!0;e.hasmousecapture&&document.releaseCapture();a.isiframe&&!e.hasmousecapture&&a.doc.css("pointer-events",a.saved.csspointerevents);a.rail.drag=!1;a.hasmoving&&a.triggerScrollEnd();return a.cancelEvent(b)}};
51
+a.onmousemove=function(b){if(a.rail.drag&&1==a.rail.drag.pt){if(e.ischrome&&0==b.which)return a.onmouseup(b);a.cursorfreezed=!0;a.hasmoving=!0;if(a.rail.drag.hr){a.scroll.x=a.rail.drag.sx+(b.clientX-a.rail.drag.x);0>a.scroll.x&&(a.scroll.x=0);var c=a.scrollvaluemaxw;a.scroll.x>c&&(a.scroll.x=c)}else a.scroll.y=a.rail.drag.sy+(b.clientY-a.rail.drag.y),0>a.scroll.y&&(a.scroll.y=0),c=a.scrollvaluemax,a.scroll.y>c&&(a.scroll.y=c);a.synched("mousemove",function(){a.rail.drag&&1==a.rail.drag.pt&&(a.showCursor(),
52
+a.rail.drag.hr?a.hasreversehr?a.doScrollLeft(a.scrollvaluemaxw-Math.round(a.scroll.x*a.scrollratio.x),a.opt.cursordragspeed):a.doScrollLeft(Math.round(a.scroll.x*a.scrollratio.x),a.opt.cursordragspeed):a.doScrollTop(Math.round(a.scroll.y*a.scrollratio.y),a.opt.cursordragspeed))});return a.cancelEvent(b)}};if(e.cantouch||a.opt.touchbehavior)a.onpreventclick=function(b){if(a.preventclick)return a.preventclick.tg.onclick=a.preventclick.click,a.preventclick=!1,a.cancelEvent(b)},a.bind(a.win,"mousedown",
53
+a.ontouchstart),a.onclick=e.isios?!1:function(b){return a.lastmouseup?(a.lastmouseup=!1,a.cancelEvent(b)):!0},a.opt.grabcursorenabled&&e.cursorgrabvalue&&(a.css(a.ispage?a.doc:a.win,{cursor:e.cursorgrabvalue}),a.css(a.rail,{cursor:e.cursorgrabvalue}));else{var p=function(b){if(a.selectiondrag){if(b){var c=a.win.outerHeight();b=b.pageY-a.selectiondrag.top;0<b&&b<c&&(b=0);b>=c&&(b-=c);a.selectiondrag.df=b}0!=a.selectiondrag.df&&(a.doScrollBy(2*-Math.floor(a.selectiondrag.df/6)),a.debounced("doselectionscroll",
54
+function(){p()},50))}};a.hasTextSelected="getSelection"in document?function(){return 0<document.getSelection().rangeCount}:"selection"in document?function(){return"None"!=document.selection.type}:function(){return!1};a.onselectionstart=function(b){a.ispage||(a.selectiondrag=a.win.offset())};a.onselectionend=function(b){a.selectiondrag=!1};a.onselectiondrag=function(b){a.selectiondrag&&a.hasTextSelected()&&a.debounced("selectionscroll",function(){p(b)},250)}}e.hasw3ctouch?(a.css(a.rail,{"touch-action":"none"}),
55
+a.css(a.cursor,{"touch-action":"none"}),a.bind(a.win,"pointerdown",a.ontouchstart),a.bind(document,"pointerup",a.ontouchend),a.bind(document,"pointermove",a.ontouchmove)):e.hasmstouch?(a.css(a.rail,{"-ms-touch-action":"none"}),a.css(a.cursor,{"-ms-touch-action":"none"}),a.bind(a.win,"MSPointerDown",a.ontouchstart),a.bind(document,"MSPointerUp",a.ontouchend),a.bind(document,"MSPointerMove",a.ontouchmove),a.bind(a.cursor,"MSGestureHold",function(a){a.preventDefault()}),a.bind(a.cursor,"contextmenu",
56
+function(a){a.preventDefault()})):this.istouchcapable&&(a.bind(a.win,"touchstart",a.ontouchstart),a.bind(document,"touchend",a.ontouchend),a.bind(document,"touchcancel",a.ontouchend),a.bind(document,"touchmove",a.ontouchmove));if(a.opt.cursordragontouch||!e.cantouch&&!a.opt.touchbehavior)a.rail.css({cursor:"default"}),a.railh&&a.railh.css({cursor:"default"}),a.jqbind(a.rail,"mouseenter",function(){if(!a.ispage&&!a.win.is(":visible"))return!1;a.canshowonmouseevent&&a.showCursor();a.rail.active=!0}),
57
+a.jqbind(a.rail,"mouseleave",function(){a.rail.active=!1;a.rail.drag||a.hideCursor()}),a.opt.sensitiverail&&(a.bind(a.rail,"click",function(b){a.doRailClick(b,!1,!1)}),a.bind(a.rail,"dblclick",function(b){a.doRailClick(b,!0,!1)}),a.bind(a.cursor,"click",function(b){a.cancelEvent(b)}),a.bind(a.cursor,"dblclick",function(b){a.cancelEvent(b)})),a.railh&&(a.jqbind(a.railh,"mouseenter",function(){if(!a.ispage&&!a.win.is(":visible"))return!1;a.canshowonmouseevent&&a.showCursor();a.rail.active=!0}),a.jqbind(a.railh,
58
+"mouseleave",function(){a.rail.active=!1;a.rail.drag||a.hideCursor()}),a.opt.sensitiverail&&(a.bind(a.railh,"click",function(b){a.doRailClick(b,!1,!0)}),a.bind(a.railh,"dblclick",function(b){a.doRailClick(b,!0,!0)}),a.bind(a.cursorh,"click",function(b){a.cancelEvent(b)}),a.bind(a.cursorh,"dblclick",function(b){a.cancelEvent(b)})));e.cantouch||a.opt.touchbehavior?(a.bind(e.hasmousecapture?a.win:document,"mouseup",a.ontouchend),a.bind(document,"mousemove",a.ontouchmove),a.onclick&&a.bind(document,"click",
59
+a.onclick),a.opt.cursordragontouch&&(a.bind(a.cursor,"mousedown",a.onmousedown),a.bind(a.cursor,"mouseup",a.onmouseup),a.cursorh&&a.bind(a.cursorh,"mousedown",function(b){a.onmousedown(b,!0)}),a.cursorh&&a.bind(a.cursorh,"mouseup",a.onmouseup))):(a.bind(e.hasmousecapture?a.win:document,"mouseup",a.onmouseup),a.bind(document,"mousemove",a.onmousemove),a.onclick&&a.bind(document,"click",a.onclick),a.bind(a.cursor,"mousedown",a.onmousedown),a.bind(a.cursor,"mouseup",a.onmouseup),a.railh&&(a.bind(a.cursorh,
60
+"mousedown",function(b){a.onmousedown(b,!0)}),a.bind(a.cursorh,"mouseup",a.onmouseup)),!a.ispage&&a.opt.enablescrollonselection&&(a.bind(a.win[0],"mousedown",a.onselectionstart),a.bind(document,"mouseup",a.onselectionend),a.bind(a.cursor,"mouseup",a.onselectionend),a.cursorh&&a.bind(a.cursorh,"mouseup",a.onselectionend),a.bind(document,"mousemove",a.onselectiondrag)),a.zoom&&(a.jqbind(a.zoom,"mouseenter",function(){a.canshowonmouseevent&&a.showCursor();a.rail.active=!0}),a.jqbind(a.zoom,"mouseleave",
61
+function(){a.rail.active=!1;a.rail.drag||a.hideCursor()})));a.opt.enablemousewheel&&(a.isiframe||a.bind(e.isie&&a.ispage?document:a.win,"mousewheel",a.onmousewheel),a.bind(a.rail,"mousewheel",a.onmousewheel),a.railh&&a.bind(a.railh,"mousewheel",a.onmousewheelhr));a.ispage||e.cantouch||/HTML|^BODY/.test(a.win[0].nodeName)||(a.win.attr("tabindex")||a.win.attr({tabindex:N++}),a.jqbind(a.win,"focus",function(b){y=a.getTarget(b).id||!0;a.hasfocus=!0;a.canshowonmouseevent&&a.noticeCursor()}),a.jqbind(a.win,
62
+"blur",function(b){y=!1;a.hasfocus=!1}),a.jqbind(a.win,"mouseenter",function(b){D=a.getTarget(b).id||!0;a.hasmousefocus=!0;a.canshowonmouseevent&&a.noticeCursor()}),a.jqbind(a.win,"mouseleave",function(){D=!1;a.hasmousefocus=!1;a.rail.drag||a.hideCursor()}))}a.onkeypress=function(b){if(a.railslocked&&0==a.page.maxh)return!0;b=b?b:window.e;var c=a.getTarget(b);if(c&&/INPUT|TEXTAREA|SELECT|OPTION/.test(c.nodeName)&&(!c.getAttribute("type")&&!c.type||!/submit|button|cancel/i.tp)||f(c).attr("contenteditable"))return!0;
63
+if(a.hasfocus||a.hasmousefocus&&!y||a.ispage&&!y&&!D){c=b.keyCode;if(a.railslocked&&27!=c)return a.cancelEvent(b);var g=b.ctrlKey||!1,d=b.shiftKey||!1,e=!1;switch(c){case 38:case 63233:a.doScrollBy(72);e=!0;break;case 40:case 63235:a.doScrollBy(-72);e=!0;break;case 37:case 63232:a.railh&&(g?a.doScrollLeft(0):a.doScrollLeftBy(72),e=!0);break;case 39:case 63234:a.railh&&(g?a.doScrollLeft(a.page.maxw):a.doScrollLeftBy(-72),e=!0);break;case 33:case 63276:a.doScrollBy(a.view.h);e=!0;break;case 34:case 63277:a.doScrollBy(-a.view.h);
64
+e=!0;break;case 36:case 63273:a.railh&&g?a.doScrollPos(0,0):a.doScrollTo(0);e=!0;break;case 35:case 63275:a.railh&&g?a.doScrollPos(a.page.maxw,a.page.maxh):a.doScrollTo(a.page.maxh);e=!0;break;case 32:a.opt.spacebarenabled&&(d?a.doScrollBy(a.view.h):a.doScrollBy(-a.view.h),e=!0);break;case 27:a.zoomactive&&(a.doZoom(),e=!0)}if(e)return a.cancelEvent(b)}};a.opt.enablekeyboard&&a.bind(document,e.isopera&&!e.isopera12?"keypress":"keydown",a.onkeypress);a.bind(document,"keydown",function(b){b.ctrlKey&&
65
+(a.wheelprevented=!0)});a.bind(document,"keyup",function(b){b.ctrlKey||(a.wheelprevented=!1)});a.bind(window,"blur",function(b){a.wheelprevented=!1});a.bind(window,"resize",a.lazyResize);a.bind(window,"orientationchange",a.lazyResize);a.bind(window,"load",a.lazyResize);if(e.ischrome&&!a.ispage&&!a.haswrapper){var r=a.win.attr("style"),c=parseFloat(a.win.css("width"))+1;a.win.css("width",c);a.synched("chromefix",function(){a.win.attr("style",r)})}a.onAttributeChange=function(b){a.lazyResize(a.isieold?
66
+250:30)};!1!==v&&(a.observerbody=new v(function(b){b.forEach(function(b){if("attributes"==b.type)return f("body").hasClass("modal-open")?a.hide():a.show()});if(document.body.scrollHeight!=a.page.maxh)return a.lazyResize(30)}),a.observerbody.observe(document.body,{childList:!0,subtree:!0,characterData:!1,attributes:!0,attributeFilter:["class"]}));a.ispage||a.haswrapper||(!1!==v?(a.observer=new v(function(b){b.forEach(a.onAttributeChange)}),a.observer.observe(a.win[0],{childList:!0,characterData:!1,
67
+attributes:!0,subtree:!1}),a.observerremover=new v(function(b){b.forEach(function(b){if(0<b.removedNodes.length)for(var c in b.removedNodes)if(a&&b.removedNodes[c]==a.win[0])return a.remove()})}),a.observerremover.observe(a.win[0].parentNode,{childList:!0,characterData:!1,attributes:!1,subtree:!1})):(a.bind(a.win,e.isie&&!e.isie9?"propertychange":"DOMAttrModified",a.onAttributeChange),e.isie9&&a.win[0].attachEvent("onpropertychange",a.onAttributeChange),a.bind(a.win,"DOMNodeRemoved",function(b){b.target==
68
+a.win[0]&&a.remove()})));!a.ispage&&a.opt.boxzoom&&a.bind(window,"resize",a.resizeZoom);a.istextarea&&a.bind(a.win,"mouseup",a.lazyResize);a.lazyResize(30)}if("IFRAME"==this.doc[0].nodeName){var M=function(){a.iframexd=!1;var b;try{b="contentDocument"in this?this.contentDocument:this.contentWindow.document}catch(c){a.iframexd=!0,b=!1}if(a.iframexd)return"console"in window&&console.log("NiceScroll error: policy restriced iframe"),!0;a.forcescreen=!0;a.isiframe&&(a.iframe={doc:f(b),html:a.doc.contents().find("html")[0],
69
+body:a.doc.contents().find("body")[0]},a.getContentSize=function(){return{w:Math.max(a.iframe.html.scrollWidth,a.iframe.body.scrollWidth),h:Math.max(a.iframe.html.scrollHeight,a.iframe.body.scrollHeight)}},a.docscroll=f(a.iframe.body));if(!e.isios&&a.opt.iframeautoresize&&!a.isiframe){a.win.scrollTop(0);a.doc.height("");var g=Math.max(b.getElementsByTagName("html")[0].scrollHeight,b.body.scrollHeight);a.doc.height(g)}a.lazyResize(30);e.isie7&&a.css(f(a.iframe.html),{"overflow-y":"hidden"});a.css(f(a.iframe.body),
70
+{"overflow-y":"hidden"});e.isios&&a.haswrapper&&a.css(f(b.body),{"-webkit-transform":"translate3d(0,0,0)"});"contentWindow"in this?a.bind(this.contentWindow,"scroll",a.onscroll):a.bind(b,"scroll",a.onscroll);a.opt.enablemousewheel&&a.bind(b,"mousewheel",a.onmousewheel);a.opt.enablekeyboard&&a.bind(b,e.isopera?"keypress":"keydown",a.onkeypress);if(e.cantouch||a.opt.touchbehavior)a.bind(b,"mousedown",a.ontouchstart),a.bind(b,"mousemove",function(b){return a.ontouchmove(b,!0)}),a.opt.grabcursorenabled&&
71
+e.cursorgrabvalue&&a.css(f(b.body),{cursor:e.cursorgrabvalue});a.bind(b,"mouseup",a.ontouchend);a.zoom&&(a.opt.dblclickzoom&&a.bind(b,"dblclick",a.doZoom),a.ongesturezoom&&a.bind(b,"gestureend",a.ongesturezoom))};this.doc[0].readyState&&"complete"==this.doc[0].readyState&&setTimeout(function(){M.call(a.doc[0],!1)},500);a.bind(this.doc,"load",M)}};this.showCursor=function(b,c){a.cursortimeout&&(clearTimeout(a.cursortimeout),a.cursortimeout=0);if(a.rail){a.autohidedom&&(a.autohidedom.stop().css({opacity:a.opt.cursoropacitymax}),
72
+a.cursoractive=!0);a.rail.drag&&1==a.rail.drag.pt||("undefined"!=typeof b&&!1!==b&&(a.scroll.y=Math.round(1*b/a.scrollratio.y)),"undefined"!=typeof c&&(a.scroll.x=Math.round(1*c/a.scrollratio.x)));a.cursor.css({height:a.cursorheight,top:a.scroll.y});if(a.cursorh){var d=a.hasreversehr?a.scrollvaluemaxw-a.scroll.x:a.scroll.x;!a.rail.align&&a.rail.visibility?a.cursorh.css({width:a.cursorwidth,left:d+a.rail.width}):a.cursorh.css({width:a.cursorwidth,left:d});a.cursoractive=!0}a.zoom&&a.zoom.stop().css({opacity:a.opt.cursoropacitymax})}};
73
+this.hideCursor=function(b){a.cursortimeout||!a.rail||!a.autohidedom||a.hasmousefocus&&"leave"==a.opt.autohidemode||(a.cursortimeout=setTimeout(function(){a.rail.active&&a.showonmouseevent||(a.autohidedom.stop().animate({opacity:a.opt.cursoropacitymin}),a.zoom&&a.zoom.stop().animate({opacity:a.opt.cursoropacitymin}),a.cursoractive=!1);a.cursortimeout=0},b||a.opt.hidecursordelay))};this.noticeCursor=function(b,c,d){a.showCursor(c,d);a.rail.active||a.hideCursor(b)};this.getContentSize=a.ispage?function(){return{w:Math.max(document.body.scrollWidth,
74
+document.documentElement.scrollWidth),h:Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}}:a.haswrapper?function(){return{w:a.doc.outerWidth()+parseInt(a.win.css("paddingLeft"))+parseInt(a.win.css("paddingRight")),h:a.doc.outerHeight()+parseInt(a.win.css("paddingTop"))+parseInt(a.win.css("paddingBottom"))}}:function(){return{w:a.docscroll[0].scrollWidth,h:a.docscroll[0].scrollHeight}};this.onResize=function(b,c){if(!a||!a.win)return!1;if(!a.haswrapper&&!a.ispage){if("none"==
75
+a.win.css("display"))return a.visibility&&a.hideRail().hideRailHr(),!1;a.hidden||a.visibility||a.showRail().showRailHr()}var d=a.page.maxh,e=a.page.maxw,f=a.view.h,h=a.view.w;a.view={w:a.ispage?a.win.width():parseInt(a.win[0].clientWidth),h:a.ispage?a.win.height():parseInt(a.win[0].clientHeight)};a.page=c?c:a.getContentSize();a.page.maxh=Math.max(0,a.page.h-a.view.h);a.page.maxw=Math.max(0,a.page.w-a.view.w);if(a.page.maxh==d&&a.page.maxw==e&&a.view.w==h&&a.view.h==f){if(a.ispage)return a;d=a.win.offset();
76
+if(a.lastposition&&(e=a.lastposition,e.top==d.top&&e.left==d.left))return a;a.lastposition=d}0==a.page.maxh?(a.hideRail(),a.scrollvaluemax=0,a.scroll.y=0,a.scrollratio.y=0,a.cursorheight=0,a.setScrollTop(0),a.rail.scrollable=!1):(a.page.maxh-=a.opt.railpadding.top+a.opt.railpadding.bottom,a.rail.scrollable=!0);0==a.page.maxw?(a.hideRailHr(),a.scrollvaluemaxw=0,a.scroll.x=0,a.scrollratio.x=0,a.cursorwidth=0,a.setScrollLeft(0),a.railh.scrollable=!1):(a.page.maxw-=a.opt.railpadding.left+a.opt.railpadding.right,
77
+a.railh.scrollable=!0);a.railslocked=a.locked||0==a.page.maxh&&0==a.page.maxw;if(a.railslocked)return a.ispage||a.updateScrollBar(a.view),!1;a.hidden||a.visibility?a.hidden||a.railh.visibility||a.showRailHr():a.showRail().showRailHr();a.istextarea&&a.win.css("resize")&&"none"!=a.win.css("resize")&&(a.view.h-=20);a.cursorheight=Math.min(a.view.h,Math.round(a.view.h/a.page.h*a.view.h));a.cursorheight=a.opt.cursorfixedheight?a.opt.cursorfixedheight:Math.max(a.opt.cursorminheight,a.cursorheight);a.cursorwidth=
78
+Math.min(a.view.w,Math.round(a.view.w/a.page.w*a.view.w));a.cursorwidth=a.opt.cursorfixedheight?a.opt.cursorfixedheight:Math.max(a.opt.cursorminheight,a.cursorwidth);a.scrollvaluemax=a.view.h-a.cursorheight-a.cursor.hborder-(a.opt.railpadding.top+a.opt.railpadding.bottom);a.railh&&(a.railh.width=0<a.page.maxh?a.view.w-a.rail.width:a.view.w,a.scrollvaluemaxw=a.railh.width-a.cursorwidth-a.cursorh.wborder-(a.opt.railpadding.left+a.opt.railpadding.right));a.ispage||a.updateScrollBar(a.view);a.scrollratio=
79
+{x:a.page.maxw/a.scrollvaluemaxw,y:a.page.maxh/a.scrollvaluemax};a.getScrollTop()>a.page.maxh?a.doScrollTop(a.page.maxh):(a.scroll.y=Math.round(a.getScrollTop()*(1/a.scrollratio.y)),a.scroll.x=Math.round(a.getScrollLeft()*(1/a.scrollratio.x)),a.cursoractive&&a.noticeCursor());a.scroll.y&&0==a.getScrollTop()&&a.doScrollTo(Math.floor(a.scroll.y*a.scrollratio.y));return a};this.resize=a.onResize;this.lazyResize=function(b){b=isNaN(b)?30:b;a.debounced("resize",a.resize,b);return a};this.jqbind=function(b,
80
+c,d){a.events.push({e:b,n:c,f:d,q:!0});f(b).bind(c,d)};this.bind=function(b,c,d,f){var h="jquery"in b?b[0]:b;"mousewheel"==c?window.addEventListener||"onwheel"in document?a._bind(h,"wheel",d,f||!1):(b="undefined"!=typeof document.onmousewheel?"mousewheel":"DOMMouseScroll",n(h,b,d,f||!1),"DOMMouseScroll"==b&&n(h,"MozMousePixelScroll",d,f||!1)):h.addEventListener?(e.cantouch&&/mouseup|mousedown|mousemove/.test(c)&&a._bind(h,"mousedown"==c?"touchstart":"mouseup"==c?"touchend":"touchmove",function(a){if(a.touches){if(2>
81
+a.touches.length){var b=a.touches.length?a.touches[0]:a;b.original=a;d.call(this,b)}}else a.changedTouches&&(b=a.changedTouches[0],b.original=a,d.call(this,b))},f||!1),a._bind(h,c,d,f||!1),e.cantouch&&"mouseup"==c&&a._bind(h,"touchcancel",d,f||!1)):a._bind(h,c,function(b){(b=b||window.event||!1)&&b.srcElement&&(b.target=b.srcElement);"pageY"in b||(b.pageX=b.clientX+document.documentElement.scrollLeft,b.pageY=b.clientY+document.documentElement.scrollTop);return!1===d.call(h,b)||!1===f?a.cancelEvent(b):
82
+!0})};e.haseventlistener?(this._bind=function(b,c,d,e){a.events.push({e:b,n:c,f:d,b:e,q:!1});b.addEventListener(c,d,e||!1)},this.cancelEvent=function(a){if(!a)return!1;a=a.original?a.original:a;a.preventDefault();a.stopPropagation();a.preventManipulation&&a.preventManipulation();return!1},this.stopPropagation=function(a){if(!a)return!1;a=a.original?a.original:a;a.stopPropagation();return!1},this._unbind=function(a,c,d,e){a.removeEventListener(c,d,e)}):(this._bind=function(b,c,d,e){a.events.push({e:b,
83
+n:c,f:d,b:e,q:!1});b.attachEvent?b.attachEvent("on"+c,d):b["on"+c]=d},this.cancelEvent=function(a){a=window.event||!1;if(!a)return!1;a.cancelBubble=!0;a.cancel=!0;return a.returnValue=!1},this.stopPropagation=function(a){a=window.event||!1;if(!a)return!1;a.cancelBubble=!0;return!1},this._unbind=function(a,c,d,e){a.detachEvent?a.detachEvent("on"+c,d):a["on"+c]=!1});this.unbindAll=function(){for(var b=0;b<a.events.length;b++){var c=a.events[b];c.q?c.e.unbind(c.n,c.f):a._unbind(c.e,c.n,c.f,c.b)}};this.showRail=
84
+function(){0==a.page.maxh||!a.ispage&&"none"==a.win.css("display")||(a.visibility=!0,a.rail.visibility=!0,a.rail.css("display","block"));return a};this.showRailHr=function(){if(!a.railh)return a;0==a.page.maxw||!a.ispage&&"none"==a.win.css("display")||(a.railh.visibility=!0,a.railh.css("display","block"));return a};this.hideRail=function(){a.visibility=!1;a.rail.visibility=!1;a.rail.css("display","none");return a};this.hideRailHr=function(){if(!a.railh)return a;a.railh.visibility=!1;a.railh.css("display",
85
+"none");return a};this.show=function(){a.hidden=!1;a.railslocked=!1;return a.showRail().showRailHr()};this.hide=function(){a.hidden=!0;a.railslocked=!0;return a.hideRail().hideRailHr()};this.toggle=function(){return a.hidden?a.show():a.hide()};this.remove=function(){a.stop();a.cursortimeout&&clearTimeout(a.cursortimeout);a.doZoomOut();a.unbindAll();e.isie9&&a.win[0].detachEvent("onpropertychange",a.onAttributeChange);!1!==a.observer&&a.observer.disconnect();!1!==a.observerremover&&a.observerremover.disconnect();
86
+!1!==a.observerbody&&a.observerbody.disconnect();a.events=null;a.cursor&&a.cursor.remove();a.cursorh&&a.cursorh.remove();a.rail&&a.rail.remove();a.railh&&a.railh.remove();a.zoom&&a.zoom.remove();for(var b=0;b<a.saved.css.length;b++){var c=a.saved.css[b];c[0].css(c[1],"undefined"==typeof c[2]?"":c[2])}a.saved=!1;a.me.data("__nicescroll","");var d=f.nicescroll;d.each(function(b){if(this&&this.id===a.id){delete d[b];for(var c=++b;c<d.length;c++,b++)d[b]=d[c];d.length--;d.length&&delete d[d.length]}});
87
+for(var h in a)a[h]=null,delete a[h];a=null};this.scrollstart=function(b){this.onscrollstart=b;return a};this.scrollend=function(b){this.onscrollend=b;return a};this.scrollcancel=function(b){this.onscrollcancel=b;return a};this.zoomin=function(b){this.onzoomin=b;return a};this.zoomout=function(b){this.onzoomout=b;return a};this.isScrollable=function(a){a=a.target?a.target:a;if("OPTION"==a.nodeName)return!0;for(;a&&1==a.nodeType&&!/^BODY|HTML/.test(a.nodeName);){var c=f(a),c=c.css("overflowY")||c.css("overflowX")||
88
+c.css("overflow")||"";if(/scroll|auto/.test(c))return a.clientHeight!=a.scrollHeight;a=a.parentNode?a.parentNode:!1}return!1};this.getViewport=function(a){for(a=a&&a.parentNode?a.parentNode:!1;a&&1==a.nodeType&&!/^BODY|HTML/.test(a.nodeName);){var c=f(a);if(/fixed|absolute/.test(c.css("position")))return c;var d=c.css("overflowY")||c.css("overflowX")||c.css("overflow")||"";if(/scroll|auto/.test(d)&&a.clientHeight!=a.scrollHeight||0<c.getNiceScroll().length)return c;a=a.parentNode?a.parentNode:!1}return!1};
89
+this.triggerScrollEnd=function(){if(a.onscrollend){var b=a.getScrollLeft(),c=a.getScrollTop();a.onscrollend.call(a,{type:"scrollend",current:{x:b,y:c},end:{x:b,y:c}})}};this.onmousewheel=function(b){if(!a.wheelprevented){if(a.railslocked)return a.debounced("checkunlock",a.resize,250),!0;if(a.rail.drag)return a.cancelEvent(b);"auto"==a.opt.oneaxismousemode&&0!=b.deltaX&&(a.opt.oneaxismousemode=!1);if(a.opt.oneaxismousemode&&0==b.deltaX&&!a.rail.scrollable)return a.railh&&a.railh.scrollable?a.onmousewheelhr(b):
90
+!0;var c=+new Date,d=!1;a.opt.preservenativescrolling&&a.checkarea+600<c&&(a.nativescrollingarea=a.isScrollable(b),d=!0);a.checkarea=c;if(a.nativescrollingarea)return!0;if(b=p(b,!1,d))a.checkarea=0;return b}};this.onmousewheelhr=function(b){if(!a.wheelprevented){if(a.railslocked||!a.railh.scrollable)return!0;if(a.rail.drag)return a.cancelEvent(b);var c=+new Date,d=!1;a.opt.preservenativescrolling&&a.checkarea+600<c&&(a.nativescrollingarea=a.isScrollable(b),d=!0);a.checkarea=c;return a.nativescrollingarea?
91
+!0:a.railslocked?a.cancelEvent(b):p(b,!0,d)}};this.stop=function(){a.cancelScroll();a.scrollmon&&a.scrollmon.stop();a.cursorfreezed=!1;a.scroll.y=Math.round(a.getScrollTop()*(1/a.scrollratio.y));a.noticeCursor();return a};this.getTransitionSpeed=function(b){var c=Math.round(10*a.opt.scrollspeed);b=Math.min(c,Math.round(b/20*a.opt.scrollspeed));return 20<b?b:0};a.opt.smoothscroll?a.ishwscroll&&e.hastransition&&a.opt.usetransition&&a.opt.smoothscroll?(this.prepareTransition=function(b,c){var d=c?20<
92
+b?b:0:a.getTransitionSpeed(b),f=d?e.prefixstyle+"transform "+d+"ms ease-out":"";a.lasttransitionstyle&&a.lasttransitionstyle==f||(a.lasttransitionstyle=f,a.doc.css(e.transitionstyle,f));return d},this.doScrollLeft=function(b,c){var d=a.scrollrunning?a.newscrolly:a.getScrollTop();a.doScrollPos(b,d,c)},this.doScrollTop=function(b,c){var d=a.scrollrunning?a.newscrollx:a.getScrollLeft();a.doScrollPos(d,b,c)},this.doScrollPos=function(b,c,d){var f=a.getScrollTop(),h=a.getScrollLeft();(0>(a.newscrolly-
93
+f)*(c-f)||0>(a.newscrollx-h)*(b-h))&&a.cancelScroll();0==a.opt.bouncescroll&&(0>c?c=0:c>a.page.maxh&&(c=a.page.maxh),0>b?b=0:b>a.page.maxw&&(b=a.page.maxw));if(a.scrollrunning&&b==a.newscrollx&&c==a.newscrolly)return!1;a.newscrolly=c;a.newscrollx=b;a.newscrollspeed=d||!1;if(a.timer)return!1;a.timer=setTimeout(function(){var d=a.getScrollTop(),f=a.getScrollLeft(),h,k;h=b-f;k=c-d;h=Math.round(Math.sqrt(Math.pow(h,2)+Math.pow(k,2)));h=a.newscrollspeed&&1<a.newscrollspeed?a.newscrollspeed:a.getTransitionSpeed(h);
94
+a.newscrollspeed&&1>=a.newscrollspeed&&(h*=a.newscrollspeed);a.prepareTransition(h,!0);a.timerscroll&&a.timerscroll.tm&&clearInterval(a.timerscroll.tm);0<h&&(!a.scrollrunning&&a.onscrollstart&&a.onscrollstart.call(a,{type:"scrollstart",current:{x:f,y:d},request:{x:b,y:c},end:{x:a.newscrollx,y:a.newscrolly},speed:h}),e.transitionend?a.scrollendtrapped||(a.scrollendtrapped=!0,a.bind(a.doc,e.transitionend,a.onScrollTransitionEnd,!1)):(a.scrollendtrapped&&clearTimeout(a.scrollendtrapped),a.scrollendtrapped=
95
+setTimeout(a.onScrollTransitionEnd,h)),a.timerscroll={bz:new A(d,a.newscrolly,h,0,0,.58,1),bh:new A(f,a.newscrollx,h,0,0,.58,1)},a.cursorfreezed||(a.timerscroll.tm=setInterval(function(){a.showCursor(a.getScrollTop(),a.getScrollLeft())},60)));a.synched("doScroll-set",function(){a.timer=0;a.scrollendtrapped&&(a.scrollrunning=!0);a.setScrollTop(a.newscrolly);a.setScrollLeft(a.newscrollx);if(!a.scrollendtrapped)a.onScrollTransitionEnd()})},50)},this.cancelScroll=function(){if(!a.scrollendtrapped)return!0;
96
+var b=a.getScrollTop(),c=a.getScrollLeft();a.scrollrunning=!1;e.transitionend||clearTimeout(e.transitionend);a.scrollendtrapped=!1;a._unbind(a.doc[0],e.transitionend,a.onScrollTransitionEnd);a.prepareTransition(0);a.setScrollTop(b);a.railh&&a.setScrollLeft(c);a.timerscroll&&a.timerscroll.tm&&clearInterval(a.timerscroll.tm);a.timerscroll=!1;a.cursorfreezed=!1;a.showCursor(b,c);return a},this.onScrollTransitionEnd=function(){a.scrollendtrapped&&a._unbind(a.doc[0],e.transitionend,a.onScrollTransitionEnd);
97
+a.scrollendtrapped=!1;a.prepareTransition(0);a.timerscroll&&a.timerscroll.tm&&clearInterval(a.timerscroll.tm);a.timerscroll=!1;var b=a.getScrollTop(),c=a.getScrollLeft();a.setScrollTop(b);a.railh&&a.setScrollLeft(c);a.noticeCursor(!1,b,c);a.cursorfreezed=!1;0>b?b=0:b>a.page.maxh&&(b=a.page.maxh);0>c?c=0:c>a.page.maxw&&(c=a.page.maxw);if(b!=a.newscrolly||c!=a.newscrollx)return a.doScrollPos(c,b,a.opt.snapbackspeed);a.onscrollend&&a.scrollrunning&&a.triggerScrollEnd();a.scrollrunning=!1}):(this.doScrollLeft=
98
+function(b,c){var d=a.scrollrunning?a.newscrolly:a.getScrollTop();a.doScrollPos(b,d,c)},this.doScrollTop=function(b,c){var d=a.scrollrunning?a.newscrollx:a.getScrollLeft();a.doScrollPos(d,b,c)},this.doScrollPos=function(b,c,d){function e(){if(a.cancelAnimationFrame)return!0;a.scrollrunning=!0;if(n=1-n)return a.timer=s(e)||1;var b=0,c,d,g=d=a.getScrollTop();if(a.dst.ay){g=a.bzscroll?a.dst.py+a.bzscroll.getNow()*a.dst.ay:a.newscrolly;c=g-d;if(0>c&&g<a.newscrolly||0<c&&g>a.newscrolly)g=a.newscrolly;
99
+a.setScrollTop(g);g==a.newscrolly&&(b=1)}else b=1;d=c=a.getScrollLeft();if(a.dst.ax){d=a.bzscroll?a.dst.px+a.bzscroll.getNow()*a.dst.ax:a.newscrollx;c=d-c;if(0>c&&d<a.newscrollx||0<c&&d>a.newscrollx)d=a.newscrollx;a.setScrollLeft(d);d==a.newscrollx&&(b+=1)}else b+=1;2==b?(a.timer=0,a.cursorfreezed=!1,a.bzscroll=!1,a.scrollrunning=!1,0>g?g=0:g>a.page.maxh&&(g=a.page.maxh),0>d?d=0:d>a.page.maxw&&(d=a.page.maxw),d!=a.newscrollx||g!=a.newscrolly?a.doScrollPos(d,g):a.onscrollend&&a.triggerScrollEnd()):
100
+a.timer=s(e)||1}c="undefined"==typeof c||!1===c?a.getScrollTop(!0):c;if(a.timer&&a.newscrolly==c&&a.newscrollx==b)return!0;a.timer&&t(a.timer);a.timer=0;var f=a.getScrollTop(),h=a.getScrollLeft();(0>(a.newscrolly-f)*(c-f)||0>(a.newscrollx-h)*(b-h))&&a.cancelScroll();a.newscrolly=c;a.newscrollx=b;a.bouncescroll&&a.rail.visibility||(0>a.newscrolly?a.newscrolly=0:a.newscrolly>a.page.maxh&&(a.newscrolly=a.page.maxh));a.bouncescroll&&a.railh.visibility||(0>a.newscrollx?a.newscrollx=0:a.newscrollx>a.page.maxw&&
101
+(a.newscrollx=a.page.maxw));a.dst={};a.dst.x=b-h;a.dst.y=c-f;a.dst.px=h;a.dst.py=f;var k=Math.round(Math.sqrt(Math.pow(a.dst.x,2)+Math.pow(a.dst.y,2)));a.dst.ax=a.dst.x/k;a.dst.ay=a.dst.y/k;var l=0,m=k;0==a.dst.x?(l=f,m=c,a.dst.ay=1,a.dst.py=0):0==a.dst.y&&(l=h,m=b,a.dst.ax=1,a.dst.px=0);k=a.getTransitionSpeed(k);d&&1>=d&&(k*=d);a.bzscroll=0<k?a.bzscroll?a.bzscroll.update(m,k):new A(l,m,k,0,1,0,1):!1;if(!a.timer){(f==a.page.maxh&&c>=a.page.maxh||h==a.page.maxw&&b>=a.page.maxw)&&a.checkContentSize();
102
+var n=1;a.cancelAnimationFrame=!1;a.timer=1;a.onscrollstart&&!a.scrollrunning&&a.onscrollstart.call(a,{type:"scrollstart",current:{x:h,y:f},request:{x:b,y:c},end:{x:a.newscrollx,y:a.newscrolly},speed:k});e();(f==a.page.maxh&&c>=f||h==a.page.maxw&&b>=h)&&a.checkContentSize();a.noticeCursor()}},this.cancelScroll=function(){a.timer&&t(a.timer);a.timer=0;a.bzscroll=!1;a.scrollrunning=!1;return a}):(this.doScrollLeft=function(b,c){var d=a.getScrollTop();a.doScrollPos(b,d,c)},this.doScrollTop=function(b,
103
+c){var d=a.getScrollLeft();a.doScrollPos(d,b,c)},this.doScrollPos=function(b,c,d){var e=b>a.page.maxw?a.page.maxw:b;0>e&&(e=0);var f=c>a.page.maxh?a.page.maxh:c;0>f&&(f=0);a.synched("scroll",function(){a.setScrollTop(f);a.setScrollLeft(e)})},this.cancelScroll=function(){});this.doScrollBy=function(b,c){var d=0,d=c?Math.floor((a.scroll.y-b)*a.scrollratio.y):(a.timer?a.newscrolly:a.getScrollTop(!0))-b;if(a.bouncescroll){var e=Math.round(a.view.h/2);d<-e?d=-e:d>a.page.maxh+e&&(d=a.page.maxh+e)}a.cursorfreezed=
104
+!1;e=a.getScrollTop(!0);if(0>d&&0>=e)return a.noticeCursor();if(d>a.page.maxh&&e>=a.page.maxh)return a.checkContentSize(),a.noticeCursor();a.doScrollTop(d)};this.doScrollLeftBy=function(b,c){var d=0,d=c?Math.floor((a.scroll.x-b)*a.scrollratio.x):(a.timer?a.newscrollx:a.getScrollLeft(!0))-b;if(a.bouncescroll){var e=Math.round(a.view.w/2);d<-e?d=-e:d>a.page.maxw+e&&(d=a.page.maxw+e)}a.cursorfreezed=!1;e=a.getScrollLeft(!0);if(0>d&&0>=e||d>a.page.maxw&&e>=a.page.maxw)return a.noticeCursor();a.doScrollLeft(d)};
105
+this.doScrollTo=function(b,c){c&&Math.round(b*a.scrollratio.y);a.cursorfreezed=!1;a.doScrollTop(b)};this.checkContentSize=function(){var b=a.getContentSize();b.h==a.page.h&&b.w==a.page.w||a.resize(!1,b)};a.onscroll=function(b){a.rail.drag||a.cursorfreezed||a.synched("scroll",function(){a.scroll.y=Math.round(a.getScrollTop()*(1/a.scrollratio.y));a.railh&&(a.scroll.x=Math.round(a.getScrollLeft()*(1/a.scrollratio.x)));a.noticeCursor()})};a.bind(a.docscroll,"scroll",a.onscroll);this.doZoomIn=function(b){if(!a.zoomactive){a.zoomactive=
106
+!0;a.zoomrestore={style:{}};var c="position top left zIndex backgroundColor marginTop marginBottom marginLeft marginRight".split(" "),d=a.win[0].style,h;for(h in c){var k=c[h];a.zoomrestore.style[k]="undefined"!=typeof d[k]?d[k]:""}a.zoomrestore.style.width=a.win.css("width");a.zoomrestore.style.height=a.win.css("height");a.zoomrestore.padding={w:a.win.outerWidth()-a.win.width(),h:a.win.outerHeight()-a.win.height()};e.isios4&&(a.zoomrestore.scrollTop=f(window).scrollTop(),f(window).scrollTop(0));
107
+a.win.css({position:e.isios4?"absolute":"fixed",top:0,left:0,"z-index":x+100,margin:"0px"});c=a.win.css("backgroundColor");(""==c||/transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(c))&&a.win.css("backgroundColor","#fff");a.rail.css({"z-index":x+101});a.zoom.css({"z-index":x+102});a.zoom.css("backgroundPosition","0px -18px");a.resizeZoom();a.onzoomin&&a.onzoomin.call(a);return a.cancelEvent(b)}};this.doZoomOut=function(b){if(a.zoomactive)return a.zoomactive=!1,a.win.css("margin",""),a.win.css(a.zoomrestore.style),
108
+e.isios4&&f(window).scrollTop(a.zoomrestore.scrollTop),a.rail.css({"z-index":a.zindex}),a.zoom.css({"z-index":a.zindex}),a.zoomrestore=!1,a.zoom.css("backgroundPosition","0px 0px"),a.onResize(),a.onzoomout&&a.onzoomout.call(a),a.cancelEvent(b)};this.doZoom=function(b){return a.zoomactive?a.doZoomOut(b):a.doZoomIn(b)};this.resizeZoom=function(){if(a.zoomactive){var b=a.getScrollTop();a.win.css({width:f(window).width()-a.zoomrestore.padding.w+"px",height:f(window).height()-a.zoomrestore.padding.h+"px"});
109
+a.onResize();a.setScrollTop(Math.min(a.page.maxh,b))}};this.init();f.nicescroll.push(this)},L=function(f){var c=this;this.nc=f;this.steptime=this.lasttime=this.speedy=this.speedx=this.lasty=this.lastx=0;this.snapy=this.snapx=!1;this.demuly=this.demulx=0;this.lastscrolly=this.lastscrollx=-1;this.timer=this.chky=this.chkx=0;this.time=function(){return+new Date};this.reset=function(f,k){c.stop();var d=c.time();c.steptime=0;c.lasttime=d;c.speedx=0;c.speedy=0;c.lastx=f;c.lasty=k;c.lastscrollx=-1;c.lastscrolly=
110
+-1};this.update=function(f,k){var d=c.time();c.steptime=d-c.lasttime;c.lasttime=d;var d=k-c.lasty,n=f-c.lastx,p=c.nc.getScrollTop(),a=c.nc.getScrollLeft(),p=p+d,a=a+n;c.snapx=0>a||a>c.nc.page.maxw;c.snapy=0>p||p>c.nc.page.maxh;c.speedx=n;c.speedy=d;c.lastx=f;c.lasty=k};this.stop=function(){c.nc.unsynched("domomentum2d");c.timer&&clearTimeout(c.timer);c.timer=0;c.lastscrollx=-1;c.lastscrolly=-1};this.doSnapy=function(f,k){var d=!1;0>k?(k=0,d=!0):k>c.nc.page.maxh&&(k=c.nc.page.maxh,d=!0);0>f?(f=0,d=
111
+!0):f>c.nc.page.maxw&&(f=c.nc.page.maxw,d=!0);d?c.nc.doScrollPos(f,k,c.nc.opt.snapbackspeed):c.nc.triggerScrollEnd()};this.doMomentum=function(f){var k=c.time(),d=f?k+f:c.lasttime;f=c.nc.getScrollLeft();var n=c.nc.getScrollTop(),p=c.nc.page.maxh,a=c.nc.page.maxw;c.speedx=0<a?Math.min(60,c.speedx):0;c.speedy=0<p?Math.min(60,c.speedy):0;d=d&&60>=k-d;if(0>n||n>p||0>f||f>a)d=!1;f=c.speedx&&d?c.speedx:!1;if(c.speedy&&d&&c.speedy||f){var s=Math.max(16,c.steptime);50<s&&(f=s/50,c.speedx*=f,c.speedy*=f,s=
112
+50);c.demulxy=0;c.lastscrollx=c.nc.getScrollLeft();c.chkx=c.lastscrollx;c.lastscrolly=c.nc.getScrollTop();c.chky=c.lastscrolly;var e=c.lastscrollx,r=c.lastscrolly,t=function(){var d=600<c.time()-k?.04:.02;c.speedx&&(e=Math.floor(c.lastscrollx-c.speedx*(1-c.demulxy)),c.lastscrollx=e,0>e||e>a)&&(d=.1);c.speedy&&(r=Math.floor(c.lastscrolly-c.speedy*(1-c.demulxy)),c.lastscrolly=r,0>r||r>p)&&(d=.1);c.demulxy=Math.min(1,c.demulxy+d);c.nc.synched("domomentum2d",function(){c.speedx&&(c.nc.getScrollLeft()!=
113
+c.chkx&&c.stop(),c.chkx=e,c.nc.setScrollLeft(e));c.speedy&&(c.nc.getScrollTop()!=c.chky&&c.stop(),c.chky=r,c.nc.setScrollTop(r));c.timer||(c.nc.hideCursor(),c.doSnapy(e,r))});1>c.demulxy?c.timer=setTimeout(t,s):(c.stop(),c.nc.hideCursor(),c.doSnapy(e,r))};t()}else c.doSnapy(c.nc.getScrollLeft(),c.nc.getScrollTop())}},w=f.fn.scrollTop;f.cssHooks.pageYOffset={get:function(k,c,h){return(c=f.data(k,"__nicescroll")||!1)&&c.ishwscroll?c.getScrollTop():w.call(k)},set:function(k,c){var h=f.data(k,"__nicescroll")||
114
+!1;h&&h.ishwscroll?h.setScrollTop(parseInt(c)):w.call(k,c);return this}};f.fn.scrollTop=function(k){if("undefined"==typeof k){var c=this[0]?f.data(this[0],"__nicescroll")||!1:!1;return c&&c.ishwscroll?c.getScrollTop():w.call(this)}return this.each(function(){var c=f.data(this,"__nicescroll")||!1;c&&c.ishwscroll?c.setScrollTop(parseInt(k)):w.call(f(this),k)})};var B=f.fn.scrollLeft;f.cssHooks.pageXOffset={get:function(k,c,h){return(c=f.data(k,"__nicescroll")||!1)&&c.ishwscroll?c.getScrollLeft():B.call(k)},
115
+set:function(k,c){var h=f.data(k,"__nicescroll")||!1;h&&h.ishwscroll?h.setScrollLeft(parseInt(c)):B.call(k,c);return this}};f.fn.scrollLeft=function(k){if("undefined"==typeof k){var c=this[0]?f.data(this[0],"__nicescroll")||!1:!1;return c&&c.ishwscroll?c.getScrollLeft():B.call(this)}return this.each(function(){var c=f.data(this,"__nicescroll")||!1;c&&c.ishwscroll?c.setScrollLeft(parseInt(k)):B.call(f(this),k)})};var C=function(k){var c=this;this.length=0;this.name="nicescrollarray";this.each=function(d){for(var f=
116
+0,h=0;f<c.length;f++)d.call(c[f],h++);return c};this.push=function(d){c[c.length]=d;c.length++};this.eq=function(d){return c[d]};if(k)for(var h=0;h<k.length;h++){var m=f.data(k[h],"__nicescroll")||!1;m&&(this[this.length]=m,this.length++)}return this};(function(f,c,h){for(var m=0;m<c.length;m++)h(f,c[m])})(C.prototype,"show hide toggle onResize resize remove stop doScrollPos".split(" "),function(f,c){f[c]=function(){var f=arguments;return this.each(function(){this[c].apply(this,f)})}});f.fn.getNiceScroll=
117
+function(k){return"undefined"==typeof k?new C(this):this[k]&&f.data(this[k],"__nicescroll")||!1};f.extend(f.expr[":"],{nicescroll:function(k){return f.data(k,"__nicescroll")?!0:!1}});f.fn.niceScroll=function(k,c){"undefined"!=typeof c||"object"!=typeof k||"jquery"in k||(c=k,k=!1);c=f.extend({},c);var h=new C;"undefined"==typeof c&&(c={});k&&(c.doc=f(k),c.win=f(this));var m=!("doc"in c);m||"win"in c||(c.win=f(this));this.each(function(){var d=f(this).data("__nicescroll")||!1;d||(c.doc=m?f(this):c.doc,
118
+d=new R(c,f(this)),f(this).data("__nicescroll",d));h.push(d)});return 1==h.length?h[0]:h};window.NiceScroll={getjQuery:function(){return f}};f.nicescroll||(f.nicescroll=new C,f.nicescroll.options=I)});

+ 11
- 0
public/91APP/js/libs/modernizr-2.6.2-respond-1.1.0.min.js
File diff suppressed because it is too large
View File


+ 175
- 0
public/91APP/js/main.js View File

@@ -0,0 +1,175 @@
1
+/**
2
+ *
3
+ * @authors Eric Hsiao
4
+ *
5
+ */
6
+
7
+main = function () {
8
+
9
+  //private menbers
10
+
11
+  var KOLData = {
12
+    "name": "不知道",
13
+    "text": "冰花煎餃很簡單",
14
+    "kv_img": "ralf.png",
15
+    "kv_img_s": "ralf_s.png",
16
+    "kv_img_s_name": "ralf_s_name.png",
17
+    "tag": "名人推薦,麵類,台式",
18
+    "ingredient": [
19
+      {
20
+        "ingredient_name": "奇美 奇美冷凍熟水餃-高麗菜豬肉1275g",
21
+        "ingredient_id": 1,
22
+        "ingredient_img": "ralf_01.jpg",
23
+        "salepage_url": "https://shop.pxmart.com.tw/SalePage/index/1403948",
24
+        "salepage_id": 1403948,
25
+        "sku_id": 1415926
26
+      },
27
+      {
28
+        "ingredient_name": "義峰 義峰低筋麵粉1kg",
29
+        "ingredient_id": 2,
30
+        "ingredient_img": "ralf_02.jpg",
31
+        "salepage_url": "https://shop.pxmart.com.tw/SalePage/index/1403234",
32
+        "salepage_id": 1403234,
33
+        "sku_id": 1415212
34
+      },
35
+      {
36
+        "ingredient_name": "欣臨 金寶日式風味甜玉米濃湯305g",
37
+        "ingredient_id": 3,
38
+        "ingredient_img": "ralf_03.jpg",
39
+        "salepage_url": "https://shop.pxmart.com.tw/SalePage/index/1402753",
40
+        "salepage_id": 1402753,
41
+        "sku_id": 1414731
42
+      }
43
+    ],
44
+    "kol": {
45
+      "name": "全聯先生",
46
+      "id": "Ralf",
47
+      "index": "0",
48
+      "UTM":"&utm_campaign=Ralf&utm_medium=KOLbuy&utm_source=web"
49
+    },
50
+    "voice": {
51
+      "source": "ralf.mp3",
52
+      "subtitle": [
53
+        {
54
+          "timecode": "00:00",
55
+          "text": "每天都「不知道」煮什麼好?<br>看雙寶煮夫全聯先生怎麼快速出餐,一打二也不失誤!",
56
+          "ingredient_id": []
57
+        },
58
+        {
59
+          "timecode": "00:30",
60
+          "text": "1.在平底鍋內倒入一些油,再將水餃排列好。",
61
+          "ingredient_id": [
62
+            1
63
+          ]
64
+        },
65
+        {
66
+          "timecode": "00:36",
67
+          "text": "2.將10克低筋麵粉加入200cc水中,拌勻倒入鍋內。",
68
+          "ingredient_id": [
69
+            2
70
+          ]
71
+        },
72
+        {
73
+          "timecode": "00:44",
74
+          "text": "3.蓋上鍋蓋,以中小火慢慢收乾水分,待水分收乾就完成了。",
75
+          "ingredient_id": []
76
+        },
77
+        {
78
+          "timecode": "00:59",
79
+          "text": "4.隨心情搭配玉米濃湯或是酸辣湯,打個蛋花就上桌。",
80
+          "ingredient_id": [
81
+            3
82
+          ]
83
+        }
84
+      ]
85
+    }
86
+  };
87
+
88
+
89
+  //private methods
90
+  function init() {
91
+    console.log('main is loaded.');
92
+
93
+    // loadData();
94
+    getOrderURL(KOLData);
95
+    loadData();
96
+  }
97
+
98
+  function getOrderURL(_kolData) {
99
+
100
+    var _ingredientData = _kolData.ingredient;
101
+    var resuleData = [];
102
+
103
+    _ingredientData.forEach(element => {
104
+      // console.log(element);
105
+      var _result =  { "salepage_id": "", "sku_id": "", "qty": 1 };
106
+      _result.salepage_id = element.salepage_id;
107
+      _result.sku_id = element.sku_id;
108
+      if(_result.sku_id !== null){
109
+        resuleData.push(_result);
110
+      }      
111
+    });
112
+
113
+    console.log(resuleData);
114
+
115
+    var _utm = _kolData.kol.UTM;
116
+    
117
+    var _url = 'http://shop.pxmart.com.tw/v2/ShoppingCart/BatchInsert?data=' + encodeURIComponent(JSON.stringify(resuleData)) + _utm;
118
+    console.log(_url);
119
+
120
+    return _url;    
121
+  } 
122
+
123
+  function loadData() {
124
+
125
+    // if (index < salepageData.length) {
126
+      console.log('START index = ',index);
127
+      var _data = salepageData[index];
128
+      var _result = { "salepage_id": "", "sku_id": "", "qty": 1 };
129
+
130
+      _result.salepage_id = _data.salepage_id;
131
+
132
+      $.ajax({
133
+        type: "POST",
134
+        url: "https://apigw.px.91app.tw/ec/V1/SalePage/GetMain",
135
+        data: { "id": 1403948 },
136
+        dataType: "json",
137
+        success: function (response) {
138
+          console.log('================== response ===================');
139
+          console.log(response);
140
+
141
+          if (response.Status == 'Success') {
142
+            // var _skuId = response.Data.SkuList[0].SkuId;
143
+            // _result.sku_id = _skuId;
144
+            // resuleData.push(_result);
145
+            // index++;
146
+
147
+            // loadData();
148
+
149
+          }
150
+        },
151
+        error: function (XMLHttpRequest, textStatus, errorThrown) {
152
+          console.log("Status: " + textStatus + ", Error: " + errorThrown);
153
+        }
154
+      });
155
+    // } else {
156
+    //   console.log('COMPLETE', resuleData);
157
+    // }
158
+  }
159
+
160
+  //constructor
161
+
162
+  {
163
+    $(document).ready(function () {
164
+      init();
165
+    });
166
+  }
167
+
168
+  //public
169
+
170
+  return {
171
+
172
+  }
173
+}
174
+
175
+main = new main();

+ 45
- 0
public/91APP/js/simplePage.js View File

@@ -0,0 +1,45 @@
1
+/**
2
+ *
3
+ * @authors Eric Hsiao
4
+ *
5
+ */
6
+
7
+simplePage = function (){
8
+
9
+	//private menbers
10
+
11
+	//private methods
12
+	function init () {
13
+    console.log('simplePage is loaded.');
14
+
15
+    
16
+  }
17
+  
18
+  function intoPage() {
19
+    if(currentPage != undefined) currentPage.leavePage();
20
+  }
21
+
22
+  function leavePage() {
23
+    
24
+  }
25
+
26
+	//constructor
27
+	{
28
+		$(document).ready(function() {
29
+			init();
30
+		});
31
+	}
32
+
33
+	//public
34
+
35
+	return {
36
+    intoPage : function () {
37
+      intoPage();
38
+    },
39
+    leavePage : function () {
40
+      leavePage();
41
+    }
42
+	};
43
+};
44
+
45
+var simplePage = new simplePage();

+ 32
- 0
public/91APP/js/templete.js View File

@@ -0,0 +1,32 @@
1
+/**
2
+ *
3
+ * @authors Eric Hsiao
4
+ *
5
+ */
6
+
7
+templete = function (){
8
+
9
+	//private menbers
10
+
11
+
12
+	//private methods
13
+	function init () {
14
+    console.log('templete is loaded.');
15
+	}
16
+
17
+	//constructor
18
+
19
+	{
20
+		$(document).ready(function() {
21
+			init();
22
+		});
23
+	}
24
+
25
+	//public
26
+
27
+	return {
28
+
29
+	};
30
+};
31
+
32
+var templete = new templete();

+ 84
- 0
public/91APP/js/utlis.js View File

@@ -0,0 +1,84 @@
1
+/**
2
+ *
3
+ * @authors Eric Hsiao
4
+ *
5
+ */
6
+
7
+/* utlis */
8
+
9
+// if (typeof console == "undefined") {
10
+//     window.console = {
11
+//         log: function () {}
12
+//     };
13
+// }
14
+
15
+ // window.console = {
16
+ //        log: function () {}
17
+ // };
18
+
19
+function ga_pageView(key) {
20
+  ga('send', 'pageview', key);
21
+  console.log("ga_pageView: " + key);
22
+}
23
+
24
+function ga_ButtonClick(key) {
25
+  ga('send', 'event', 'Button', 'Click', key);
26
+  console.log("ga_ButtonClick: " + key);
27
+}
28
+
29
+function setDefault(_textbox, _value) { // depend on jQuery
30
+  $(_textbox).val(_value).css({opacity:.4});
31
+  $(_textbox).focus(
32
+    function() {
33
+      if ($(this).val() == _value) {
34
+        $(this).val('').css({opacity:1});
35
+      }
36
+    })
37
+    .blur(function() {
38
+      if ($(this).val() == '') {
39
+        $(this).val(_value).css({opacity:.4});
40
+      }
41
+    });
42
+}
43
+
44
+var isMobile = false;
45
+var isIE = false;
46
+
47
+utlis = function (){
48
+
49
+	//private menbers
50
+
51
+
52
+	//private methods
53
+	function init () {
54
+		console.log('all is loaded.');
55
+	}
56
+
57
+	//constructor
58
+
59
+	{
60
+    if ($('html').is('.ie6, .ie7, .ie8')) {
61
+      isIE = true;
62
+      // alert('.ie6, .ie7, .ie8');
63
+    }
64
+
65
+		$(document).ready(function() {
66
+
67
+		    if($('body').width() <= 640){
68
+		      isMobile = true;
69
+		  }else{
70
+		    	isMobile = false;
71
+		  }
72
+
73
+			init();
74
+		});
75
+	}
76
+
77
+	//public
78
+
79
+	return {
80
+
81
+	}
82
+}
83
+
84
+utlis = new utlis();

+ 1
- 0
public/[Eric]photoHelper/css/normalize.min.css View File

@@ -0,0 +1 @@
1
+/*! normalize.css v1.1.2 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}

+ 124
- 0
public/[Eric]photoHelper/css/style.css View File

@@ -0,0 +1,124 @@
1
+@charset "UTF-8";
2
+/**
3
+ *
4
+ * @authors Eric Hsiao
5
+ *
6
+ */
7
+
8
+/* ==========================================================================
9
+   HTML5 Boilerplate styles - h5bp.com (generated via initializr.com)
10
+   ========================================================================== */
11
+
12
+.chromeframe {
13
+    margin: 0.2em 0;
14
+    background: #ccc;
15
+    color: #000;
16
+    padding: 0.2em 0;
17
+}
18
+
19
+/* ==========================================================================
20
+   Content class
21
+   ========================================================================== */
22
+
23
+html,
24
+body {
25
+  margin:0;
26
+  padding:0;
27
+  height:100%;
28
+}
29
+
30
+#wrapper {
31
+  min-height:100%;
32
+  position:relative;
33
+}
34
+
35
+#header {
36
+  background:#ededed;
37
+  padding-top:10px; /* fixed h1 */
38
+}
39
+
40
+#content {
41
+  padding-bottom:100px; /* Height of the footer element */
42
+}
43
+
44
+#footer {
45
+  background:#666;
46
+  width:100%;
47
+  height:100px;
48
+  position:absolute;
49
+  bottom:0;
50
+  left:0;
51
+}
52
+
53
+/* ==========================================================================
54
+   Responsive class
55
+   ========================================================================== */
56
+
57
+
58
+@media only screen and (max-width: 640px) {
59
+
60
+
61
+}
62
+
63
+
64
+/* ==========================================================================
65
+   Helper classes
66
+   ========================================================================== */
67
+
68
+.ir {
69
+    background-color: transparent;
70
+    border: 0;
71
+    overflow: hidden;
72
+    *text-indent: -9999px;
73
+}
74
+
75
+.ir:before {
76
+    content: "";
77
+    display: block;
78
+    width: 0;
79
+    height: 150%;
80
+}
81
+
82
+.hidden {
83
+    display: none !important;
84
+    visibility: hidden;
85
+}
86
+
87
+.visuallyhidden {
88
+    border: 0;
89
+    clip: rect(0 0 0 0);
90
+    height: 1px;
91
+    margin: -1px;
92
+    overflow: hidden;
93
+    padding: 0;
94
+    position: absolute;
95
+    width: 1px;
96
+}
97
+
98
+.visuallyhidden.focusable:active,
99
+.visuallyhidden.focusable:focus {
100
+    clip: auto;
101
+    height: auto;
102
+    margin: 0;
103
+    overflow: visible;
104
+    position: static;
105
+    width: auto;
106
+}
107
+
108
+.invisible {
109
+    visibility: hidden;
110
+}
111
+
112
+.clearfix:before,
113
+.clearfix:after {
114
+    content: " ";
115
+    display: table;
116
+}
117
+
118
+.clearfix:after {
119
+    clear: both;
120
+}
121
+
122
+.clearfix {
123
+    *zoom: 1;
124
+}

BIN
public/[Eric]photoHelper/images/demo1.jpg View File


BIN
public/[Eric]photoHelper/images/demo2.jpg View File


+ 66
- 0
public/[Eric]photoHelper/index.html View File

@@ -0,0 +1,66 @@
1
+<!DOCTYPE html>
2
+<!--[if IE 6]><html class="ie6 lte9 lte8 lte7" lang="zh-tw"><![endif]-->
3
+<!--[if IE 8]><html class="ie8 lte9 lte8" lang="zh-tw"><![endif]-->
4
+<!--[if IE 9]><html class="ie9 lte9" lang="zh-tw"><![endif]-->
5
+<!--[if IE 7]><html class="ie7 lte9 lte8 lte7" lang="zh-tw"><![endif]-->
6
+<!--[if !(IE 6) | !(IE 7) | !(IE 8) | !(IE 9)  ]><!--><html  lang="zh-tw"><!--<![endif]-->
7
+    <head>
8
+        <meta charset="utf-8">
9
+        <meta content-language="zh-TW">
10
+        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
11
+        <meta name="description" content="">
12
+        <meta name="viewport" content="width=1000,initial-scale=1,maximum-scale=1,user-scalable=0">
13
+        <meta property="og:title" content=""/>
14
+        <meta property="og:description" content=""/>
15
+        <meta property="og:url" content=""/>
16
+        <meta property="og:image" content=""/>
17
+
18
+         <title></title>
19
+
20
+        <link rel="stylesheet" href="css/normalize.min.css">
21
+        <link rel="stylesheet" href="css/style.css">
22
+        <script src="js/libs/modernizr-2.6.2-respond-1.1.0.min.js"></script>
23
+
24
+        <style>
25
+          .block img{
26
+            height: 150px;
27
+            width: auto;
28
+          }
29
+        </style>
30
+    </head>
31
+    <body>
32
+
33
+        <div id="wrapper">
34
+
35
+          <div class="block">
36
+            <p>上傳模板(不超過512KB)</p>
37
+            <input class="templeteUpLoad__btn" type="file">
38
+            <img class="templete_output" src="" alt="">
39
+          </div>
40
+
41
+          <div class="block">
42
+            <p>上傳照片(不超過512KB)</p>
43
+            <input class="plotoUpLoad__btn" type="file">
44
+            <img class="output" src="" alt="">
45
+          </div>
46
+          <hr>
47
+          <p>合成比例(0.01~1 越小越像消費者)</p>
48
+          <input class="faceFusion__alpha" type="text" value="0.01">
49
+          <button class="faceFusion__start">開始融合</button>
50
+          <br>          
51
+          <hr>
52
+          <h2>合成結果</h2>
53
+          <div class="msg"></div>
54
+          <img class="faceFusion" src="" alt="">
55
+        </div><!-- #wrapper -->
56
+
57
+        <script src="js/libs/jquery-1.11.1.min.js"></script>
58
+        <script src="js/utlis.js"></script>
59
+        <script src="js/main.js"></script>
60
+        
61
+        <script src="js/exif.js"></script>
62
+        <script src="js/photoHelper.js"></script>
63
+        <script src="js/faceFusionAPI.js"></script>
64
+
65
+    </body>
66
+</html>

+ 1059
- 0
public/[Eric]photoHelper/js/exif.js
File diff suppressed because it is too large
View File


+ 0
- 0
public/[Eric]photoHelper/js/faceFusionAPI.js View File


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