sandm 3 жил өмнө
parent
commit
92d2775eb4
100 өөрчлөгдсөн 45666 нэмэгдсэн , 0 устгасан
  1. 15 0
      .editorconfig
  2. 62 0
      .env.docker
  3. 57 0
      .env.example
  4. 4 0
      .gitignore
  5. 1 0
      .htaccess
  6. 1 0
      .phpunit.result.cache
  7. 13 0
      .styleci.yml
  8. 26 0
      404.html
  9. 1 0
      DingTalkToken
  10. 661 0
      LICENSE
  11. 59 0
      README-EN.md
  12. 18112 0
      _ide_helper.php
  13. 77 0
      app/Console/Commands/Action.php
  14. 41 0
      app/Console/Kernel.php
  15. 28 0
      app/Events/ServerStartEvent.php
  16. 24 0
      app/Events/WorkerStartEvent.php
  17. 62 0
      app/Exceptions/Handler.php
  18. 260 0
      app/Http/Controllers/Api/ChatController.php
  19. 347 0
      app/Http/Controllers/Api/DingController.php
  20. 680 0
      app/Http/Controllers/Api/DocsController.php
  21. 3154 0
      app/Http/Controllers/Api/ProjectController.php
  22. 416 0
      app/Http/Controllers/Api/ReportController.php
  23. 290 0
      app/Http/Controllers/Api/SystemController.php
  24. 587 0
      app/Http/Controllers/Api/UsersController.php
  25. 10 0
      app/Http/Controllers/Api/apidoc.json
  26. 89 0
      app/Http/Controllers/Api/apidoc.php
  27. 13 0
      app/Http/Controllers/Controller.php
  28. 68 0
      app/Http/Controllers/IndexController.php
  29. 70 0
      app/Http/Kernel.php
  30. 32 0
      app/Http/Middleware/ApiMiddleware.php
  31. 21 0
      app/Http/Middleware/Authenticate.php
  32. 17 0
      app/Http/Middleware/CheckForMaintenanceMode.php
  33. 35 0
      app/Http/Middleware/EnableCrossRequestMiddleware.php
  34. 17 0
      app/Http/Middleware/EncryptCookies.php
  35. 27 0
      app/Http/Middleware/RedirectIfAuthenticated.php
  36. 18 0
      app/Http/Middleware/TrimStrings.php
  37. 23 0
      app/Http/Middleware/TrustProxies.php
  38. 39 0
      app/Http/Middleware/VerifyCsrfToken.php
  39. 29 0
      app/Jobs/Timer/SystemCronJob.php
  40. 526 0
      app/Model/DBCache.php
  41. 55 0
      app/Model/DBClause.php
  42. 32 0
      app/Model/DOModel.php
  43. 2556 0
      app/Module/Base.php
  44. 144 0
      app/Module/BillExport.php
  45. 16 0
      app/Module/BillImport.php
  46. 245 0
      app/Module/Chat.php
  47. 105 0
      app/Module/Docs.php
  48. 235 0
      app/Module/Ihttp.php
  49. 234 0
      app/Module/Project.php
  50. 115 0
      app/Module/Umeng.php
  51. 350 0
      app/Module/Users.php
  52. 8469 0
      app/Module/ip/all_cn.txt
  53. 28 0
      app/Providers/AppServiceProvider.php
  54. 30 0
      app/Providers/AuthServiceProvider.php
  55. 21 0
      app/Providers/BroadcastServiceProvider.php
  56. 34 0
      app/Providers/EventServiceProvider.php
  57. 80 0
      app/Providers/RouteServiceProvider.php
  58. 468 0
      app/Services/WebSocketService.php
  59. 30 0
      app/SubTask.php
  60. 30 0
      app/Task.php
  61. 102 0
      app/Tasks/AutoArchivedTask.php
  62. 47 0
      app/Tasks/ChromeExtendTask.php
  63. 50 0
      app/Tasks/NotificationTask.php
  64. 27 0
      app/Tasks/PushTask.php
  65. 39 0
      app/User.php
  66. 53 0
      artisan
  67. 97 0
      assets/js/_components/ScrollerY.vue
  68. 49 0
      assets/js/_components/Title.vue
  69. 114 0
      assets/js/_components/scrollerX.vue
  70. 42 0
      assets/js/_components/sreachTitle.vue
  71. 21 0
      assets/js/_modules/directives/clickoutside.js
  72. 108 0
      assets/js/_modules/directives/popper-novalue.js
  73. 77 0
      assets/js/_modules/directives/transfer-dom.js
  74. 179 0
      assets/js/_modules/language/index.js
  75. 52 0
      assets/js/_modules/mixins/index.js
  76. 1562 0
      assets/js/common.js
  77. 272 0
      assets/js/main/App.vue
  78. 94 0
      assets/js/main/app.js
  79. 63 0
      assets/js/main/components/DrawerTabsContainer.vue
  80. 178 0
      assets/js/main/components/FullCalendar/FullCalendar.vue
  81. 787 0
      assets/js/main/components/FullCalendar/components/body.vue
  82. 3 0
      assets/js/main/components/FullCalendar/components/bus.js
  83. 106 0
      assets/js/main/components/FullCalendar/components/dateFunc.js
  84. 130 0
      assets/js/main/components/FullCalendar/components/header.vue
  85. 17 0
      assets/js/main/components/FullCalendar/dataMap/langSets.js
  86. 5 0
      assets/js/main/components/FullCalendar/index.js
  87. 597 0
      assets/js/main/components/ImgUpload.vue
  88. 13 0
      assets/js/main/components/MDEditor/README.md
  89. 138 0
      assets/js/main/components/MDEditor/assets/css/dark.less
  90. 113 0
      assets/js/main/components/MDEditor/assets/css/github.less
  91. 950 0
      assets/js/main/components/MDEditor/assets/css/index.less
  92. 132 0
      assets/js/main/components/MDEditor/assets/css/light.less
  93. 93 0
      assets/js/main/components/MDEditor/assets/css/one-dark.less
  94. 27 0
      assets/js/main/components/MDEditor/assets/css/theme.less
  95. 3 0
      assets/js/main/components/MDEditor/assets/font/iconfont.css
  96. BIN
      assets/js/main/components/MDEditor/assets/font/iconfont.eot
  97. 37 0
      assets/js/main/components/MDEditor/assets/font/iconfont.svg
  98. BIN
      assets/js/main/components/MDEditor/assets/font/iconfont.ttf
  99. BIN
      assets/js/main/components/MDEditor/assets/font/iconfont.woff
  100. BIN
      assets/js/main/components/MDEditor/assets/font/iconfont.woff2

+ 15 - 0
.editorconfig

@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.{yml,yaml}]
+indent_size = 2

+ 62 - 0
.env.docker

@@ -0,0 +1,62 @@
+APP_NAME=Wookteam
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=true
+APP_URL=http://localhost
+APP_PORT=8000
+APP_PORT_SSL=44300
+
+LOG_CHANNEL=stack
+
+DB_CONNECTION=mysql
+DB_HOST=mariadb
+DB_PORT=3306
+DB_DATABASE=wookteam
+DB_USERNAME=wookteam
+DB_PASSWORD=123456
+
+DB_ROOT_PASSWORD=
+DB_PREFIX=pre_
+
+BROADCAST_DRIVER=log
+CACHE_DRIVER=redis
+QUEUE_CONNECTION=redis
+SESSION_DRIVER=redis
+SESSION_LIFETIME=120
+
+REDIS_HOST=redis
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+
+MAIL_MAILER=smtp
+MAIL_HOST=smtp.mailtrap.io
+MAIL_PORT=2525
+MAIL_USERNAME=null
+MAIL_PASSWORD=null
+MAIL_ENCRYPTION=null
+MAIL_FROM_ADDRESS=null
+MAIL_FROM_NAME="${APP_NAME}"
+
+AWS_ACCESS_KEY_ID=
+AWS_SECRET_ACCESS_KEY=
+AWS_DEFAULT_REGION=us-east-1
+AWS_BUCKET=
+
+PUSHER_APP_ID=
+PUSHER_APP_KEY=
+PUSHER_APP_SECRET=
+PUSHER_APP_CLUSTER=mt1
+
+UMENG_PUSH_IOS_APPKEY=
+UMENG_PUSH_IOS_APPMASTERSECRET=
+UMENG_PUSH_ANDROID_APPKEY=
+UMENG_PUSH_ANDROID_APPMASTERSECRET=
+
+MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
+MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
+
+LARAVELS_LISTEN_IP=0.0.0.0
+LARAVELS_LISTEN_PORT=5200
+LARAVELS_PROXY_URL=
+
+DOCKER_ID=

+ 57 - 0
.env.example

@@ -0,0 +1,57 @@
+APP_NAME=Wookteam
+APP_ENV=local
+APP_KEY=
+APP_DEBUG=true
+APP_URL=http://localhost
+APP_PORT=80
+
+LOG_CHANNEL=stack
+
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=wookteam
+DB_USERNAME=root
+DB_PASSWORD=123456
+DB_PREFIX=pre_
+
+BROADCAST_DRIVER=log
+CACHE_DRIVER=file
+QUEUE_CONNECTION=sync
+SESSION_DRIVER=file
+SESSION_LIFETIME=120
+
+REDIS_HOST=127.0.0.1
+REDIS_PASSWORD=null
+REDIS_PORT=6379
+
+MAIL_MAILER=smtp
+MAIL_HOST=smtp.mailtrap.io
+MAIL_PORT=2525
+MAIL_USERNAME=null
+MAIL_PASSWORD=null
+MAIL_ENCRYPTION=null
+MAIL_FROM_ADDRESS=null
+MAIL_FROM_NAME="${APP_NAME}"
+
+AWS_ACCESS_KEY_ID=
+AWS_SECRET_ACCESS_KEY=
+AWS_DEFAULT_REGION=us-east-1
+AWS_BUCKET=
+
+PUSHER_APP_ID=
+PUSHER_APP_KEY=
+PUSHER_APP_SECRET=
+PUSHER_APP_CLUSTER=mt1
+
+UMENG_PUSH_IOS_APPKEY=
+UMENG_PUSH_IOS_APPMASTERSECRET=
+UMENG_PUSH_ANDROID_APPKEY=
+UMENG_PUSH_ANDROID_APPMASTERSECRET=
+
+MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
+MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
+
+LARAVELS_LISTEN_IP=127.0.0.1
+LARAVELS_LISTEN_PORT=5200
+LARAVELS_PROXY_URL=

+ 4 - 0
.gitignore

@@ -4,3 +4,7 @@
 .env.php
 .env
 
+config
+node_modules
+storage
+vendor

+ 1 - 0
.htaccess

@@ -0,0 +1 @@
+ 

+ 1 - 0
.phpunit.result.cache

@@ -0,0 +1 @@
+{"version":1,"defects":[],"times":{"Tests\\Unit\\ExampleTest::testBasicTest":0.102,"Tests\\Feature\\ExampleTest::testBasicTest":0.685}}

+ 13 - 0
.styleci.yml

@@ -0,0 +1,13 @@
+php:
+  preset: laravel
+  disabled:
+    - unused_use
+  finder:
+    not-name:
+      - index.php
+      - server.php
+js:
+  finder:
+    not-name:
+      - webpack.mix.js
+css: true

+ 26 - 0
404.html

@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+<title>404</title>
+<style>
+	body{
+		background-color:#444;
+		font-size:14px;
+	}
+	h3{
+		font-size:60px;
+		color:#eee;
+		text-align:center;
+		padding-top:30px;
+		font-weight:normal;
+	}
+</style>
+</head>
+
+<body>
+<h3>404,您请求的文件不存在!</h3>
+</body>
+</html>

+ 1 - 0
DingTalkToken

@@ -0,0 +1 @@
+{"errcode":0,"access_token":"2c6beccd0d39301dbd263ff5e2c0ef86","errmsg":"ok","expires_in":1653448622}

+ 661 - 0
LICENSE

@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<https://www.gnu.org/licenses/>.

+ 59 - 0
README-EN.md

@@ -0,0 +1,59 @@
+# Introduction
+
+**[中文文档](README.md)**
+
+- `wookteam` Is a lightweight online team collaboration tool, provides a variety of documentation tools, online mind mapping, online flow chart, project management, task distribution, knowledge base management tools.
+- `wookteam` Support team online chat communication, subscribe task dynamic real-time push.
+- **`wookteam` All open source.**
+
+## Installation
+- [Install(Docker)](install/en/DOCKER.md)
+- [Install(Server)](install/en/SERVER.md)
+- [Install(Bt Panel)](install/BT.md)
+
+## Website
+
+- [https://www.wookteam.com](https://www.wookteam.com)
+
+## Demo
+
+- [https://demo.wookteam.com](https://demo.wookteam.com) (admin/123456)
+
+## WeChat
+
+- ![WeChat](resources/assets/statics/other/wxqr.jpeg)
+
+## Technology
+
+- API Framework: [Laravel7](https://laravel.com/) + LaravelS
+- UI Framework: [Vue 2.0](https://cn.vuejs.org/) + Iview UI
+- Database: Mysql
+- Communication: Swoole
+- Theme style: Kooteam
+
+## Internationalization
+
+- `WookTeam`Support internationalization, support: simplified Chinese, English, English translation from Google translation. If you have a better grammar you are welcome to write it. [Translation data](https://docs.google.com/spreadsheets/d/1m0de8-5vCwjKRwW_lsgzsi8wmOmQRl_bIMGN988Keak/edit?usp=sharing)
+
+## Function
+
+**1. Four quadrants: Highlight priorities, help employees arrange their time properly, and improve work efficiency**
+![Four quadrants: Highlight priorities, help employees arrange their time properly, and improve work efficiency](resources/assets/statics/images/index/todo.jpg)
+
+**2. Online flow chart: online flow chart tool, easy to use**
+![Online flow chart: online flow chart tool, easy to use](resources/assets/statics/images/index/banner/1.jpg)
+
+**3. Online mind mapping: Organize your thoughts and optimize your workflow**
+![Online mind mapping: Organize your thoughts and optimize your workflow](resources/assets/statics/images/index/banner/2.jpg)
+
+**4. Project management: Custom project kanban, visual task scheduling**
+![Project management: Custom project kanban, visual task scheduling](resources/assets/statics/images/index/project.jpg)
+
+**5. Online knowledge base: online flowcharts, online documentation, and visual catalogs, document management without worry**
+![Online knowledge base: online flowcharts, online documentation, and visual catalogs, document management without worry](resources/assets/statics/images/index/wiki.jpg)
+
+**6. Task Gantt chart: Visual task time planning, intuitive and convenient**
+![Task Gantt chart: Visual task time planning, intuitive and convenient](resources/assets/statics/images/index/gantt.jpg)
+
+**7. Instant chat: team internal communication, real-time understanding of project dynamics**
+![Instant chat: team internal communication, real-time understanding of project dynamics](resources/assets/statics/images/index/chat.jpg)

+ 18112 - 0
_ide_helper.php

@@ -0,0 +1,18112 @@
+<?php
+// @formatter:off
+
+/**
+ * A helper file for Laravel, to provide autocomplete information to your IDE
+ * Generated for Laravel 7.26.1.
+ *
+ * This file should not be included in your code, only analyzed by your IDE!
+ *
+ * @author Barry vd. Heuvel <barryvdh@gmail.com>
+ * @see https://github.com/barryvdh/laravel-ide-helper
+ */
+
+    namespace Illuminate\Support\Facades { 
+            /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Foundation\Application
+     */ 
+        class App {
+                    /**
+         * Get the version number of the application.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function version()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->version();
+        }
+                    /**
+         * Run the given array of bootstrap classes.
+         *
+         * @param string[] $bootstrappers
+         * @return void 
+         * @static 
+         */ 
+        public static function bootstrapWith($bootstrappers)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bootstrapWith($bootstrappers);
+        }
+                    /**
+         * Register a callback to run after loading the environment.
+         *
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function afterLoadingEnvironment($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->afterLoadingEnvironment($callback);
+        }
+                    /**
+         * Register a callback to run before a bootstrapper.
+         *
+         * @param string $bootstrapper
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function beforeBootstrapping($bootstrapper, $callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->beforeBootstrapping($bootstrapper, $callback);
+        }
+                    /**
+         * Register a callback to run after a bootstrapper.
+         *
+         * @param string $bootstrapper
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function afterBootstrapping($bootstrapper, $callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->afterBootstrapping($bootstrapper, $callback);
+        }
+                    /**
+         * Determine if the application has been bootstrapped before.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasBeenBootstrapped()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->hasBeenBootstrapped();
+        }
+                    /**
+         * Set the base path for the application.
+         *
+         * @param string $basePath
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function setBasePath($basePath)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->setBasePath($basePath);
+        }
+                    /**
+         * Get the path to the application "app" directory.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function path($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->path($path);
+        }
+                    /**
+         * Set the application directory.
+         *
+         * @param string $path
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function useAppPath($path)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->useAppPath($path);
+        }
+                    /**
+         * Get the base path of the Laravel installation.
+         *
+         * @param string $path Optionally, a path to append to the base path
+         * @return string 
+         * @static 
+         */ 
+        public static function basePath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->basePath($path);
+        }
+                    /**
+         * Get the path to the bootstrap directory.
+         *
+         * @param string $path Optionally, a path to append to the bootstrap path
+         * @return string 
+         * @static 
+         */ 
+        public static function bootstrapPath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->bootstrapPath($path);
+        }
+                    /**
+         * Get the path to the application configuration files.
+         *
+         * @param string $path Optionally, a path to append to the config path
+         * @return string 
+         * @static 
+         */ 
+        public static function configPath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->configPath($path);
+        }
+                    /**
+         * Get the path to the database directory.
+         *
+         * @param string $path Optionally, a path to append to the database path
+         * @return string 
+         * @static 
+         */ 
+        public static function databasePath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->databasePath($path);
+        }
+                    /**
+         * Set the database directory.
+         *
+         * @param string $path
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function useDatabasePath($path)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->useDatabasePath($path);
+        }
+                    /**
+         * Get the path to the language files.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function langPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->langPath();
+        }
+                    /**
+         * Get the path to the public / web directory.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function publicPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->publicPath();
+        }
+                    /**
+         * Get the path to the storage directory.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function storagePath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->storagePath();
+        }
+                    /**
+         * Set the storage directory.
+         *
+         * @param string $path
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function useStoragePath($path)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->useStoragePath($path);
+        }
+                    /**
+         * Get the path to the resources directory.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function resourcePath($path = '')
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->resourcePath($path);
+        }
+                    /**
+         * Get the path to the environment file directory.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function environmentPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environmentPath();
+        }
+                    /**
+         * Set the directory for the environment file.
+         *
+         * @param string $path
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function useEnvironmentPath($path)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->useEnvironmentPath($path);
+        }
+                    /**
+         * Set the environment file to be loaded during bootstrapping.
+         *
+         * @param string $file
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function loadEnvironmentFrom($file)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->loadEnvironmentFrom($file);
+        }
+                    /**
+         * Get the environment file the application is using.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function environmentFile()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environmentFile();
+        }
+                    /**
+         * Get the fully qualified path to the environment file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function environmentFilePath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environmentFilePath();
+        }
+                    /**
+         * Get or check the current application environment.
+         *
+         * @param string|array $environments
+         * @return string|bool 
+         * @static 
+         */ 
+        public static function environment(...$environments)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->environment(...$environments);
+        }
+                    /**
+         * Determine if application is in local environment.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isLocal()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isLocal();
+        }
+                    /**
+         * Determine if application is in production environment.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isProduction()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isProduction();
+        }
+                    /**
+         * Detect the application's current environment.
+         *
+         * @param \Closure $callback
+         * @return string 
+         * @static 
+         */ 
+        public static function detectEnvironment($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->detectEnvironment($callback);
+        }
+                    /**
+         * Determine if the application is running in the console.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function runningInConsole()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->runningInConsole();
+        }
+                    /**
+         * Determine if the application is running unit tests.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function runningUnitTests()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->runningUnitTests();
+        }
+                    /**
+         * Register all of the configured providers.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function registerConfiguredProviders()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->registerConfiguredProviders();
+        }
+                    /**
+         * Register a service provider with the application.
+         *
+         * @param \Illuminate\Support\ServiceProvider|string $provider
+         * @param bool $force
+         * @return \Illuminate\Support\ServiceProvider 
+         * @static 
+         */ 
+        public static function register($provider, $force = false)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->register($provider, $force);
+        }
+                    /**
+         * Get the registered service provider instance if it exists.
+         *
+         * @param \Illuminate\Support\ServiceProvider|string $provider
+         * @return \Illuminate\Support\ServiceProvider|null 
+         * @static 
+         */ 
+        public static function getProvider($provider)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getProvider($provider);
+        }
+                    /**
+         * Get the registered service provider instances if any exist.
+         *
+         * @param \Illuminate\Support\ServiceProvider|string $provider
+         * @return array 
+         * @static 
+         */ 
+        public static function getProviders($provider)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getProviders($provider);
+        }
+                    /**
+         * Resolve a service provider instance from the class name.
+         *
+         * @param string $provider
+         * @return \Illuminate\Support\ServiceProvider 
+         * @static 
+         */ 
+        public static function resolveProvider($provider)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->resolveProvider($provider);
+        }
+                    /**
+         * Load and boot all of the remaining deferred providers.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function loadDeferredProviders()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->loadDeferredProviders();
+        }
+                    /**
+         * Load the provider for a deferred service.
+         *
+         * @param string $service
+         * @return void 
+         * @static 
+         */ 
+        public static function loadDeferredProvider($service)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->loadDeferredProvider($service);
+        }
+                    /**
+         * Register a deferred provider and service.
+         *
+         * @param string $provider
+         * @param string|null $service
+         * @return void 
+         * @static 
+         */ 
+        public static function registerDeferredProvider($provider, $service = null)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->registerDeferredProvider($provider, $service);
+        }
+                    /**
+         * Resolve the given type from the container.
+         *
+         * @param string $abstract
+         * @param array $parameters
+         * @return mixed 
+         * @static 
+         */ 
+        public static function make($abstract, $parameters = [])
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->make($abstract, $parameters);
+        }
+                    /**
+         * Determine if the given abstract type has been bound.
+         *
+         * @param string $abstract
+         * @return bool 
+         * @static 
+         */ 
+        public static function bound($abstract)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->bound($abstract);
+        }
+                    /**
+         * Determine if the application has booted.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isBooted()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isBooted();
+        }
+                    /**
+         * Boot the application's service providers.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function boot()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->boot();
+        }
+                    /**
+         * Register a new boot listener.
+         *
+         * @param callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function booting($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->booting($callback);
+        }
+                    /**
+         * Register a new "booted" listener.
+         *
+         * @param callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function booted($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->booted($callback);
+        }
+                    /**
+         * {@inheritdoc}
+         *
+         * @static 
+         */ 
+        public static function handle($request, $type = 1, $catch = true)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->handle($request, $type, $catch);
+        }
+                    /**
+         * Determine if middleware has been disabled for the application.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function shouldSkipMiddleware()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->shouldSkipMiddleware();
+        }
+                    /**
+         * Get the path to the cached services.php file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedServicesPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedServicesPath();
+        }
+                    /**
+         * Get the path to the cached packages.php file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedPackagesPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedPackagesPath();
+        }
+                    /**
+         * Determine if the application configuration is cached.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function configurationIsCached()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->configurationIsCached();
+        }
+                    /**
+         * Get the path to the configuration cache file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedConfigPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedConfigPath();
+        }
+                    /**
+         * Determine if the application routes are cached.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function routesAreCached()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->routesAreCached();
+        }
+                    /**
+         * Get the path to the routes cache file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedRoutesPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedRoutesPath();
+        }
+                    /**
+         * Determine if the application events are cached.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function eventsAreCached()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->eventsAreCached();
+        }
+                    /**
+         * Get the path to the events cache file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCachedEventsPath()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getCachedEventsPath();
+        }
+                    /**
+         * Add new prefix to list of absolute path prefixes.
+         *
+         * @param string $prefix
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function addAbsoluteCachePathPrefix($prefix)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->addAbsoluteCachePathPrefix($prefix);
+        }
+                    /**
+         * Determine if the application is currently down for maintenance.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDownForMaintenance()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isDownForMaintenance();
+        }
+                    /**
+         * Throw an HttpException with the given data.
+         *
+         * @param int $code
+         * @param string $message
+         * @param array $headers
+         * @return void 
+         * @throws \Symfony\Component\HttpKernel\Exception\HttpException
+         * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+         * @static 
+         */ 
+        public static function abort($code, $message = '', $headers = [])
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->abort($code, $message, $headers);
+        }
+                    /**
+         * Register a terminating callback with the application.
+         *
+         * @param callable|string $callback
+         * @return \Illuminate\Foundation\Application 
+         * @static 
+         */ 
+        public static function terminating($callback)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->terminating($callback);
+        }
+                    /**
+         * Terminate the application.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function terminate()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->terminate();
+        }
+                    /**
+         * Get the service providers that have been loaded.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getLoadedProviders()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getLoadedProviders();
+        }
+                    /**
+         * Determine if the given service provider is loaded.
+         *
+         * @param string $provider
+         * @return bool 
+         * @static 
+         */ 
+        public static function providerIsLoaded($provider)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->providerIsLoaded($provider);
+        }
+                    /**
+         * Get the application's deferred services.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDeferredServices()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getDeferredServices();
+        }
+                    /**
+         * Set the application's deferred services.
+         *
+         * @param array $services
+         * @return void 
+         * @static 
+         */ 
+        public static function setDeferredServices($services)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->setDeferredServices($services);
+        }
+                    /**
+         * Add an array of services to the application's deferred services.
+         *
+         * @param array $services
+         * @return void 
+         * @static 
+         */ 
+        public static function addDeferredServices($services)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->addDeferredServices($services);
+        }
+                    /**
+         * Determine if the given service is a deferred service.
+         *
+         * @param string $service
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDeferredService($service)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isDeferredService($service);
+        }
+                    /**
+         * Configure the real-time facade namespace.
+         *
+         * @param string $namespace
+         * @return void 
+         * @static 
+         */ 
+        public static function provideFacades($namespace)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->provideFacades($namespace);
+        }
+                    /**
+         * Get the current application locale.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLocale()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getLocale();
+        }
+                    /**
+         * Get the current application fallback locale.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getFallbackLocale()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getFallbackLocale();
+        }
+                    /**
+         * Set the current application locale.
+         *
+         * @param string $locale
+         * @return void 
+         * @static 
+         */ 
+        public static function setLocale($locale)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->setLocale($locale);
+        }
+                    /**
+         * Set the current application fallback locale.
+         *
+         * @param string $fallbackLocale
+         * @return void 
+         * @static 
+         */ 
+        public static function setFallbackLocale($fallbackLocale)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->setFallbackLocale($fallbackLocale);
+        }
+                    /**
+         * Determine if application locale is the given locale.
+         *
+         * @param string $locale
+         * @return bool 
+         * @static 
+         */ 
+        public static function isLocale($locale)
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isLocale($locale);
+        }
+                    /**
+         * Register the core class aliases in the container.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function registerCoreContainerAliases()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->registerCoreContainerAliases();
+        }
+                    /**
+         * Flush the container of all bindings and resolved instances.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->flush();
+        }
+                    /**
+         * Get the application namespace.
+         *
+         * @return string 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function getNamespace()
+        {
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getNamespace();
+        }
+                    /**
+         * Define a contextual binding.
+         *
+         * @param array|string $concrete
+         * @return \Illuminate\Contracts\Container\ContextualBindingBuilder 
+         * @static 
+         */ 
+        public static function when($concrete)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->when($concrete);
+        }
+                    /**
+         * Returns true if the container can return an entry for the given identifier.
+         * 
+         * Returns false otherwise.
+         * 
+         * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
+         * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
+         *
+         * @param string $id Identifier of the entry to look for.
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($id)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->has($id);
+        }
+                    /**
+         * Determine if the given abstract type has been resolved.
+         *
+         * @param string $abstract
+         * @return bool 
+         * @static 
+         */ 
+        public static function resolved($abstract)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->resolved($abstract);
+        }
+                    /**
+         * Determine if a given type is shared.
+         *
+         * @param string $abstract
+         * @return bool 
+         * @static 
+         */ 
+        public static function isShared($abstract)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isShared($abstract);
+        }
+                    /**
+         * Determine if a given string is an alias.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function isAlias($name)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->isAlias($name);
+        }
+                    /**
+         * Register a binding with the container.
+         *
+         * @param string $abstract
+         * @param \Closure|string|null $concrete
+         * @param bool $shared
+         * @return void 
+         * @static 
+         */ 
+        public static function bind($abstract, $concrete = null, $shared = false)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bind($abstract, $concrete, $shared);
+        }
+                    /**
+         * Determine if the container has a method binding.
+         *
+         * @param string $method
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMethodBinding($method)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->hasMethodBinding($method);
+        }
+                    /**
+         * Bind a callback to resolve with Container::call.
+         *
+         * @param array|string $method
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function bindMethod($method, $callback)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bindMethod($method, $callback);
+        }
+                    /**
+         * Get the method binding for the given method.
+         *
+         * @param string $method
+         * @param mixed $instance
+         * @return mixed 
+         * @static 
+         */ 
+        public static function callMethodBinding($method, $instance)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->callMethodBinding($method, $instance);
+        }
+                    /**
+         * Add a contextual binding to the container.
+         *
+         * @param string $concrete
+         * @param string $abstract
+         * @param \Closure|string $implementation
+         * @return void 
+         * @static 
+         */ 
+        public static function addContextualBinding($concrete, $abstract, $implementation)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->addContextualBinding($concrete, $abstract, $implementation);
+        }
+                    /**
+         * Register a binding if it hasn't already been registered.
+         *
+         * @param string $abstract
+         * @param \Closure|string|null $concrete
+         * @param bool $shared
+         * @return void 
+         * @static 
+         */ 
+        public static function bindIf($abstract, $concrete = null, $shared = false)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->bindIf($abstract, $concrete, $shared);
+        }
+                    /**
+         * Register a shared binding in the container.
+         *
+         * @param string $abstract
+         * @param \Closure|string|null $concrete
+         * @return void 
+         * @static 
+         */ 
+        public static function singleton($abstract, $concrete = null)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->singleton($abstract, $concrete);
+        }
+                    /**
+         * Register a shared binding if it hasn't already been registered.
+         *
+         * @param string $abstract
+         * @param \Closure|string|null $concrete
+         * @return void 
+         * @static 
+         */ 
+        public static function singletonIf($abstract, $concrete = null)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->singletonIf($abstract, $concrete);
+        }
+                    /**
+         * "Extend" an abstract type in the container.
+         *
+         * @param string $abstract
+         * @param \Closure $closure
+         * @return void 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function extend($abstract, $closure)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->extend($abstract, $closure);
+        }
+                    /**
+         * Register an existing instance as shared in the container.
+         *
+         * @param string $abstract
+         * @param mixed $instance
+         * @return mixed 
+         * @static 
+         */ 
+        public static function instance($abstract, $instance)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->instance($abstract, $instance);
+        }
+                    /**
+         * Assign a set of tags to a given binding.
+         *
+         * @param array|string $abstracts
+         * @param array|mixed $tags
+         * @return void 
+         * @static 
+         */ 
+        public static function tag($abstracts, $tags)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->tag($abstracts, $tags);
+        }
+                    /**
+         * Resolve all of the bindings for a given tag.
+         *
+         * @param string $tag
+         * @return \Illuminate\Container\iterable 
+         * @static 
+         */ 
+        public static function tagged($tag)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->tagged($tag);
+        }
+                    /**
+         * Alias a type to a different name.
+         *
+         * @param string $abstract
+         * @param string $alias
+         * @return void 
+         * @throws \LogicException
+         * @static 
+         */ 
+        public static function alias($abstract, $alias)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->alias($abstract, $alias);
+        }
+                    /**
+         * Bind a new callback to an abstract's rebind event.
+         *
+         * @param string $abstract
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function rebinding($abstract, $callback)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->rebinding($abstract, $callback);
+        }
+                    /**
+         * Refresh an instance on the given target and method.
+         *
+         * @param string $abstract
+         * @param mixed $target
+         * @param string $method
+         * @return mixed 
+         * @static 
+         */ 
+        public static function refresh($abstract, $target, $method)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->refresh($abstract, $target, $method);
+        }
+                    /**
+         * Wrap the given closure such that its dependencies will be injected when executed.
+         *
+         * @param \Closure $callback
+         * @param array $parameters
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function wrap($callback, $parameters = [])
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->wrap($callback, $parameters);
+        }
+                    /**
+         * Call the given Closure / class@method and inject its dependencies.
+         *
+         * @param callable|string $callback
+         * @param \Illuminate\Container\array<string,  mixed>  $parameters
+         * @param string|null $defaultMethod
+         * @return mixed 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function call($callback, $parameters = [], $defaultMethod = null)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->call($callback, $parameters, $defaultMethod);
+        }
+                    /**
+         * Get a closure to resolve the given type from the container.
+         *
+         * @param string $abstract
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function factory($abstract)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->factory($abstract);
+        }
+                    /**
+         * An alias function name for make().
+         *
+         * @param string $abstract
+         * @param array $parameters
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Container\BindingResolutionException
+         * @static 
+         */ 
+        public static function makeWith($abstract, $parameters = [])
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->makeWith($abstract, $parameters);
+        }
+                    /**
+         * Finds an entry of the container by its identifier and returns it.
+         *
+         * @param string $id Identifier of the entry to look for.
+         * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
+         * @throws ContainerExceptionInterface Error while retrieving the entry.
+         * @return mixed Entry.
+         * @static 
+         */ 
+        public static function get($id)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->get($id);
+        }
+                    /**
+         * Instantiate a concrete instance of the given type.
+         *
+         * @param \Closure|string $concrete
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Container\BindingResolutionException
+         * @static 
+         */ 
+        public static function build($concrete)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->build($concrete);
+        }
+                    /**
+         * Register a new resolving callback.
+         *
+         * @param \Closure|string $abstract
+         * @param \Closure|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function resolving($abstract, $callback = null)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->resolving($abstract, $callback);
+        }
+                    /**
+         * Register a new after resolving callback for all types.
+         *
+         * @param \Closure|string $abstract
+         * @param \Closure|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function afterResolving($abstract, $callback = null)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->afterResolving($abstract, $callback);
+        }
+                    /**
+         * Get the container's bindings.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getBindings()
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getBindings();
+        }
+                    /**
+         * Get the alias for an abstract if available.
+         *
+         * @param string $abstract
+         * @return string 
+         * @static 
+         */ 
+        public static function getAlias($abstract)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->getAlias($abstract);
+        }
+                    /**
+         * Remove all of the extender callbacks for a given type.
+         *
+         * @param string $abstract
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetExtenders($abstract)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->forgetExtenders($abstract);
+        }
+                    /**
+         * Remove a resolved instance from the instance cache.
+         *
+         * @param string $abstract
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetInstance($abstract)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->forgetInstance($abstract);
+        }
+                    /**
+         * Clear all of the instances from the container.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetInstances()
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->forgetInstances();
+        }
+                    /**
+         * Get the globally available instance of the container.
+         *
+         * @return static 
+         * @static 
+         */ 
+        public static function getInstance()
+        {            //Method inherited from \Illuminate\Container\Container         
+                        return \Illuminate\Foundation\Application::getInstance();
+        }
+                    /**
+         * Set the shared instance of the container.
+         *
+         * @param \Illuminate\Contracts\Container\Container|null $container
+         * @return \Illuminate\Contracts\Container\Container|static 
+         * @static 
+         */ 
+        public static function setInstance($container = null)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        return \Illuminate\Foundation\Application::setInstance($container);
+        }
+                    /**
+         * Determine if a given offset exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($key)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->offsetExists($key);
+        }
+                    /**
+         * Get the value at a given offset.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($key)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        return $instance->offsetGet($key);
+        }
+                    /**
+         * Set the value at a given offset.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($key, $value)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->offsetSet($key, $value);
+        }
+                    /**
+         * Unset the value at a given offset.
+         *
+         * @param string $key
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($key)
+        {            //Method inherited from \Illuminate\Container\Container         
+                        /** @var \Illuminate\Foundation\Application $instance */
+                        $instance->offsetUnset($key);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Console\Kernel
+     */ 
+        class Artisan {
+                    /**
+         * Run the console application.
+         *
+         * @param \Symfony\Component\Console\Input\InputInterface $input
+         * @param \Symfony\Component\Console\Output\OutputInterface|null $output
+         * @return int 
+         * @static 
+         */ 
+        public static function handle($input, $output = null)
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->handle($input, $output);
+        }
+                    /**
+         * Terminate the application.
+         *
+         * @param \Symfony\Component\Console\Input\InputInterface $input
+         * @param int $status
+         * @return void 
+         * @static 
+         */ 
+        public static function terminate($input, $status)
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->terminate($input, $status);
+        }
+                    /**
+         * Register a Closure based command with the application.
+         *
+         * @param string $signature
+         * @param \Closure $callback
+         * @return \Illuminate\Foundation\Console\ClosureCommand 
+         * @static 
+         */ 
+        public static function command($signature, $callback)
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->command($signature, $callback);
+        }
+                    /**
+         * Register the given command with the console application.
+         *
+         * @param \Symfony\Component\Console\Command\Command $command
+         * @return void 
+         * @static 
+         */ 
+        public static function registerCommand($command)
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->registerCommand($command);
+        }
+                    /**
+         * Run an Artisan console command by name.
+         *
+         * @param string $command
+         * @param array $parameters
+         * @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
+         * @return int 
+         * @throws \Symfony\Component\Console\Exception\CommandNotFoundException
+         * @static 
+         */ 
+        public static function call($command, $parameters = [], $outputBuffer = null)
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->call($command, $parameters, $outputBuffer);
+        }
+                    /**
+         * Queue the given console command.
+         *
+         * @param string $command
+         * @param array $parameters
+         * @return \Illuminate\Foundation\Bus\PendingDispatch 
+         * @static 
+         */ 
+        public static function queue($command, $parameters = [])
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->queue($command, $parameters);
+        }
+                    /**
+         * Get all of the commands registered with the console.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function all()
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->all();
+        }
+                    /**
+         * Get the output for the last run command.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function output()
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        return $instance->output();
+        }
+                    /**
+         * Bootstrap the application for artisan commands.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function bootstrap()
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->bootstrap();
+        }
+                    /**
+         * Set the Artisan application instance.
+         *
+         * @param \Illuminate\Console\Application $artisan
+         * @return void 
+         * @static 
+         */ 
+        public static function setArtisan($artisan)
+        {            //Method inherited from \Illuminate\Foundation\Console\Kernel         
+                        /** @var \App\Console\Kernel $instance */
+                        $instance->setArtisan($artisan);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Auth\AuthManager
+     * @see \Illuminate\Contracts\Auth\Factory
+     * @see \Illuminate\Contracts\Auth\Guard
+     * @see \Illuminate\Contracts\Auth\StatefulGuard
+     */ 
+        class Auth {
+                    /**
+         * Attempt to get the guard from the local cache.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Contracts\Auth\Guard|\Illuminate\Contracts\Auth\StatefulGuard 
+         * @static 
+         */ 
+        public static function guard($name = null)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->guard($name);
+        }
+                    /**
+         * Create a session based authentication guard.
+         *
+         * @param string $name
+         * @param array $config
+         * @return \Illuminate\Auth\SessionGuard 
+         * @static 
+         */ 
+        public static function createSessionDriver($name, $config)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->createSessionDriver($name, $config);
+        }
+                    /**
+         * Create a token based authentication guard.
+         *
+         * @param string $name
+         * @param array $config
+         * @return \Illuminate\Auth\TokenGuard 
+         * @static 
+         */ 
+        public static function createTokenDriver($name, $config)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->createTokenDriver($name, $config);
+        }
+                    /**
+         * Get the default authentication driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the default guard driver the factory should serve.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function shouldUse($name)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        $instance->shouldUse($name);
+        }
+                    /**
+         * Set the default authentication driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+                    /**
+         * Register a new callback based request guard.
+         *
+         * @param string $driver
+         * @param callable $callback
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function viaRequest($driver, $callback)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->viaRequest($driver, $callback);
+        }
+                    /**
+         * Get the user resolver callback.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function userResolver()
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->userResolver();
+        }
+                    /**
+         * Set the callback to be used to resolve users.
+         *
+         * @param \Closure $userResolver
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function resolveUsersUsing($userResolver)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->resolveUsersUsing($userResolver);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Register a custom provider creator Closure.
+         *
+         * @param string $name
+         * @param \Closure $callback
+         * @return \Illuminate\Auth\AuthManager 
+         * @static 
+         */ 
+        public static function provider($name, $callback)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->provider($name, $callback);
+        }
+                    /**
+         * Determines if any guards have already been resolved.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasResolvedGuards()
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->hasResolvedGuards();
+        }
+                    /**
+         * Create the user provider implementation for the driver.
+         *
+         * @param string|null $provider
+         * @return \Illuminate\Contracts\Auth\UserProvider|null 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function createUserProvider($provider = null)
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->createUserProvider($provider);
+        }
+                    /**
+         * Get the default user provider name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultUserProvider()
+        {
+                        /** @var \Illuminate\Auth\AuthManager $instance */
+                        return $instance->getDefaultUserProvider();
+        }
+                    /**
+         * Get the currently authenticated user.
+         *
+         * @return \App\User|null 
+         * @static 
+         */ 
+        public static function user()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->user();
+        }
+                    /**
+         * Get the ID for the currently authenticated user.
+         *
+         * @return int|string|null 
+         * @static 
+         */ 
+        public static function id()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->id();
+        }
+                    /**
+         * Log a user into the application without sessions or cookies.
+         *
+         * @param array $credentials
+         * @return bool 
+         * @static 
+         */ 
+        public static function once($credentials = [])
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->once($credentials);
+        }
+                    /**
+         * Log the given user ID into the application without sessions or cookies.
+         *
+         * @param mixed $id
+         * @return \App\User|false 
+         * @static 
+         */ 
+        public static function onceUsingId($id)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->onceUsingId($id);
+        }
+                    /**
+         * Validate a user's credentials.
+         *
+         * @param array $credentials
+         * @return bool 
+         * @static 
+         */ 
+        public static function validate($credentials = [])
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->validate($credentials);
+        }
+                    /**
+         * Attempt to authenticate using HTTP Basic Auth.
+         *
+         * @param string $field
+         * @param array $extraConditions
+         * @return \Symfony\Component\HttpFoundation\Response|null 
+         * @static 
+         */ 
+        public static function basic($field = 'email', $extraConditions = [])
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->basic($field, $extraConditions);
+        }
+                    /**
+         * Perform a stateless HTTP Basic login attempt.
+         *
+         * @param string $field
+         * @param array $extraConditions
+         * @return \Symfony\Component\HttpFoundation\Response|null 
+         * @static 
+         */ 
+        public static function onceBasic($field = 'email', $extraConditions = [])
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->onceBasic($field, $extraConditions);
+        }
+                    /**
+         * Attempt to authenticate a user using the given credentials.
+         *
+         * @param array $credentials
+         * @param bool $remember
+         * @return bool 
+         * @static 
+         */ 
+        public static function attempt($credentials = [], $remember = false)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->attempt($credentials, $remember);
+        }
+                    /**
+         * Log the given user ID into the application.
+         *
+         * @param mixed $id
+         * @param bool $remember
+         * @return \App\User|false 
+         * @static 
+         */ 
+        public static function loginUsingId($id, $remember = false)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->loginUsingId($id, $remember);
+        }
+                    /**
+         * Log a user into the application.
+         *
+         * @param \Illuminate\Contracts\Auth\Authenticatable $user
+         * @param bool $remember
+         * @return void 
+         * @static 
+         */ 
+        public static function login($user, $remember = false)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->login($user, $remember);
+        }
+                    /**
+         * Log the user out of the application.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function logout()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->logout();
+        }
+                    /**
+         * Log the user out of the application on their current device only.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function logoutCurrentDevice()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->logoutCurrentDevice();
+        }
+                    /**
+         * Invalidate other sessions for the current user.
+         * 
+         * The application must be using the AuthenticateSession middleware.
+         *
+         * @param string $password
+         * @param string $attribute
+         * @return bool|null 
+         * @static 
+         */ 
+        public static function logoutOtherDevices($password, $attribute = 'password')
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->logoutOtherDevices($password, $attribute);
+        }
+                    /**
+         * Register an authentication attempt event listener.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function attempting($callback)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->attempting($callback);
+        }
+                    /**
+         * Get the last user we attempted to authenticate.
+         *
+         * @return \App\User 
+         * @static 
+         */ 
+        public static function getLastAttempted()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getLastAttempted();
+        }
+                    /**
+         * Get a unique identifier for the auth session value.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getName()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getName();
+        }
+                    /**
+         * Get the name of the cookie used to store the "recaller".
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getRecallerName()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getRecallerName();
+        }
+                    /**
+         * Determine if the user was authenticated via "remember me" cookie.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function viaRemember()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->viaRemember();
+        }
+                    /**
+         * Get the cookie creator instance used by the guard.
+         *
+         * @return \Illuminate\Contracts\Cookie\QueueingFactory 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function getCookieJar()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getCookieJar();
+        }
+                    /**
+         * Set the cookie creator instance used by the guard.
+         *
+         * @param \Illuminate\Contracts\Cookie\QueueingFactory $cookie
+         * @return void 
+         * @static 
+         */ 
+        public static function setCookieJar($cookie)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->setCookieJar($cookie);
+        }
+                    /**
+         * Get the event dispatcher instance.
+         *
+         * @return \Illuminate\Contracts\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function getDispatcher()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getDispatcher();
+        }
+                    /**
+         * Set the event dispatcher instance.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return void 
+         * @static 
+         */ 
+        public static function setDispatcher($events)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->setDispatcher($events);
+        }
+                    /**
+         * Get the session store used by the guard.
+         *
+         * @return \Illuminate\Contracts\Session\Session 
+         * @static 
+         */ 
+        public static function getSession()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getSession();
+        }
+                    /**
+         * Return the currently cached user.
+         *
+         * @return \App\User|null 
+         * @static 
+         */ 
+        public static function getUser()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getUser();
+        }
+                    /**
+         * Set the current user.
+         *
+         * @param \Illuminate\Contracts\Auth\Authenticatable $user
+         * @return \Illuminate\Auth\SessionGuard 
+         * @static 
+         */ 
+        public static function setUser($user)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->setUser($user);
+        }
+                    /**
+         * Get the current request instance.
+         *
+         * @return \Symfony\Component\HttpFoundation\Request 
+         * @static 
+         */ 
+        public static function getRequest()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getRequest();
+        }
+                    /**
+         * Set the current request instance.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @return \Illuminate\Auth\SessionGuard 
+         * @static 
+         */ 
+        public static function setRequest($request)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->setRequest($request);
+        }
+                    /**
+         * Determine if current user is authenticated. If not, throw an exception.
+         *
+         * @return \App\User 
+         * @throws \Illuminate\Auth\AuthenticationException
+         * @static 
+         */ 
+        public static function authenticate()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->authenticate();
+        }
+                    /**
+         * Determine if the guard has a user instance.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasUser()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->hasUser();
+        }
+                    /**
+         * Determine if the current user is authenticated.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function check()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->check();
+        }
+                    /**
+         * Determine if the current user is a guest.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function guest()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->guest();
+        }
+                    /**
+         * Get the user provider used by the guard.
+         *
+         * @return \Illuminate\Contracts\Auth\UserProvider 
+         * @static 
+         */ 
+        public static function getProvider()
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        return $instance->getProvider();
+        }
+                    /**
+         * Set the user provider used by the guard.
+         *
+         * @param \Illuminate\Contracts\Auth\UserProvider $provider
+         * @return void 
+         * @static 
+         */ 
+        public static function setProvider($provider)
+        {
+                        /** @var \Illuminate\Auth\SessionGuard $instance */
+                        $instance->setProvider($provider);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Auth\SessionGuard::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Auth\SessionGuard::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Auth\SessionGuard::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\View\Compilers\BladeCompiler
+     */ 
+        class Blade {
+                    /**
+         * Compile the view at the given path.
+         *
+         * @param string|null $path
+         * @return void 
+         * @static 
+         */ 
+        public static function compile($path = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->compile($path);
+        }
+                    /**
+         * Get the path currently being compiled.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getPath()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getPath();
+        }
+                    /**
+         * Set the path currently being compiled.
+         *
+         * @param string $path
+         * @return void 
+         * @static 
+         */ 
+        public static function setPath($path)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->setPath($path);
+        }
+                    /**
+         * Compile the given Blade template contents.
+         *
+         * @param string $value
+         * @return string 
+         * @static 
+         */ 
+        public static function compileString($value)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->compileString($value);
+        }
+                    /**
+         * Strip the parentheses from the given expression.
+         *
+         * @param string $expression
+         * @return string 
+         * @static 
+         */ 
+        public static function stripParentheses($expression)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->stripParentheses($expression);
+        }
+                    /**
+         * Register a custom Blade compiler.
+         *
+         * @param callable $compiler
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($compiler)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->extend($compiler);
+        }
+                    /**
+         * Get the extensions used by the compiler.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getExtensions()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getExtensions();
+        }
+                    /**
+         * Register an "if" statement directive.
+         *
+         * @param string $name
+         * @param callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function if($name, $callback)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->if($name, $callback);
+        }
+                    /**
+         * Check the result of a condition.
+         *
+         * @param string $name
+         * @param array $parameters
+         * @return bool 
+         * @static 
+         */ 
+        public static function check($name, ...$parameters)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->check($name, ...$parameters);
+        }
+                    /**
+         * Register a class-based component alias directive.
+         *
+         * @param string $class
+         * @param string|null $alias
+         * @param string $prefix
+         * @return void 
+         * @static 
+         */ 
+        public static function component($class, $alias = null, $prefix = '')
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->component($class, $alias, $prefix);
+        }
+                    /**
+         * Register an array of class-based components.
+         *
+         * @param array $components
+         * @param string $prefix
+         * @return void 
+         * @static 
+         */ 
+        public static function components($components, $prefix = '')
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->components($components, $prefix);
+        }
+                    /**
+         * Get the registered class component aliases.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getClassComponentAliases()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getClassComponentAliases();
+        }
+                    /**
+         * Register a component alias directive.
+         *
+         * @param string $path
+         * @param string|null $alias
+         * @return void 
+         * @static 
+         */ 
+        public static function aliasComponent($path, $alias = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->aliasComponent($path, $alias);
+        }
+                    /**
+         * Register an include alias directive.
+         *
+         * @param string $path
+         * @param string|null $alias
+         * @return void 
+         * @static 
+         */ 
+        public static function include($path, $alias = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->include($path, $alias);
+        }
+                    /**
+         * Register an include alias directive.
+         *
+         * @param string $path
+         * @param string|null $alias
+         * @return void 
+         * @static 
+         */ 
+        public static function aliasInclude($path, $alias = null)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->aliasInclude($path, $alias);
+        }
+                    /**
+         * Register a handler for custom directives.
+         *
+         * @param string $name
+         * @param callable $handler
+         * @return void 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function directive($name, $handler)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->directive($name, $handler);
+        }
+                    /**
+         * Get the list of custom directives.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getCustomDirectives()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getCustomDirectives();
+        }
+                    /**
+         * Register a new precompiler.
+         *
+         * @param callable $precompiler
+         * @return void 
+         * @static 
+         */ 
+        public static function precompiler($precompiler)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->precompiler($precompiler);
+        }
+                    /**
+         * Set the echo format to be used by the compiler.
+         *
+         * @param string $format
+         * @return void 
+         * @static 
+         */ 
+        public static function setEchoFormat($format)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->setEchoFormat($format);
+        }
+                    /**
+         * Set the "echo" format to double encode entities.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function withDoubleEncoding()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->withDoubleEncoding();
+        }
+                    /**
+         * Set the "echo" format to not double encode entities.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function withoutDoubleEncoding()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->withoutDoubleEncoding();
+        }
+                    /**
+         * Indicate that component tags should not be compiled.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function withoutComponentTags()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        $instance->withoutComponentTags();
+        }
+                    /**
+         * Get the path to the compiled version of a view.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function getCompiledPath($path)
+        {            //Method inherited from \Illuminate\View\Compilers\Compiler         
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->getCompiledPath($path);
+        }
+                    /**
+         * Determine if the view at the given path is expired.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isExpired($path)
+        {            //Method inherited from \Illuminate\View\Compilers\Compiler         
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->isExpired($path);
+        }
+                    /**
+         * Get a new component hash for a component name.
+         *
+         * @param string $component
+         * @return string 
+         * @static 
+         */ 
+        public static function newComponentHash($component)
+        {
+                        return \Illuminate\View\Compilers\BladeCompiler::newComponentHash($component);
+        }
+                    /**
+         * Compile a class component opening.
+         *
+         * @param string $component
+         * @param string $alias
+         * @param string $data
+         * @param string $hash
+         * @return string 
+         * @static 
+         */ 
+        public static function compileClassComponentOpening($component, $alias, $data, $hash)
+        {
+                        return \Illuminate\View\Compilers\BladeCompiler::compileClassComponentOpening($component, $alias, $data, $hash);
+        }
+                    /**
+         * Compile the end-component statements into valid PHP.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function compileEndComponentClass()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->compileEndComponentClass();
+        }
+                    /**
+         * Sanitize the given component attribute value.
+         *
+         * @param mixed $value
+         * @return mixed 
+         * @static 
+         */ 
+        public static function sanitizeComponentAttribute($value)
+        {
+                        return \Illuminate\View\Compilers\BladeCompiler::sanitizeComponentAttribute($value);
+        }
+                    /**
+         * Compile an end-once block into valid PHP.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function compileEndOnce()
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->compileEndOnce();
+        }
+                    /**
+         * Compile Blade echos into valid PHP.
+         *
+         * @param string $value
+         * @return string 
+         * @static 
+         */ 
+        public static function compileEchos($value)
+        {
+                        /** @var \Illuminate\View\Compilers\BladeCompiler $instance */
+                        return $instance->compileEchos($value);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @method static \Illuminate\Broadcasting\Broadcasters\Broadcaster channel(string $channel, callable|string  $callback, array $options = [])
+     * @method static mixed auth(\Illuminate\Http\Request $request)
+     * @see \Illuminate\Contracts\Broadcasting\Factory
+     */ 
+        class Broadcast {
+                    /**
+         * Register the routes for handling broadcast authentication and sockets.
+         *
+         * @param array|null $attributes
+         * @return void 
+         * @static 
+         */ 
+        public static function routes($attributes = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        $instance->routes($attributes);
+        }
+                    /**
+         * Get the socket ID for the given request.
+         *
+         * @param \Illuminate\Http\Request|null $request
+         * @return string|null 
+         * @static 
+         */ 
+        public static function socket($request = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->socket($request);
+        }
+                    /**
+         * Begin broadcasting an event.
+         *
+         * @param mixed|null $event
+         * @return \Illuminate\Broadcasting\PendingBroadcast|void 
+         * @static 
+         */ 
+        public static function event($event = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->event($event);
+        }
+                    /**
+         * Queue the given event for broadcast.
+         *
+         * @param mixed $event
+         * @return void 
+         * @static 
+         */ 
+        public static function queue($event)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        $instance->queue($event);
+        }
+                    /**
+         * Get a driver instance.
+         *
+         * @param string|null $driver
+         * @return mixed 
+         * @static 
+         */ 
+        public static function connection($driver = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->connection($driver);
+        }
+                    /**
+         * Get a driver instance.
+         *
+         * @param string|null $name
+         * @return mixed 
+         * @static 
+         */ 
+        public static function driver($name = null)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->driver($name);
+        }
+                    /**
+         * Get the default driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the default driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Broadcasting\BroadcastManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Broadcasting\BroadcastManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Bus\Dispatcher
+     */ 
+        class Bus {
+                    /**
+         * Dispatch a command to its appropriate handler.
+         *
+         * @param mixed $command
+         * @return mixed 
+         * @static 
+         */ 
+        public static function dispatch($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->dispatch($command);
+        }
+                    /**
+         * Dispatch a command to its appropriate handler in the current process.
+         *
+         * @param mixed $command
+         * @param mixed $handler
+         * @return mixed 
+         * @static 
+         */ 
+        public static function dispatchNow($command, $handler = null)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->dispatchNow($command, $handler);
+        }
+                    /**
+         * Determine if the given command has a handler.
+         *
+         * @param mixed $command
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasCommandHandler($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->hasCommandHandler($command);
+        }
+                    /**
+         * Retrieve the handler for a command.
+         *
+         * @param mixed $command
+         * @return bool|mixed 
+         * @static 
+         */ 
+        public static function getCommandHandler($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->getCommandHandler($command);
+        }
+                    /**
+         * Dispatch a command to its appropriate handler behind a queue.
+         *
+         * @param mixed $command
+         * @return mixed 
+         * @static 
+         */ 
+        public static function dispatchToQueue($command)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->dispatchToQueue($command);
+        }
+                    /**
+         * Dispatch a command to its appropriate handler after the current process.
+         *
+         * @param mixed $command
+         * @param mixed $handler
+         * @return void 
+         * @static 
+         */ 
+        public static function dispatchAfterResponse($command, $handler = null)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        $instance->dispatchAfterResponse($command, $handler);
+        }
+                    /**
+         * Set the pipes through which commands should be piped before dispatching.
+         *
+         * @param array $pipes
+         * @return \Illuminate\Bus\Dispatcher 
+         * @static 
+         */ 
+        public static function pipeThrough($pipes)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->pipeThrough($pipes);
+        }
+                    /**
+         * Map a command to a handler.
+         *
+         * @param array $map
+         * @return \Illuminate\Bus\Dispatcher 
+         * @static 
+         */ 
+        public static function map($map)
+        {
+                        /** @var \Illuminate\Bus\Dispatcher $instance */
+                        return $instance->map($map);
+        }
+                    /**
+         * Assert if a job was dispatched based on a truth-test callback.
+         *
+         * @param string|\Closure $command
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatched($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertDispatched($command, $callback);
+        }
+                    /**
+         * Assert if a job was pushed a number of times.
+         *
+         * @param string $command
+         * @param int $times
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatchedTimes($command, $times = 1)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertDispatchedTimes($command, $times);
+        }
+                    /**
+         * Determine if a job was dispatched based on a truth-test callback.
+         *
+         * @param string|\Closure $command
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotDispatched($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertNotDispatched($command, $callback);
+        }
+                    /**
+         * Assert if a job was dispatched after the response was sent based on a truth-test callback.
+         *
+         * @param string|\Closure $command
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatchedAfterResponse($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertDispatchedAfterResponse($command, $callback);
+        }
+                    /**
+         * Assert if a job was pushed after the response was sent a number of times.
+         *
+         * @param string $command
+         * @param int $times
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatchedAfterResponseTimes($command, $times = 1)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertDispatchedAfterResponseTimes($command, $times);
+        }
+                    /**
+         * Determine if a job was dispatched based on a truth-test callback.
+         *
+         * @param string|\Closure $command
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotDispatchedAfterResponse($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        $instance->assertNotDispatchedAfterResponse($command, $callback);
+        }
+                    /**
+         * Get all of the jobs matching a truth-test callback.
+         *
+         * @param string $command
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function dispatched($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        return $instance->dispatched($command, $callback);
+        }
+                    /**
+         * Get all of the jobs dispatched after the response was sent matching a truth-test callback.
+         *
+         * @param string $command
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function dispatchedAfterResponse($command, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        return $instance->dispatchedAfterResponse($command, $callback);
+        }
+                    /**
+         * Determine if there are any stored commands for a given class.
+         *
+         * @param string $command
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasDispatched($command)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        return $instance->hasDispatched($command);
+        }
+                    /**
+         * Determine if there are any stored commands for a given class.
+         *
+         * @param string $command
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasDispatchedAfterResponse($command)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
+                        return $instance->hasDispatchedAfterResponse($command);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @method static \Illuminate\Contracts\Cache\Lock lock(string $name, int $seconds = 0, mixed $owner = null)
+     * @method static \Illuminate\Contracts\Cache\Lock restoreLock(string $name, string $owner)
+     * @see \Illuminate\Cache\CacheManager
+     * @see \Illuminate\Cache\Repository
+     */ 
+        class Cache {
+                    /**
+         * Get a cache store instance by name, wrapped in a repository.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Contracts\Cache\Repository 
+         * @static 
+         */ 
+        public static function store($name = null)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->store($name);
+        }
+                    /**
+         * Get a cache driver instance.
+         *
+         * @param string|null $driver
+         * @return \Illuminate\Contracts\Cache\Repository 
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->driver($driver);
+        }
+                    /**
+         * Create a new cache repository with the given implementation.
+         *
+         * @param \Illuminate\Contracts\Cache\Store $store
+         * @return \Illuminate\Cache\Repository 
+         * @static 
+         */ 
+        public static function repository($store)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->repository($store);
+        }
+                    /**
+         * Re-set the event dispatcher on all resolved cache repositories.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function refreshEventDispatcher()
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        $instance->refreshEventDispatcher();
+        }
+                    /**
+         * Get the default cache driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the default cache driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+                    /**
+         * Unset the given driver instances.
+         *
+         * @param array|string|null $name
+         * @return \Illuminate\Cache\CacheManager 
+         * @static 
+         */ 
+        public static function forgetDriver($name = null)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->forgetDriver($name);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Cache\CacheManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Cache\CacheManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Determine if an item exists in the cache.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->has($key);
+        }
+                    /**
+         * Determine if an item doesn't exist in the cache.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function missing($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->missing($key);
+        }
+                    /**
+         * Retrieve an item from the cache by key.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->get($key, $default);
+        }
+                    /**
+         * Retrieve multiple items from the cache by key.
+         * 
+         * Items not found in the cache will have a null value.
+         *
+         * @param array $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function many($keys)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->many($keys);
+        }
+                    /**
+         * Obtains multiple cache items by their unique keys.
+         *
+         * @param \Psr\SimpleCache\iterable $keys A list of keys that can obtained in a single operation.
+         * @param mixed $default Default value to return for keys that do not exist.
+         * @return \Psr\SimpleCache\iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if $keys is neither an array nor a Traversable,
+         *   or if any of the $keys are not a legal value.
+         * @static 
+         */ 
+        public static function getMultiple($keys, $default = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->getMultiple($keys, $default);
+        }
+                    /**
+         * Retrieve an item from the cache and delete it.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pull($key, $default = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->pull($key, $default);
+        }
+                    /**
+         * Store an item in the cache.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @param \DateTimeInterface|\DateInterval|int|null $ttl
+         * @return bool 
+         * @static 
+         */ 
+        public static function put($key, $value, $ttl = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->put($key, $value, $ttl);
+        }
+                    /**
+         * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
+         *
+         * @param string $key The key of the item to store.
+         * @param mixed $value The value of the item to store, must be serializable.
+         * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
+         *                                      the driver supports TTL then the library may set a default value
+         *                                      for it or let the driver take care of that.
+         * @return bool True on success and false on failure.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if the $key string is not a legal value.
+         * @static 
+         */ 
+        public static function set($key, $value, $ttl = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->set($key, $value, $ttl);
+        }
+                    /**
+         * Store multiple items in the cache for a given number of seconds.
+         *
+         * @param array $values
+         * @param \DateTimeInterface|\DateInterval|int|null $ttl
+         * @return bool 
+         * @static 
+         */ 
+        public static function putMany($values, $ttl = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->putMany($values, $ttl);
+        }
+                    /**
+         * Persists a set of key => value pairs in the cache, with an optional TTL.
+         *
+         * @param \Psr\SimpleCache\iterable $values A list of key => value pairs for a multiple-set operation.
+         * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
+         *                                       the driver supports TTL then the library may set a default value
+         *                                       for it or let the driver take care of that.
+         * @return bool True on success and false on failure.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if $values is neither an array nor a Traversable,
+         *   or if any of the $values are not a legal value.
+         * @static 
+         */ 
+        public static function setMultiple($values, $ttl = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->setMultiple($values, $ttl);
+        }
+                    /**
+         * Store an item in the cache if the key does not exist.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @param \DateTimeInterface|\DateInterval|int|null $ttl
+         * @return bool 
+         * @static 
+         */ 
+        public static function add($key, $value, $ttl = null)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->add($key, $value, $ttl);
+        }
+                    /**
+         * Increment the value of an item in the cache.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return int|bool 
+         * @static 
+         */ 
+        public static function increment($key, $value = 1)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->increment($key, $value);
+        }
+                    /**
+         * Decrement the value of an item in the cache.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return int|bool 
+         * @static 
+         */ 
+        public static function decrement($key, $value = 1)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->decrement($key, $value);
+        }
+                    /**
+         * Store an item in the cache indefinitely.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return bool 
+         * @static 
+         */ 
+        public static function forever($key, $value)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->forever($key, $value);
+        }
+                    /**
+         * Get an item from the cache, or execute the given Closure and store the result.
+         *
+         * @param string $key
+         * @param \DateTimeInterface|\DateInterval|int|null $ttl
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function remember($key, $ttl, $callback)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->remember($key, $ttl, $callback);
+        }
+                    /**
+         * Get an item from the cache, or execute the given Closure and store the result forever.
+         *
+         * @param string $key
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function sear($key, $callback)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->sear($key, $callback);
+        }
+                    /**
+         * Get an item from the cache, or execute the given Closure and store the result forever.
+         *
+         * @param string $key
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function rememberForever($key, $callback)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->rememberForever($key, $callback);
+        }
+                    /**
+         * Remove an item from the cache.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function forget($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->forget($key);
+        }
+                    /**
+         * Delete an item from the cache by its unique key.
+         *
+         * @param string $key The unique cache key of the item to delete.
+         * @return bool True if the item was successfully removed. False if there was an error.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if the $key string is not a legal value.
+         * @static 
+         */ 
+        public static function delete($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->delete($key);
+        }
+                    /**
+         * Deletes multiple cache items in a single operation.
+         *
+         * @param \Psr\SimpleCache\iterable $keys A list of string-based keys to be deleted.
+         * @return bool True if the items were successfully removed. False if there was an error.
+         * @throws \Psr\SimpleCache\InvalidArgumentException
+         *   MUST be thrown if $keys is neither an array nor a Traversable,
+         *   or if any of the $keys are not a legal value.
+         * @static 
+         */ 
+        public static function deleteMultiple($keys)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->deleteMultiple($keys);
+        }
+                    /**
+         * Wipes clean the entire cache's keys.
+         *
+         * @return bool True on success and false on failure.
+         * @static 
+         */ 
+        public static function clear()
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->clear();
+        }
+                    /**
+         * Begin executing a new tags operation if the store supports it.
+         *
+         * @param array|mixed $names
+         * @return \Illuminate\Cache\TaggedCache 
+         * @throws \BadMethodCallException
+         * @static 
+         */ 
+        public static function tags($names)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->tags($names);
+        }
+                    /**
+         * Get the default cache time.
+         *
+         * @return int|null 
+         * @static 
+         */ 
+        public static function getDefaultCacheTime()
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->getDefaultCacheTime();
+        }
+                    /**
+         * Set the default cache time in seconds.
+         *
+         * @param int|null $seconds
+         * @return \Illuminate\Cache\Repository 
+         * @static 
+         */ 
+        public static function setDefaultCacheTime($seconds)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->setDefaultCacheTime($seconds);
+        }
+                    /**
+         * Get the cache store implementation.
+         *
+         * @return \Illuminate\Contracts\Cache\Store 
+         * @static 
+         */ 
+        public static function getStore()
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->getStore();
+        }
+                    /**
+         * Get the event dispatcher instance.
+         *
+         * @return \Illuminate\Contracts\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function getEventDispatcher()
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->getEventDispatcher();
+        }
+                    /**
+         * Set the event dispatcher instance.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return void 
+         * @static 
+         */ 
+        public static function setEventDispatcher($events)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->setEventDispatcher($events);
+        }
+                    /**
+         * Determine if a cached value exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->offsetExists($key);
+        }
+                    /**
+         * Retrieve an item from the cache by key.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->offsetGet($key);
+        }
+                    /**
+         * Store an item in the cache for the default time.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($key, $value)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->offsetSet($key, $value);
+        }
+                    /**
+         * Remove an item from the cache.
+         *
+         * @param string $key
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($key)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        $instance->offsetUnset($key);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Cache\Repository::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Cache\Repository::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Cache\Repository::hasMacro($name);
+        }
+                    /**
+         * Dynamically handle calls to the class.
+         *
+         * @param string $method
+         * @param array $parameters
+         * @return mixed 
+         * @throws \BadMethodCallException
+         * @static 
+         */ 
+        public static function macroCall($method, $parameters)
+        {
+                        /** @var \Illuminate\Cache\Repository $instance */
+                        return $instance->macroCall($method, $parameters);
+        }
+                    /**
+         * Remove all items from the cache.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->flush();
+        }
+                    /**
+         * Get the Filesystem instance.
+         *
+         * @return \Illuminate\Filesystem\Filesystem 
+         * @static 
+         */ 
+        public static function getFilesystem()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->getFilesystem();
+        }
+                    /**
+         * Get the working directory of the cache.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDirectory()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->getDirectory();
+        }
+                    /**
+         * Get the cache key prefix.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getPrefix()
+        {
+                        /** @var \Illuminate\Cache\FileStore $instance */
+                        return $instance->getPrefix();
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Config\Repository
+     */ 
+        class Config {
+                    /**
+         * Determine if the given configuration value exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->has($key);
+        }
+                    /**
+         * Get the specified configuration value.
+         *
+         * @param array|string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->get($key, $default);
+        }
+                    /**
+         * Get many configuration values.
+         *
+         * @param array $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function getMany($keys)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->getMany($keys);
+        }
+                    /**
+         * Set a given configuration value.
+         *
+         * @param array|string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function set($key, $value = null)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->set($key, $value);
+        }
+                    /**
+         * Prepend a value onto an array configuration value.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function prepend($key, $value)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->prepend($key, $value);
+        }
+                    /**
+         * Push a value onto an array configuration value.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function push($key, $value)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->push($key, $value);
+        }
+                    /**
+         * Get all of the configuration items for the application.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function all()
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->all();
+        }
+                    /**
+         * Determine if the given configuration option exists.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->offsetExists($key);
+        }
+                    /**
+         * Get a configuration option.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        return $instance->offsetGet($key);
+        }
+                    /**
+         * Set a configuration option.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($key, $value)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->offsetSet($key, $value);
+        }
+                    /**
+         * Unset a configuration option.
+         *
+         * @param string $key
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($key)
+        {
+                        /** @var \Illuminate\Config\Repository $instance */
+                        $instance->offsetUnset($key);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Cookie\CookieJar
+     */ 
+        class Cookie {
+                    /**
+         * Create a new cookie instance.
+         *
+         * @param string $name
+         * @param string $value
+         * @param int $minutes
+         * @param string|null $path
+         * @param string|null $domain
+         * @param bool|null $secure
+         * @param bool $httpOnly
+         * @param bool $raw
+         * @param string|null $sameSite
+         * @return \Symfony\Component\HttpFoundation\Cookie 
+         * @static 
+         */ 
+        public static function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->make($name, $value, $minutes, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
+        }
+                    /**
+         * Create a cookie that lasts "forever" (five years).
+         *
+         * @param string $name
+         * @param string $value
+         * @param string|null $path
+         * @param string|null $domain
+         * @param bool|null $secure
+         * @param bool $httpOnly
+         * @param bool $raw
+         * @param string|null $sameSite
+         * @return \Symfony\Component\HttpFoundation\Cookie 
+         * @static 
+         */ 
+        public static function forever($name, $value, $path = null, $domain = null, $secure = null, $httpOnly = true, $raw = false, $sameSite = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->forever($name, $value, $path, $domain, $secure, $httpOnly, $raw, $sameSite);
+        }
+                    /**
+         * Expire the given cookie.
+         *
+         * @param string $name
+         * @param string|null $path
+         * @param string|null $domain
+         * @return \Symfony\Component\HttpFoundation\Cookie 
+         * @static 
+         */ 
+        public static function forget($name, $path = null, $domain = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->forget($name, $path, $domain);
+        }
+                    /**
+         * Determine if a cookie has been queued.
+         *
+         * @param string $key
+         * @param string|null $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasQueued($key, $path = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->hasQueued($key, $path);
+        }
+                    /**
+         * Get a queued cookie instance.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @param string|null $path
+         * @return \Symfony\Component\HttpFoundation\Cookie|null 
+         * @static 
+         */ 
+        public static function queued($key, $default = null, $path = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->queued($key, $default, $path);
+        }
+                    /**
+         * Queue a cookie to send with the next response.
+         *
+         * @param array $parameters
+         * @return void 
+         * @static 
+         */ 
+        public static function queue(...$parameters)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        $instance->queue(...$parameters);
+        }
+                    /**
+         * Remove a cookie from the queue.
+         *
+         * @param string $name
+         * @param string|null $path
+         * @return void 
+         * @static 
+         */ 
+        public static function unqueue($name, $path = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        $instance->unqueue($name, $path);
+        }
+                    /**
+         * Set the default path and domain for the jar.
+         *
+         * @param string $path
+         * @param string $domain
+         * @param bool $secure
+         * @param string|null $sameSite
+         * @return \Illuminate\Cookie\CookieJar 
+         * @static 
+         */ 
+        public static function setDefaultPathAndDomain($path, $domain, $secure = false, $sameSite = null)
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->setDefaultPathAndDomain($path, $domain, $secure, $sameSite);
+        }
+                    /**
+         * Get the cookies which have been queued for the next request.
+         *
+         * @return \Symfony\Component\HttpFoundation\Cookie[] 
+         * @static 
+         */ 
+        public static function getQueuedCookies()
+        {
+                        /** @var \Illuminate\Cookie\CookieJar $instance */
+                        return $instance->getQueuedCookies();
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Cookie\CookieJar::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Cookie\CookieJar::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Cookie\CookieJar::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Encryption\Encrypter
+     */ 
+        class Crypt {
+                    /**
+         * Determine if the given key and cipher combination is valid.
+         *
+         * @param string $key
+         * @param string $cipher
+         * @return bool 
+         * @static 
+         */ 
+        public static function supported($key, $cipher)
+        {
+                        return \Illuminate\Encryption\Encrypter::supported($key, $cipher);
+        }
+                    /**
+         * Create a new encryption key for the given cipher.
+         *
+         * @param string $cipher
+         * @return string 
+         * @static 
+         */ 
+        public static function generateKey($cipher)
+        {
+                        return \Illuminate\Encryption\Encrypter::generateKey($cipher);
+        }
+                    /**
+         * Encrypt the given value.
+         *
+         * @param mixed $value
+         * @param bool $serialize
+         * @return string 
+         * @throws \Illuminate\Contracts\Encryption\EncryptException
+         * @static 
+         */ 
+        public static function encrypt($value, $serialize = true)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->encrypt($value, $serialize);
+        }
+                    /**
+         * Encrypt a string without serialization.
+         *
+         * @param string $value
+         * @return string 
+         * @throws \Illuminate\Contracts\Encryption\EncryptException
+         * @static 
+         */ 
+        public static function encryptString($value)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->encryptString($value);
+        }
+                    /**
+         * Decrypt the given value.
+         *
+         * @param string $payload
+         * @param bool $unserialize
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Encryption\DecryptException
+         * @static 
+         */ 
+        public static function decrypt($payload, $unserialize = true)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->decrypt($payload, $unserialize);
+        }
+                    /**
+         * Decrypt the given string without unserialization.
+         *
+         * @param string $payload
+         * @return string 
+         * @throws \Illuminate\Contracts\Encryption\DecryptException
+         * @static 
+         */ 
+        public static function decryptString($payload)
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->decryptString($payload);
+        }
+                    /**
+         * Get the encryption key.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getKey()
+        {
+                        /** @var \Illuminate\Encryption\Encrypter $instance */
+                        return $instance->getKey();
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Database\DatabaseManager
+     * @see \Illuminate\Database\Connection
+     */ 
+        class DB {
+                    /**
+         * Get a database connection instance.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Database\Connection 
+         * @static 
+         */ 
+        public static function connection($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->connection($name);
+        }
+                    /**
+         * Disconnect from the given database and remove from local cache.
+         *
+         * @param string|null $name
+         * @return void 
+         * @static 
+         */ 
+        public static function purge($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->purge($name);
+        }
+                    /**
+         * Disconnect from the given database.
+         *
+         * @param string|null $name
+         * @return void 
+         * @static 
+         */ 
+        public static function disconnect($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->disconnect($name);
+        }
+                    /**
+         * Reconnect to the given database.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Database\Connection 
+         * @static 
+         */ 
+        public static function reconnect($name = null)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->reconnect($name);
+        }
+                    /**
+         * Set the default database connection for the callback execution.
+         *
+         * @param string $name
+         * @param callable $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function usingConnection($name, $callback)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->usingConnection($name, $callback);
+        }
+                    /**
+         * Get the default connection name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultConnection()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->getDefaultConnection();
+        }
+                    /**
+         * Set the default connection name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultConnection($name)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->setDefaultConnection($name);
+        }
+                    /**
+         * Get all of the support drivers.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function supportedDrivers()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->supportedDrivers();
+        }
+                    /**
+         * Get all of the drivers that are actually available.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function availableDrivers()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->availableDrivers();
+        }
+                    /**
+         * Register an extension connection resolver.
+         *
+         * @param string $name
+         * @param callable $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($name, $resolver)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->extend($name, $resolver);
+        }
+                    /**
+         * Return all of the created connections.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getConnections()
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        return $instance->getConnections();
+        }
+                    /**
+         * Set the database reconnector callback.
+         *
+         * @param callable $reconnector
+         * @return void 
+         * @static 
+         */ 
+        public static function setReconnector($reconnector)
+        {
+                        /** @var \Illuminate\Database\DatabaseManager $instance */
+                        $instance->setReconnector($reconnector);
+        }
+                    /**
+         * Get a schema builder instance for the connection.
+         *
+         * @return \Illuminate\Database\Schema\MySqlBuilder 
+         * @static 
+         */ 
+        public static function getSchemaBuilder()
+        {
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getSchemaBuilder();
+        }
+                    /**
+         * Set the query grammar to the default implementation.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function useDefaultQueryGrammar()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->useDefaultQueryGrammar();
+        }
+                    /**
+         * Set the schema grammar to the default implementation.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function useDefaultSchemaGrammar()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->useDefaultSchemaGrammar();
+        }
+                    /**
+         * Set the query post processor to the default implementation.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function useDefaultPostProcessor()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->useDefaultPostProcessor();
+        }
+                    /**
+         * Begin a fluent query against a database table.
+         *
+         * @param \Closure|\Illuminate\Database\Query\Builder|string $table
+         * @param string|null $as
+         * @return \Illuminate\Database\Query\Builder 
+         * @static 
+         */ 
+        public static function table($table, $as = null)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->table($table, $as);
+        }
+                    /**
+         * Get a new query builder instance.
+         *
+         * @return \Illuminate\Database\Query\Builder 
+         * @static 
+         */ 
+        public static function query()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->query();
+        }
+                    /**
+         * Run a select statement and return a single result.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param bool $useReadPdo
+         * @return mixed 
+         * @static 
+         */ 
+        public static function selectOne($query, $bindings = [], $useReadPdo = true)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->selectOne($query, $bindings, $useReadPdo);
+        }
+                    /**
+         * Run a select statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return array 
+         * @static 
+         */ 
+        public static function selectFromWriteConnection($query, $bindings = [])
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->selectFromWriteConnection($query, $bindings);
+        }
+                    /**
+         * Run a select statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param bool $useReadPdo
+         * @return array 
+         * @static 
+         */ 
+        public static function select($query, $bindings = [], $useReadPdo = true)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->select($query, $bindings, $useReadPdo);
+        }
+                    /**
+         * Run a select statement against the database and returns a generator.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param bool $useReadPdo
+         * @return \Generator 
+         * @static 
+         */ 
+        public static function cursor($query, $bindings = [], $useReadPdo = true)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->cursor($query, $bindings, $useReadPdo);
+        }
+                    /**
+         * Run an insert statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return bool 
+         * @static 
+         */ 
+        public static function insert($query, $bindings = [])
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->insert($query, $bindings);
+        }
+                    /**
+         * Run an update statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return int 
+         * @static 
+         */ 
+        public static function update($query, $bindings = [])
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->update($query, $bindings);
+        }
+                    /**
+         * Run a delete statement against the database.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return int 
+         * @static 
+         */ 
+        public static function delete($query, $bindings = [])
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->delete($query, $bindings);
+        }
+                    /**
+         * Execute an SQL statement and return the boolean result.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return bool 
+         * @static 
+         */ 
+        public static function statement($query, $bindings = [])
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->statement($query, $bindings);
+        }
+                    /**
+         * Run an SQL statement and get the number of rows affected.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @return int 
+         * @static 
+         */ 
+        public static function affectingStatement($query, $bindings = [])
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->affectingStatement($query, $bindings);
+        }
+                    /**
+         * Run a raw, unprepared query against the PDO connection.
+         *
+         * @param string $query
+         * @return bool 
+         * @static 
+         */ 
+        public static function unprepared($query)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->unprepared($query);
+        }
+                    /**
+         * Execute the given callback in "dry run" mode.
+         *
+         * @param \Closure $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function pretend($callback)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->pretend($callback);
+        }
+                    /**
+         * Bind values to their parameters in the given statement.
+         *
+         * @param \PDOStatement $statement
+         * @param array $bindings
+         * @return void 
+         * @static 
+         */ 
+        public static function bindValues($statement, $bindings)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->bindValues($statement, $bindings);
+        }
+                    /**
+         * Prepare the query bindings for execution.
+         *
+         * @param array $bindings
+         * @return array 
+         * @static 
+         */ 
+        public static function prepareBindings($bindings)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->prepareBindings($bindings);
+        }
+                    /**
+         * Log a query in the connection's query log.
+         *
+         * @param string $query
+         * @param array $bindings
+         * @param float|null $time
+         * @return void 
+         * @static 
+         */ 
+        public static function logQuery($query, $bindings, $time = null)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->logQuery($query, $bindings, $time);
+        }
+                    /**
+         * Register a database query listener with the connection.
+         *
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function listen($callback)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->listen($callback);
+        }
+                    /**
+         * Get a new raw query expression.
+         *
+         * @param mixed $value
+         * @return \Illuminate\Database\Query\Expression 
+         * @static 
+         */ 
+        public static function raw($value)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->raw($value);
+        }
+                    /**
+         * Indicate if any records have been modified.
+         *
+         * @param bool $value
+         * @return void 
+         * @static 
+         */ 
+        public static function recordsHaveBeenModified($value = true)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->recordsHaveBeenModified($value);
+        }
+                    /**
+         * Is Doctrine available?
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDoctrineAvailable()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->isDoctrineAvailable();
+        }
+                    /**
+         * Get a Doctrine Schema Column instance.
+         *
+         * @param string $table
+         * @param string $column
+         * @return \Doctrine\DBAL\Schema\Column 
+         * @static 
+         */ 
+        public static function getDoctrineColumn($table, $column)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDoctrineColumn($table, $column);
+        }
+                    /**
+         * Get the Doctrine DBAL schema manager for the connection.
+         *
+         * @return \Doctrine\DBAL\Schema\AbstractSchemaManager 
+         * @static 
+         */ 
+        public static function getDoctrineSchemaManager()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDoctrineSchemaManager();
+        }
+                    /**
+         * Get the Doctrine DBAL database connection instance.
+         *
+         * @return \Doctrine\DBAL\Connection 
+         * @static 
+         */ 
+        public static function getDoctrineConnection()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDoctrineConnection();
+        }
+                    /**
+         * Get the current PDO connection.
+         *
+         * @return \PDO 
+         * @static 
+         */ 
+        public static function getPdo()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getPdo();
+        }
+                    /**
+         * Get the current PDO connection parameter without executing any reconnect logic.
+         *
+         * @return \PDO|\Closure|null 
+         * @static 
+         */ 
+        public static function getRawPdo()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getRawPdo();
+        }
+                    /**
+         * Get the current PDO connection used for reading.
+         *
+         * @return \PDO 
+         * @static 
+         */ 
+        public static function getReadPdo()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getReadPdo();
+        }
+                    /**
+         * Get the current read PDO connection parameter without executing any reconnect logic.
+         *
+         * @return \PDO|\Closure|null 
+         * @static 
+         */ 
+        public static function getRawReadPdo()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getRawReadPdo();
+        }
+                    /**
+         * Set the PDO connection.
+         *
+         * @param \PDO|\Closure|null $pdo
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setPdo($pdo)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setPdo($pdo);
+        }
+                    /**
+         * Set the PDO connection used for reading.
+         *
+         * @param \PDO|\Closure|null $pdo
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setReadPdo($pdo)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setReadPdo($pdo);
+        }
+                    /**
+         * Get the database connection name.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function getName()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getName();
+        }
+                    /**
+         * Get an option from the configuration options.
+         *
+         * @param string|null $option
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getConfig($option = null)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getConfig($option);
+        }
+                    /**
+         * Get the PDO driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDriverName()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDriverName();
+        }
+                    /**
+         * Get the query grammar used by the connection.
+         *
+         * @return \Illuminate\Database\Query\Grammars\Grammar 
+         * @static 
+         */ 
+        public static function getQueryGrammar()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getQueryGrammar();
+        }
+                    /**
+         * Set the query grammar used by the connection.
+         *
+         * @param \Illuminate\Database\Query\Grammars\Grammar $grammar
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setQueryGrammar($grammar)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setQueryGrammar($grammar);
+        }
+                    /**
+         * Get the schema grammar used by the connection.
+         *
+         * @return \Illuminate\Database\Schema\Grammars\Grammar 
+         * @static 
+         */ 
+        public static function getSchemaGrammar()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getSchemaGrammar();
+        }
+                    /**
+         * Set the schema grammar used by the connection.
+         *
+         * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setSchemaGrammar($grammar)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setSchemaGrammar($grammar);
+        }
+                    /**
+         * Get the query post processor used by the connection.
+         *
+         * @return \Illuminate\Database\Query\Processors\Processor 
+         * @static 
+         */ 
+        public static function getPostProcessor()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getPostProcessor();
+        }
+                    /**
+         * Set the query post processor used by the connection.
+         *
+         * @param \Illuminate\Database\Query\Processors\Processor $processor
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setPostProcessor($processor)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setPostProcessor($processor);
+        }
+                    /**
+         * Get the event dispatcher used by the connection.
+         *
+         * @return \Illuminate\Contracts\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function getEventDispatcher()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getEventDispatcher();
+        }
+                    /**
+         * Set the event dispatcher instance on the connection.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setEventDispatcher($events)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setEventDispatcher($events);
+        }
+                    /**
+         * Unset the event dispatcher for this connection.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function unsetEventDispatcher()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->unsetEventDispatcher();
+        }
+                    /**
+         * Determine if the connection is in a "dry run".
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function pretending()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->pretending();
+        }
+                    /**
+         * Get the connection query log.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getQueryLog()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getQueryLog();
+        }
+                    /**
+         * Clear the query log.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushQueryLog()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->flushQueryLog();
+        }
+                    /**
+         * Enable the query log on the connection.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function enableQueryLog()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->enableQueryLog();
+        }
+                    /**
+         * Disable the query log on the connection.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function disableQueryLog()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->disableQueryLog();
+        }
+                    /**
+         * Determine whether we're logging queries.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function logging()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->logging();
+        }
+                    /**
+         * Get the name of the connected database.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDatabaseName()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getDatabaseName();
+        }
+                    /**
+         * Set the name of the connected database.
+         *
+         * @param string $database
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setDatabaseName($database)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setDatabaseName($database);
+        }
+                    /**
+         * Get the table prefix for the connection.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getTablePrefix()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->getTablePrefix();
+        }
+                    /**
+         * Set the table prefix in use by the connection.
+         *
+         * @param string $prefix
+         * @return \Illuminate\Database\MySqlConnection 
+         * @static 
+         */ 
+        public static function setTablePrefix($prefix)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->setTablePrefix($prefix);
+        }
+                    /**
+         * Set the table prefix and return the grammar.
+         *
+         * @param \Illuminate\Database\Grammar $grammar
+         * @return \Illuminate\Database\Grammar 
+         * @static 
+         */ 
+        public static function withTablePrefix($grammar)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->withTablePrefix($grammar);
+        }
+                    /**
+         * Register a connection resolver.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function resolverFor($driver, $callback)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        \Illuminate\Database\MySqlConnection::resolverFor($driver, $callback);
+        }
+                    /**
+         * Get the connection resolver for the given driver.
+         *
+         * @param string $driver
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getResolver($driver)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        return \Illuminate\Database\MySqlConnection::getResolver($driver);
+        }
+                    /**
+         * Execute a Closure within a transaction.
+         *
+         * @param \Closure $callback
+         * @param int $attempts
+         * @return mixed 
+         * @throws \Throwable
+         * @static 
+         */ 
+        public static function transaction($callback, $attempts = 1)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->transaction($callback, $attempts);
+        }
+                    /**
+         * Start a new database transaction.
+         *
+         * @return void 
+         * @throws \Throwable
+         * @static 
+         */ 
+        public static function beginTransaction()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->beginTransaction();
+        }
+                    /**
+         * Commit the active database transaction.
+         *
+         * @return void 
+         * @throws \Throwable
+         * @static 
+         */ 
+        public static function commit()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->commit();
+        }
+                    /**
+         * Rollback the active database transaction.
+         *
+         * @param int|null $toLevel
+         * @return void 
+         * @throws \Throwable
+         * @static 
+         */ 
+        public static function rollBack($toLevel = null)
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        $instance->rollBack($toLevel);
+        }
+                    /**
+         * Get the number of active transactions.
+         *
+         * @return int 
+         * @static 
+         */ 
+        public static function transactionLevel()
+        {            //Method inherited from \Illuminate\Database\Connection         
+                        /** @var \Illuminate\Database\MySqlConnection $instance */
+                        return $instance->transactionLevel();
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Events\Dispatcher
+     */ 
+        class Event {
+                    /**
+         * Register an event listener with the dispatcher.
+         *
+         * @param string|array $events
+         * @param \Closure|string $listener
+         * @return void 
+         * @static 
+         */ 
+        public static function listen($events, $listener)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->listen($events, $listener);
+        }
+                    /**
+         * Determine if a given event has listeners.
+         *
+         * @param string $eventName
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasListeners($eventName)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->hasListeners($eventName);
+        }
+                    /**
+         * Determine if the given event has any wildcard listeners.
+         *
+         * @param string $eventName
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasWildcardListeners($eventName)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->hasWildcardListeners($eventName);
+        }
+                    /**
+         * Register an event and payload to be fired later.
+         *
+         * @param string $event
+         * @param array $payload
+         * @return void 
+         * @static 
+         */ 
+        public static function push($event, $payload = [])
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->push($event, $payload);
+        }
+                    /**
+         * Flush a set of pushed events.
+         *
+         * @param string $event
+         * @return void 
+         * @static 
+         */ 
+        public static function flush($event)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->flush($event);
+        }
+                    /**
+         * Register an event subscriber with the dispatcher.
+         *
+         * @param object|string $subscriber
+         * @return void 
+         * @static 
+         */ 
+        public static function subscribe($subscriber)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->subscribe($subscriber);
+        }
+                    /**
+         * Fire an event until the first non-null response is returned.
+         *
+         * @param string|object $event
+         * @param mixed $payload
+         * @return array|null 
+         * @static 
+         */ 
+        public static function until($event, $payload = [])
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->until($event, $payload);
+        }
+                    /**
+         * Fire an event and call the listeners.
+         *
+         * @param string|object $event
+         * @param mixed $payload
+         * @param bool $halt
+         * @return array|null 
+         * @static 
+         */ 
+        public static function dispatch($event, $payload = [], $halt = false)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->dispatch($event, $payload, $halt);
+        }
+                    /**
+         * Get all of the listeners for a given event name.
+         *
+         * @param string $eventName
+         * @return array 
+         * @static 
+         */ 
+        public static function getListeners($eventName)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->getListeners($eventName);
+        }
+                    /**
+         * Register an event listener with the dispatcher.
+         *
+         * @param \Closure|string $listener
+         * @param bool $wildcard
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function makeListener($listener, $wildcard = false)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->makeListener($listener, $wildcard);
+        }
+                    /**
+         * Create a class based listener using the IoC container.
+         *
+         * @param string $listener
+         * @param bool $wildcard
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function createClassListener($listener, $wildcard = false)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->createClassListener($listener, $wildcard);
+        }
+                    /**
+         * Remove a set of listeners from the dispatcher.
+         *
+         * @param string $event
+         * @return void 
+         * @static 
+         */ 
+        public static function forget($event)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->forget($event);
+        }
+                    /**
+         * Forget all of the pushed listeners.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function forgetPushed()
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        $instance->forgetPushed();
+        }
+                    /**
+         * Set the queue resolver implementation.
+         *
+         * @param callable $resolver
+         * @return \Illuminate\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function setQueueResolver($resolver)
+        {
+                        /** @var \Illuminate\Events\Dispatcher $instance */
+                        return $instance->setQueueResolver($resolver);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Events\Dispatcher::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Events\Dispatcher::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Events\Dispatcher::hasMacro($name);
+        }
+                    /**
+         * Assert if an event was dispatched based on a truth-test callback.
+         *
+         * @param string|\Closure $event
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatched($event, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        $instance->assertDispatched($event, $callback);
+        }
+                    /**
+         * Assert if an event was dispatched a number of times.
+         *
+         * @param string $event
+         * @param int $times
+         * @return void 
+         * @static 
+         */ 
+        public static function assertDispatchedTimes($event, $times = 1)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        $instance->assertDispatchedTimes($event, $times);
+        }
+                    /**
+         * Determine if an event was dispatched based on a truth-test callback.
+         *
+         * @param string|\Closure $event
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotDispatched($event, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        $instance->assertNotDispatched($event, $callback);
+        }
+                    /**
+         * Get all of the events matching a truth-test callback.
+         *
+         * @param string $event
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function dispatched($event, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        return $instance->dispatched($event, $callback);
+        }
+                    /**
+         * Determine if the given event has been dispatched.
+         *
+         * @param string $event
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasDispatched($event)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\EventFake $instance */
+                        return $instance->hasDispatched($event);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Filesystem\Filesystem
+     */ 
+        class File {
+                    /**
+         * Determine if a file or directory exists.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->exists($path);
+        }
+                    /**
+         * Determine if a file or directory is missing.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function missing($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->missing($path);
+        }
+                    /**
+         * Get the contents of a file.
+         *
+         * @param string $path
+         * @param bool $lock
+         * @return string 
+         * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+         * @static 
+         */ 
+        public static function get($path, $lock = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->get($path, $lock);
+        }
+                    /**
+         * Get contents of a file with shared access.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function sharedGet($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->sharedGet($path);
+        }
+                    /**
+         * Get the returned value of a file.
+         *
+         * @param string $path
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+         * @static 
+         */ 
+        public static function getRequire($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->getRequire($path);
+        }
+                    /**
+         * Require the given file once.
+         *
+         * @param string $file
+         * @return mixed 
+         * @static 
+         */ 
+        public static function requireOnce($file)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->requireOnce($file);
+        }
+                    /**
+         * Get the MD5 hash of the file at the given path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function hash($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->hash($path);
+        }
+                    /**
+         * Write the contents of a file.
+         *
+         * @param string $path
+         * @param string $contents
+         * @param bool $lock
+         * @return int|bool 
+         * @static 
+         */ 
+        public static function put($path, $contents, $lock = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->put($path, $contents, $lock);
+        }
+                    /**
+         * Write the contents of a file, replacing it atomically if it already exists.
+         *
+         * @param string $path
+         * @param string $content
+         * @return void 
+         * @static 
+         */ 
+        public static function replace($path, $content)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        $instance->replace($path, $content);
+        }
+                    /**
+         * Prepend to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @return int 
+         * @static 
+         */ 
+        public static function prepend($path, $data)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->prepend($path, $data);
+        }
+                    /**
+         * Append to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @return int 
+         * @static 
+         */ 
+        public static function append($path, $data)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->append($path, $data);
+        }
+                    /**
+         * Get or set UNIX mode of a file or directory.
+         *
+         * @param string $path
+         * @param int|null $mode
+         * @return mixed 
+         * @static 
+         */ 
+        public static function chmod($path, $mode = null)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->chmod($path, $mode);
+        }
+                    /**
+         * Delete the file at a given path.
+         *
+         * @param string|array $paths
+         * @return bool 
+         * @static 
+         */ 
+        public static function delete($paths)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->delete($paths);
+        }
+                    /**
+         * Move a file to a new location.
+         *
+         * @param string $path
+         * @param string $target
+         * @return bool 
+         * @static 
+         */ 
+        public static function move($path, $target)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->move($path, $target);
+        }
+                    /**
+         * Copy a file to a new location.
+         *
+         * @param string $path
+         * @param string $target
+         * @return bool 
+         * @static 
+         */ 
+        public static function copy($path, $target)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->copy($path, $target);
+        }
+                    /**
+         * Create a symlink to the target file or directory. On Windows, a hard link is created if the target is a file.
+         *
+         * @param string $target
+         * @param string $link
+         * @return void 
+         * @static 
+         */ 
+        public static function link($target, $link)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        $instance->link($target, $link);
+        }
+                    /**
+         * Extract the file name from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function name($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->name($path);
+        }
+                    /**
+         * Extract the trailing name component from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function basename($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->basename($path);
+        }
+                    /**
+         * Extract the parent directory from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function dirname($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->dirname($path);
+        }
+                    /**
+         * Extract the file extension from a file path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function extension($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->extension($path);
+        }
+                    /**
+         * Guess the file extension from the mime-type of a given file.
+         *
+         * @param string $path
+         * @return string|null 
+         * @static 
+         */ 
+        public static function guessExtension($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->guessExtension($path);
+        }
+                    /**
+         * Get the file type of a given file.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function type($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->type($path);
+        }
+                    /**
+         * Get the mime-type of a given file.
+         *
+         * @param string $path
+         * @return string|false 
+         * @static 
+         */ 
+        public static function mimeType($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->mimeType($path);
+        }
+                    /**
+         * Get the file size of a given file.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function size($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->size($path);
+        }
+                    /**
+         * Get the file's last modification time.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function lastModified($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->lastModified($path);
+        }
+                    /**
+         * Determine if the given path is a directory.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function isDirectory($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isDirectory($directory);
+        }
+                    /**
+         * Determine if the given path is readable.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isReadable($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isReadable($path);
+        }
+                    /**
+         * Determine if the given path is writable.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isWritable($path)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isWritable($path);
+        }
+                    /**
+         * Determine if the given path is a file.
+         *
+         * @param string $file
+         * @return bool 
+         * @static 
+         */ 
+        public static function isFile($file)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->isFile($file);
+        }
+                    /**
+         * Find path names matching a given pattern.
+         *
+         * @param string $pattern
+         * @param int $flags
+         * @return array 
+         * @static 
+         */ 
+        public static function glob($pattern, $flags = 0)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->glob($pattern, $flags);
+        }
+                    /**
+         * Get an array of all files in a directory.
+         *
+         * @param string $directory
+         * @param bool $hidden
+         * @return \Symfony\Component\Finder\SplFileInfo[] 
+         * @static 
+         */ 
+        public static function files($directory, $hidden = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->files($directory, $hidden);
+        }
+                    /**
+         * Get all of the files from the given directory (recursive).
+         *
+         * @param string $directory
+         * @param bool $hidden
+         * @return \Symfony\Component\Finder\SplFileInfo[] 
+         * @static 
+         */ 
+        public static function allFiles($directory, $hidden = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->allFiles($directory, $hidden);
+        }
+                    /**
+         * Get all of the directories within a given directory.
+         *
+         * @param string $directory
+         * @return array 
+         * @static 
+         */ 
+        public static function directories($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->directories($directory);
+        }
+                    /**
+         * Ensure a directory exists.
+         *
+         * @param string $path
+         * @param int $mode
+         * @param bool $recursive
+         * @return void 
+         * @static 
+         */ 
+        public static function ensureDirectoryExists($path, $mode = 493, $recursive = true)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        $instance->ensureDirectoryExists($path, $mode, $recursive);
+        }
+                    /**
+         * Create a directory.
+         *
+         * @param string $path
+         * @param int $mode
+         * @param bool $recursive
+         * @param bool $force
+         * @return bool 
+         * @static 
+         */ 
+        public static function makeDirectory($path, $mode = 493, $recursive = false, $force = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->makeDirectory($path, $mode, $recursive, $force);
+        }
+                    /**
+         * Move a directory.
+         *
+         * @param string $from
+         * @param string $to
+         * @param bool $overwrite
+         * @return bool 
+         * @static 
+         */ 
+        public static function moveDirectory($from, $to, $overwrite = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->moveDirectory($from, $to, $overwrite);
+        }
+                    /**
+         * Copy a directory from one location to another.
+         *
+         * @param string $directory
+         * @param string $destination
+         * @param int|null $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function copyDirectory($directory, $destination, $options = null)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->copyDirectory($directory, $destination, $options);
+        }
+                    /**
+         * Recursively delete a directory.
+         * 
+         * The directory itself may be optionally preserved.
+         *
+         * @param string $directory
+         * @param bool $preserve
+         * @return bool 
+         * @static 
+         */ 
+        public static function deleteDirectory($directory, $preserve = false)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->deleteDirectory($directory, $preserve);
+        }
+                    /**
+         * Remove all of the directories within a given directory.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function deleteDirectories($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->deleteDirectories($directory);
+        }
+                    /**
+         * Empty the specified directory of all files and folders.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function cleanDirectory($directory)
+        {
+                        /** @var \Illuminate\Filesystem\Filesystem $instance */
+                        return $instance->cleanDirectory($directory);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Filesystem\Filesystem::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Filesystem\Filesystem::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Filesystem\Filesystem::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Auth\Access\Gate
+     */ 
+        class Gate {
+                    /**
+         * Determine if a given ability has been defined.
+         *
+         * @param string|array $ability
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($ability)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->has($ability);
+        }
+                    /**
+         * Define a new ability.
+         *
+         * @param string $ability
+         * @param callable|string $callback
+         * @return \Illuminate\Auth\Access\Gate 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function define($ability, $callback)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->define($ability, $callback);
+        }
+                    /**
+         * Define abilities for a resource.
+         *
+         * @param string $name
+         * @param string $class
+         * @param array|null $abilities
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function resource($name, $class, $abilities = null)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->resource($name, $class, $abilities);
+        }
+                    /**
+         * Define a policy class for a given class type.
+         *
+         * @param string $class
+         * @param string $policy
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function policy($class, $policy)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->policy($class, $policy);
+        }
+                    /**
+         * Register a callback to run before all Gate checks.
+         *
+         * @param callable $callback
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function before($callback)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->before($callback);
+        }
+                    /**
+         * Register a callback to run after all Gate checks.
+         *
+         * @param callable $callback
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function after($callback)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->after($callback);
+        }
+                    /**
+         * Determine if the given ability should be granted for the current user.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function allows($ability, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->allows($ability, $arguments);
+        }
+                    /**
+         * Determine if the given ability should be denied for the current user.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function denies($ability, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->denies($ability, $arguments);
+        }
+                    /**
+         * Determine if all of the given abilities should be granted for the current user.
+         *
+         * @param \Illuminate\Auth\Access\iterable|string $abilities
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function check($abilities, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->check($abilities, $arguments);
+        }
+                    /**
+         * Determine if any one of the given abilities should be granted for the current user.
+         *
+         * @param \Illuminate\Auth\Access\iterable|string $abilities
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function any($abilities, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->any($abilities, $arguments);
+        }
+                    /**
+         * Determine if all of the given abilities should be denied for the current user.
+         *
+         * @param \Illuminate\Auth\Access\iterable|string $abilities
+         * @param array|mixed $arguments
+         * @return bool 
+         * @static 
+         */ 
+        public static function none($abilities, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->none($abilities, $arguments);
+        }
+                    /**
+         * Determine if the given ability should be granted for the current user.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return \Illuminate\Auth\Access\Response 
+         * @throws \Illuminate\Auth\Access\AuthorizationException
+         * @static 
+         */ 
+        public static function authorize($ability, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->authorize($ability, $arguments);
+        }
+                    /**
+         * Inspect the user for the given ability.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return \Illuminate\Auth\Access\Response 
+         * @static 
+         */ 
+        public static function inspect($ability, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->inspect($ability, $arguments);
+        }
+                    /**
+         * Get the raw result from the authorization callback.
+         *
+         * @param string $ability
+         * @param array|mixed $arguments
+         * @return mixed 
+         * @throws \Illuminate\Auth\Access\AuthorizationException
+         * @static 
+         */ 
+        public static function raw($ability, $arguments = [])
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->raw($ability, $arguments);
+        }
+                    /**
+         * Get a policy instance for a given class.
+         *
+         * @param object|string $class
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getPolicyFor($class)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->getPolicyFor($class);
+        }
+                    /**
+         * Specify a callback to be used to guess policy names.
+         *
+         * @param callable $callback
+         * @return \Illuminate\Auth\Access\Gate 
+         * @static 
+         */ 
+        public static function guessPolicyNamesUsing($callback)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->guessPolicyNamesUsing($callback);
+        }
+                    /**
+         * Build a policy class instance of the given type.
+         *
+         * @param object|string $class
+         * @return mixed 
+         * @throws \Illuminate\Contracts\Container\BindingResolutionException
+         * @static 
+         */ 
+        public static function resolvePolicy($class)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->resolvePolicy($class);
+        }
+                    /**
+         * Get a gate instance for the given user.
+         *
+         * @param \Illuminate\Contracts\Auth\Authenticatable|mixed $user
+         * @return static 
+         * @static 
+         */ 
+        public static function forUser($user)
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->forUser($user);
+        }
+                    /**
+         * Get all of the defined abilities.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function abilities()
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->abilities();
+        }
+                    /**
+         * Get all of the defined policies.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function policies()
+        {
+                        /** @var \Illuminate\Auth\Access\Gate $instance */
+                        return $instance->policies();
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Hashing\HashManager
+     */ 
+        class Hash {
+                    /**
+         * Create an instance of the Bcrypt hash Driver.
+         *
+         * @return \Illuminate\Hashing\BcryptHasher 
+         * @static 
+         */ 
+        public static function createBcryptDriver()
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->createBcryptDriver();
+        }
+                    /**
+         * Create an instance of the Argon2i hash Driver.
+         *
+         * @return \Illuminate\Hashing\ArgonHasher 
+         * @static 
+         */ 
+        public static function createArgonDriver()
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->createArgonDriver();
+        }
+                    /**
+         * Create an instance of the Argon2id hash Driver.
+         *
+         * @return \Illuminate\Hashing\Argon2IdHasher 
+         * @static 
+         */ 
+        public static function createArgon2idDriver()
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->createArgon2idDriver();
+        }
+                    /**
+         * Get information about the given hashed value.
+         *
+         * @param string $hashedValue
+         * @return array 
+         * @static 
+         */ 
+        public static function info($hashedValue)
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->info($hashedValue);
+        }
+                    /**
+         * Hash the given value.
+         *
+         * @param string $value
+         * @param array $options
+         * @return string 
+         * @static 
+         */ 
+        public static function make($value, $options = [])
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->make($value, $options);
+        }
+                    /**
+         * Check the given plain value against a hash.
+         *
+         * @param string $value
+         * @param string $hashedValue
+         * @param array $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function check($value, $hashedValue, $options = [])
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->check($value, $hashedValue, $options);
+        }
+                    /**
+         * Check if the given hash has been hashed using the given options.
+         *
+         * @param string $hashedValue
+         * @param array $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function needsRehash($hashedValue, $options = [])
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->needsRehash($hashedValue, $options);
+        }
+                    /**
+         * Get the default driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Get a driver instance.
+         *
+         * @param string|null $driver
+         * @return mixed 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->driver($driver);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Hashing\HashManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Get all of the created "drivers".
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDrivers()
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Hashing\HashManager $instance */
+                        return $instance->getDrivers();
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @method static \Illuminate\Http\Client\PendingRequest accept(string $contentType)
+     * @method static \Illuminate\Http\Client\PendingRequest acceptJson()
+     * @method static \Illuminate\Http\Client\PendingRequest asForm()
+     * @method static \Illuminate\Http\Client\PendingRequest asJson()
+     * @method static \Illuminate\Http\Client\PendingRequest asMultipart()
+     * @method static \Illuminate\Http\Client\PendingRequest attach(string $name, string $contents, string|null $filename = null, array $headers = [])
+     * @method static \Illuminate\Http\Client\PendingRequest baseUrl(string $url)
+     * @method static \Illuminate\Http\Client\PendingRequest beforeSending(callable $callback)
+     * @method static \Illuminate\Http\Client\PendingRequest bodyFormat(string $format)
+     * @method static \Illuminate\Http\Client\PendingRequest contentType(string $contentType)
+     * @method static \Illuminate\Http\Client\PendingRequest retry(int $times, int $sleep = 0)
+     * @method static \Illuminate\Http\Client\PendingRequest stub(callable $callback)
+     * @method static \Illuminate\Http\Client\PendingRequest timeout(int $seconds)
+     * @method static \Illuminate\Http\Client\PendingRequest withBasicAuth(string $username, string $password)
+     * @method static \Illuminate\Http\Client\PendingRequest withBody(resource|string $content, string $contentType)
+     * @method static \Illuminate\Http\Client\PendingRequest withCookies(array $cookies, string $domain)
+     * @method static \Illuminate\Http\Client\PendingRequest withDigestAuth(string $username, string $password)
+     * @method static \Illuminate\Http\Client\PendingRequest withHeaders(array $headers)
+     * @method static \Illuminate\Http\Client\PendingRequest withOptions(array $options)
+     * @method static \Illuminate\Http\Client\PendingRequest withToken(string $token, string $type = 'Bearer')
+     * @method static \Illuminate\Http\Client\PendingRequest withoutRedirecting()
+     * @method static \Illuminate\Http\Client\PendingRequest withoutVerifying()
+     * @method static \Illuminate\Http\Client\Response delete(string $url, array $data = [])
+     * @method static \Illuminate\Http\Client\Response get(string $url, array $query = [])
+     * @method static \Illuminate\Http\Client\Response head(string $url, array $query = [])
+     * @method static \Illuminate\Http\Client\Response patch(string $url, array $data = [])
+     * @method static \Illuminate\Http\Client\Response post(string $url, array $data = [])
+     * @method static \Illuminate\Http\Client\Response put(string $url, array $data = [])
+     * @method static \Illuminate\Http\Client\Response send(string $method, string $url, array $options = [])
+     * @see \Illuminate\Http\Client\Factory
+     */ 
+        class Http {
+                    /**
+         * Create a new response instance for use during stubbing.
+         *
+         * @param array|string $body
+         * @param int $status
+         * @param array $headers
+         * @return \GuzzleHttp\Promise\PromiseInterface 
+         * @static 
+         */ 
+        public static function response($body = null, $status = 200, $headers = [])
+        {
+                        return \Illuminate\Http\Client\Factory::response($body, $status, $headers);
+        }
+                    /**
+         * Get an invokable object that returns a sequence of responses in order for use during stubbing.
+         *
+         * @param array $responses
+         * @return \Illuminate\Http\Client\ResponseSequence 
+         * @static 
+         */ 
+        public static function sequence($responses = [])
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        return $instance->sequence($responses);
+        }
+                    /**
+         * Register a stub callable that will intercept requests and be able to return stub responses.
+         *
+         * @param callable|array $callback
+         * @return \Illuminate\Http\Client\Factory 
+         * @static 
+         */ 
+        public static function fake($callback = null)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        return $instance->fake($callback);
+        }
+                    /**
+         * Register a response sequence for the given URL pattern.
+         *
+         * @param string $url
+         * @return \Illuminate\Http\Client\ResponseSequence 
+         * @static 
+         */ 
+        public static function fakeSequence($url = '*')
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        return $instance->fakeSequence($url);
+        }
+                    /**
+         * Stub the given URL using the given callback.
+         *
+         * @param string $url
+         * @param \Illuminate\Http\Client\Response|\GuzzleHttp\Promise\PromiseInterface|callable $callback
+         * @return \Illuminate\Http\Client\Factory 
+         * @static 
+         */ 
+        public static function stubUrl($url, $callback)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        return $instance->stubUrl($url, $callback);
+        }
+                    /**
+         * Record a request response pair.
+         *
+         * @param \Illuminate\Http\Client\Request $request
+         * @param \Illuminate\Http\Client\Response $response
+         * @return void 
+         * @static 
+         */ 
+        public static function recordRequestResponsePair($request, $response)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        $instance->recordRequestResponsePair($request, $response);
+        }
+                    /**
+         * Assert that a request / response pair was recorded matching a given truth test.
+         *
+         * @param callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSent($callback)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        $instance->assertSent($callback);
+        }
+                    /**
+         * Assert that a request / response pair was not recorded matching a given truth test.
+         *
+         * @param callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotSent($callback)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        $instance->assertNotSent($callback);
+        }
+                    /**
+         * Assert that no request / response pair was recorded.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingSent()
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        $instance->assertNothingSent();
+        }
+                    /**
+         * Assert how many requests have been recorded.
+         *
+         * @param int $count
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSentCount($count)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        $instance->assertSentCount($count);
+        }
+                    /**
+         * Assert that every created response sequence is empty.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSequencesAreEmpty()
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        $instance->assertSequencesAreEmpty();
+        }
+                    /**
+         * Get a collection of the request / response pairs matching the given truth test.
+         *
+         * @param callable $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function recorded($callback)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        return $instance->recorded($callback);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Http\Client\Factory::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Http\Client\Factory::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Http\Client\Factory::hasMacro($name);
+        }
+                    /**
+         * Dynamically handle calls to the class.
+         *
+         * @param string $method
+         * @param array $parameters
+         * @return mixed 
+         * @throws \BadMethodCallException
+         * @static 
+         */ 
+        public static function macroCall($method, $parameters)
+        {
+                        /** @var \Illuminate\Http\Client\Factory $instance */
+                        return $instance->macroCall($method, $parameters);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Translation\Translator
+     */ 
+        class Lang {
+                    /**
+         * Determine if a translation exists for a given locale.
+         *
+         * @param string $key
+         * @param string|null $locale
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasForLocale($key, $locale = null)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->hasForLocale($key, $locale);
+        }
+                    /**
+         * Determine if a translation exists.
+         *
+         * @param string $key
+         * @param string|null $locale
+         * @param bool $fallback
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key, $locale = null, $fallback = true)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->has($key, $locale, $fallback);
+        }
+                    /**
+         * Get the translation for the given key.
+         *
+         * @param string $key
+         * @param array $replace
+         * @param string|null $locale
+         * @param bool $fallback
+         * @return string|array 
+         * @static 
+         */ 
+        public static function get($key, $replace = [], $locale = null, $fallback = true)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->get($key, $replace, $locale, $fallback);
+        }
+                    /**
+         * Get a translation according to an integer value.
+         *
+         * @param string $key
+         * @param \Countable|int|array $number
+         * @param array $replace
+         * @param string|null $locale
+         * @return string 
+         * @static 
+         */ 
+        public static function choice($key, $number, $replace = [], $locale = null)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->choice($key, $number, $replace, $locale);
+        }
+                    /**
+         * Add translation lines to the given locale.
+         *
+         * @param array $lines
+         * @param string $locale
+         * @param string $namespace
+         * @return void 
+         * @static 
+         */ 
+        public static function addLines($lines, $locale, $namespace = '*')
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->addLines($lines, $locale, $namespace);
+        }
+                    /**
+         * Load the specified language group.
+         *
+         * @param string $namespace
+         * @param string $group
+         * @param string $locale
+         * @return void 
+         * @static 
+         */ 
+        public static function load($namespace, $group, $locale)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->load($namespace, $group, $locale);
+        }
+                    /**
+         * Add a new namespace to the loader.
+         *
+         * @param string $namespace
+         * @param string $hint
+         * @return void 
+         * @static 
+         */ 
+        public static function addNamespace($namespace, $hint)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->addNamespace($namespace, $hint);
+        }
+                    /**
+         * Add a new JSON path to the loader.
+         *
+         * @param string $path
+         * @return void 
+         * @static 
+         */ 
+        public static function addJsonPath($path)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->addJsonPath($path);
+        }
+                    /**
+         * Parse a key into namespace, group, and item.
+         *
+         * @param string $key
+         * @return array 
+         * @static 
+         */ 
+        public static function parseKey($key)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->parseKey($key);
+        }
+                    /**
+         * Get the message selector instance.
+         *
+         * @return \Illuminate\Translation\MessageSelector 
+         * @static 
+         */ 
+        public static function getSelector()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getSelector();
+        }
+                    /**
+         * Set the message selector instance.
+         *
+         * @param \Illuminate\Translation\MessageSelector $selector
+         * @return void 
+         * @static 
+         */ 
+        public static function setSelector($selector)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setSelector($selector);
+        }
+                    /**
+         * Get the language line loader implementation.
+         *
+         * @return \Illuminate\Contracts\Translation\Loader 
+         * @static 
+         */ 
+        public static function getLoader()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getLoader();
+        }
+                    /**
+         * Get the default locale being used.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function locale()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->locale();
+        }
+                    /**
+         * Get the default locale being used.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLocale()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getLocale();
+        }
+                    /**
+         * Set the default locale.
+         *
+         * @param string $locale
+         * @return void 
+         * @static 
+         */ 
+        public static function setLocale($locale)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setLocale($locale);
+        }
+                    /**
+         * Get the fallback locale being used.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getFallback()
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        return $instance->getFallback();
+        }
+                    /**
+         * Set the fallback locale being used.
+         *
+         * @param string $fallback
+         * @return void 
+         * @static 
+         */ 
+        public static function setFallback($fallback)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setFallback($fallback);
+        }
+                    /**
+         * Set the loaded translation groups.
+         *
+         * @param array $loaded
+         * @return void 
+         * @static 
+         */ 
+        public static function setLoaded($loaded)
+        {
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setLoaded($loaded);
+        }
+                    /**
+         * Set the parsed value of a key.
+         *
+         * @param string $key
+         * @param array $parsed
+         * @return void 
+         * @static 
+         */ 
+        public static function setParsedKey($key, $parsed)
+        {            //Method inherited from \Illuminate\Support\NamespacedItemResolver         
+                        /** @var \Illuminate\Translation\Translator $instance */
+                        $instance->setParsedKey($key, $parsed);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Translation\Translator::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Translation\Translator::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Translation\Translator::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Log\Logger
+     */ 
+        class Log {
+                    /**
+         * Create a new, on-demand aggregate logger instance.
+         *
+         * @param array $channels
+         * @param string|null $channel
+         * @return \Psr\Log\LoggerInterface 
+         * @static 
+         */ 
+        public static function stack($channels, $channel = null)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->stack($channels, $channel);
+        }
+                    /**
+         * Get a log channel instance.
+         *
+         * @param string|null $channel
+         * @return \Psr\Log\LoggerInterface 
+         * @static 
+         */ 
+        public static function channel($channel = null)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->channel($channel);
+        }
+                    /**
+         * Get a log driver instance.
+         *
+         * @param string|null $driver
+         * @return \Psr\Log\LoggerInterface 
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->driver($driver);
+        }
+                    /**
+         * 
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getChannels()
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->getChannels();
+        }
+                    /**
+         * Get the default log driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the default log driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Log\LogManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Unset the given channel instance.
+         *
+         * @param string|null $driver
+         * @return \Illuminate\Log\LogManager 
+         * @static 
+         */ 
+        public static function forgetChannel($driver = null)
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        return $instance->forgetChannel($driver);
+        }
+                    /**
+         * System is unusable.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function emergency($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->emergency($message, $context);
+        }
+                    /**
+         * Action must be taken immediately.
+         * 
+         * Example: Entire website down, database unavailable, etc. This should
+         * trigger the SMS alerts and wake you up.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function alert($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->alert($message, $context);
+        }
+                    /**
+         * Critical conditions.
+         * 
+         * Example: Application component unavailable, unexpected exception.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function critical($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->critical($message, $context);
+        }
+                    /**
+         * Runtime errors that do not require immediate action but should typically
+         * be logged and monitored.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function error($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->error($message, $context);
+        }
+                    /**
+         * Exceptional occurrences that are not errors.
+         * 
+         * Example: Use of deprecated APIs, poor use of an API, undesirable things
+         * that are not necessarily wrong.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function warning($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->warning($message, $context);
+        }
+                    /**
+         * Normal but significant events.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function notice($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->notice($message, $context);
+        }
+                    /**
+         * Interesting events.
+         * 
+         * Example: User logs in, SQL logs.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function info($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->info($message, $context);
+        }
+                    /**
+         * Detailed debug information.
+         *
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function debug($message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->debug($message, $context);
+        }
+                    /**
+         * Logs with an arbitrary level.
+         *
+         * @param mixed $level
+         * @param string $message
+         * @param array $context
+         * @return void 
+         * @static 
+         */ 
+        public static function log($level, $message, $context = [])
+        {
+                        /** @var \Illuminate\Log\LogManager $instance */
+                        $instance->log($level, $message, $context);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Mail\Mailer
+     * @see \Illuminate\Support\Testing\Fakes\MailFake
+     */ 
+        class Mail {
+                    /**
+         * Get a mailer instance by name.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Mail\Mailer 
+         * @static 
+         */ 
+        public static function mailer($name = null)
+        {
+                        /** @var \Illuminate\Mail\MailManager $instance */
+                        return $instance->mailer($name);
+        }
+                    /**
+         * Get a mailer driver instance.
+         *
+         * @param string|null $driver
+         * @return \Illuminate\Mail\Mailer 
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {
+                        /** @var \Illuminate\Mail\MailManager $instance */
+                        return $instance->driver($driver);
+        }
+                    /**
+         * Create a new transport instance.
+         *
+         * @param array $config
+         * @return \Swift_Transport 
+         * @static 
+         */ 
+        public static function createTransport($config)
+        {
+                        /** @var \Illuminate\Mail\MailManager $instance */
+                        return $instance->createTransport($config);
+        }
+                    /**
+         * Get the default mail driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Mail\MailManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the default mail driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Mail\MailManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+                    /**
+         * Register a custom transport creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Mail\MailManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Mail\MailManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Assert if a mailable was sent based on a truth-test callback.
+         *
+         * @param string|\Closure $mailable
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSent($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertSent($mailable, $callback);
+        }
+                    /**
+         * Determine if a mailable was not sent based on a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotSent($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNotSent($mailable, $callback);
+        }
+                    /**
+         * Assert that no mailables were sent.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingSent()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNothingSent();
+        }
+                    /**
+         * Assert if a mailable was queued based on a truth-test callback.
+         *
+         * @param string|\Closure $mailable
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertQueued($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertQueued($mailable, $callback);
+        }
+                    /**
+         * Determine if a mailable was not queued based on a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotQueued($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNotQueued($mailable, $callback);
+        }
+                    /**
+         * Assert that no mailables were queued.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingQueued()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->assertNothingQueued();
+        }
+                    /**
+         * Get all of the mailables matching a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function sent($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->sent($mailable, $callback);
+        }
+                    /**
+         * Determine if the given mailable has been sent.
+         *
+         * @param string $mailable
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasSent($mailable)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->hasSent($mailable);
+        }
+                    /**
+         * Get all of the queued mailables matching a truth-test callback.
+         *
+         * @param string $mailable
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function queued($mailable, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->queued($mailable, $callback);
+        }
+                    /**
+         * Determine if the given mailable has been queued.
+         *
+         * @param string $mailable
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasQueued($mailable)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->hasQueued($mailable);
+        }
+                    /**
+         * Begin the process of mailing a mailable class instance.
+         *
+         * @param mixed $users
+         * @return \Illuminate\Mail\PendingMail 
+         * @static 
+         */ 
+        public static function to($users)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->to($users);
+        }
+                    /**
+         * Begin the process of mailing a mailable class instance.
+         *
+         * @param mixed $users
+         * @return \Illuminate\Mail\PendingMail 
+         * @static 
+         */ 
+        public static function bcc($users)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->bcc($users);
+        }
+                    /**
+         * Send a new message with only a raw text part.
+         *
+         * @param string $text
+         * @param \Closure|string $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function raw($text, $callback)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->raw($text, $callback);
+        }
+                    /**
+         * Send a new message using a view.
+         *
+         * @param string|array $view
+         * @param array $data
+         * @param \Closure|string|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function send($view, $data = [], $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        $instance->send($view, $data, $callback);
+        }
+                    /**
+         * Queue a new e-mail message for sending.
+         *
+         * @param string|array $view
+         * @param string|null $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function queue($view, $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->queue($view, $queue);
+        }
+                    /**
+         * Queue a new e-mail message for sending after (n) seconds.
+         *
+         * @param \DateTimeInterface|\DateInterval|int $delay
+         * @param \Illuminate\Contracts\Mail\Mailable|string|array $view
+         * @param string|null $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function later($delay, $view, $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->later($delay, $view, $queue);
+        }
+                    /**
+         * Get the array of failed recipients.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function failures()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\MailFake $instance */
+                        return $instance->failures();
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Notifications\ChannelManager
+     */ 
+        class Notification {
+                    /**
+         * Send the given notification to the given notifiable entities.
+         *
+         * @param \Illuminate\Support\Collection|array|mixed $notifiables
+         * @param mixed $notification
+         * @return void 
+         * @static 
+         */ 
+        public static function send($notifiables, $notification)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        $instance->send($notifiables, $notification);
+        }
+                    /**
+         * Send the given notification immediately.
+         *
+         * @param \Illuminate\Support\Collection|array|mixed $notifiables
+         * @param mixed $notification
+         * @param array|null $channels
+         * @return void 
+         * @static 
+         */ 
+        public static function sendNow($notifiables, $notification, $channels = null)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        $instance->sendNow($notifiables, $notification, $channels);
+        }
+                    /**
+         * Get a channel instance.
+         *
+         * @param string|null $name
+         * @return mixed 
+         * @static 
+         */ 
+        public static function channel($name = null)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->channel($name);
+        }
+                    /**
+         * Get the default channel driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Get the default channel driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function deliversVia()
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->deliversVia();
+        }
+                    /**
+         * Set the default channel driver name.
+         *
+         * @param string $channel
+         * @return void 
+         * @static 
+         */ 
+        public static function deliverVia($channel)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        $instance->deliverVia($channel);
+        }
+                    /**
+         * Set the locale of notifications.
+         *
+         * @param string $locale
+         * @return \Illuminate\Notifications\ChannelManager 
+         * @static 
+         */ 
+        public static function locale($locale)
+        {
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->locale($locale);
+        }
+                    /**
+         * Get a driver instance.
+         *
+         * @param string|null $driver
+         * @return mixed 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->driver($driver);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Notifications\ChannelManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Get all of the created "drivers".
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDrivers()
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Notifications\ChannelManager $instance */
+                        return $instance->getDrivers();
+        }
+                    /**
+         * Assert if a notification was sent based on a truth-test callback.
+         *
+         * @param mixed $notifiable
+         * @param string|\Closure $notification
+         * @param callable|null $callback
+         * @return void 
+         * @throws \Exception
+         * @static 
+         */ 
+        public static function assertSentTo($notifiable, $notification, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertSentTo($notifiable, $notification, $callback);
+        }
+                    /**
+         * Assert if a notification was sent a number of times.
+         *
+         * @param mixed $notifiable
+         * @param string $notification
+         * @param int $times
+         * @return void 
+         * @static 
+         */ 
+        public static function assertSentToTimes($notifiable, $notification, $times = 1)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertSentToTimes($notifiable, $notification, $times);
+        }
+                    /**
+         * Determine if a notification was sent based on a truth-test callback.
+         *
+         * @param mixed $notifiable
+         * @param string|\Closure $notification
+         * @param callable|null $callback
+         * @return void 
+         * @throws \Exception
+         * @static 
+         */ 
+        public static function assertNotSentTo($notifiable, $notification, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertNotSentTo($notifiable, $notification, $callback);
+        }
+                    /**
+         * Assert that no notifications were sent.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingSent()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertNothingSent();
+        }
+                    /**
+         * Assert the total amount of times a notification was sent.
+         *
+         * @param int $expectedCount
+         * @param string $notification
+         * @return void 
+         * @static 
+         */ 
+        public static function assertTimesSent($expectedCount, $notification)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        $instance->assertTimesSent($expectedCount, $notification);
+        }
+                    /**
+         * Get all of the notifications matching a truth-test callback.
+         *
+         * @param mixed $notifiable
+         * @param string $notification
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function sent($notifiable, $notification, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        return $instance->sent($notifiable, $notification, $callback);
+        }
+                    /**
+         * Determine if there are more notifications left to inspect.
+         *
+         * @param mixed $notifiable
+         * @param string $notification
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasSent($notifiable, $notification)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\NotificationFake $instance */
+                        return $instance->hasSent($notifiable, $notification);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Support\Testing\Fakes\NotificationFake::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Support\Testing\Fakes\NotificationFake::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Support\Testing\Fakes\NotificationFake::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @method static mixed reset(array $credentials, \Closure $callback)
+     * @method static string sendResetLink(array $credentials)
+     * @method static \Illuminate\Contracts\Auth\CanResetPassword getUser(array $credentials)
+     * @method static string createToken(\Illuminate\Contracts\Auth\CanResetPassword $user)
+     * @method static void deleteToken(\Illuminate\Contracts\Auth\CanResetPassword $user)
+     * @method static bool tokenExists(\Illuminate\Contracts\Auth\CanResetPassword $user, string $token)
+     * @method static \Illuminate\Auth\Passwords\TokenRepositoryInterface getRepository()
+     * @see \Illuminate\Auth\Passwords\PasswordBroker
+     */ 
+        class Password {
+                    /**
+         * Attempt to get the broker from the local cache.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Contracts\Auth\PasswordBroker 
+         * @static 
+         */ 
+        public static function broker($name = null)
+        {
+                        /** @var \Illuminate\Auth\Passwords\PasswordBrokerManager $instance */
+                        return $instance->broker($name);
+        }
+                    /**
+         * Get the default password broker name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Auth\Passwords\PasswordBrokerManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the default password broker name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Auth\Passwords\PasswordBrokerManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Queue\QueueManager
+     * @see \Illuminate\Queue\Queue
+     */ 
+        class Queue {
+                    /**
+         * Register an event listener for the before job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function before($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->before($callback);
+        }
+                    /**
+         * Register an event listener for the after job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function after($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->after($callback);
+        }
+                    /**
+         * Register an event listener for the exception occurred job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function exceptionOccurred($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->exceptionOccurred($callback);
+        }
+                    /**
+         * Register an event listener for the daemon queue loop.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function looping($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->looping($callback);
+        }
+                    /**
+         * Register an event listener for the failed job event.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function failing($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->failing($callback);
+        }
+                    /**
+         * Register an event listener for the daemon queue stopping.
+         *
+         * @param mixed $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function stopping($callback)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->stopping($callback);
+        }
+                    /**
+         * Determine if the driver is connected.
+         *
+         * @param string|null $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function connected($name = null)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->connected($name);
+        }
+                    /**
+         * Resolve a queue connection instance.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Contracts\Queue\Queue 
+         * @static 
+         */ 
+        public static function connection($name = null)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->connection($name);
+        }
+                    /**
+         * Add a queue connection resolver.
+         *
+         * @param string $driver
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($driver, $resolver)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->extend($driver, $resolver);
+        }
+                    /**
+         * Add a queue connection resolver.
+         *
+         * @param string $driver
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function addConnector($driver, $resolver)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->addConnector($driver, $resolver);
+        }
+                    /**
+         * Get the name of the default queue connection.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the name of the default queue connection.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+                    /**
+         * Get the full name for the given connection.
+         *
+         * @param string|null $connection
+         * @return string 
+         * @static 
+         */ 
+        public static function getName($connection = null)
+        {
+                        /** @var \Illuminate\Queue\QueueManager $instance */
+                        return $instance->getName($connection);
+        }
+                    /**
+         * Assert if a job was pushed based on a truth-test callback.
+         *
+         * @param string|\Closure $job
+         * @param callable|int|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertPushed($job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertPushed($job, $callback);
+        }
+                    /**
+         * Assert if a job was pushed based on a truth-test callback.
+         *
+         * @param string $queue
+         * @param string|\Closure $job
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertPushedOn($queue, $job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertPushedOn($queue, $job, $callback);
+        }
+                    /**
+         * Assert if a job was pushed with chained jobs based on a truth-test callback.
+         *
+         * @param string $job
+         * @param array $expectedChain
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertPushedWithChain($job, $expectedChain = [], $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertPushedWithChain($job, $expectedChain, $callback);
+        }
+                    /**
+         * Assert if a job was pushed with an empty chain based on a truth-test callback.
+         *
+         * @param string $job
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertPushedWithoutChain($job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertPushedWithoutChain($job, $callback);
+        }
+                    /**
+         * Determine if a job was pushed based on a truth-test callback.
+         *
+         * @param string|\Closure $job
+         * @param callable|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNotPushed($job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertNotPushed($job, $callback);
+        }
+                    /**
+         * Assert that no jobs were pushed.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function assertNothingPushed()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        $instance->assertNothingPushed();
+        }
+                    /**
+         * Get all of the jobs matching a truth-test callback.
+         *
+         * @param string $job
+         * @param callable|null $callback
+         * @return \Illuminate\Support\Collection 
+         * @static 
+         */ 
+        public static function pushed($job, $callback = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pushed($job, $callback);
+        }
+                    /**
+         * Determine if there are any stored jobs for a given class.
+         *
+         * @param string $job
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasPushed($job)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->hasPushed($job);
+        }
+                    /**
+         * Get the size of the queue.
+         *
+         * @param string|null $queue
+         * @return int 
+         * @static 
+         */ 
+        public static function size($queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->size($queue);
+        }
+                    /**
+         * Push a new job onto the queue.
+         *
+         * @param string $job
+         * @param mixed $data
+         * @param string|null $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function push($job, $data = '', $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->push($job, $data, $queue);
+        }
+                    /**
+         * Push a raw payload onto the queue.
+         *
+         * @param string $payload
+         * @param string|null $queue
+         * @param array $options
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pushRaw($payload, $queue = null, $options = [])
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pushRaw($payload, $queue, $options);
+        }
+                    /**
+         * Push a new job onto the queue after a delay.
+         *
+         * @param \DateTimeInterface|\DateInterval|int $delay
+         * @param string $job
+         * @param mixed $data
+         * @param string|null $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function later($delay, $job, $data = '', $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->later($delay, $job, $data, $queue);
+        }
+                    /**
+         * Push a new job onto the queue.
+         *
+         * @param string $queue
+         * @param string $job
+         * @param mixed $data
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pushOn($queue, $job, $data = '')
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pushOn($queue, $job, $data);
+        }
+                    /**
+         * Push a new job onto the queue after a delay.
+         *
+         * @param string $queue
+         * @param \DateTimeInterface|\DateInterval|int $delay
+         * @param string $job
+         * @param mixed $data
+         * @return mixed 
+         * @static 
+         */ 
+        public static function laterOn($queue, $delay, $job, $data = '')
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->laterOn($queue, $delay, $job, $data);
+        }
+                    /**
+         * Pop the next job off of the queue.
+         *
+         * @param string|null $queue
+         * @return \Illuminate\Contracts\Queue\Job|null 
+         * @static 
+         */ 
+        public static function pop($queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pop($queue);
+        }
+                    /**
+         * Push an array of jobs onto the queue.
+         *
+         * @param array $jobs
+         * @param mixed $data
+         * @param string|null $queue
+         * @return mixed 
+         * @static 
+         */ 
+        public static function bulk($jobs, $data = '', $queue = null)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->bulk($jobs, $data, $queue);
+        }
+                    /**
+         * Get the jobs that have been pushed.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function pushedJobs()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->pushedJobs();
+        }
+                    /**
+         * Get the connection name for the queue.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getConnectionName()
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->getConnectionName();
+        }
+                    /**
+         * Set the connection name for the queue.
+         *
+         * @param string $name
+         * @return \Illuminate\Support\Testing\Fakes\QueueFake 
+         * @static 
+         */ 
+        public static function setConnectionName($name)
+        {
+                        /** @var \Illuminate\Support\Testing\Fakes\QueueFake $instance */
+                        return $instance->setConnectionName($name);
+        }
+                    /**
+         * Get the retry delay for an object-based queue handler.
+         *
+         * @param mixed $job
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getJobRetryDelay($job)
+        {            //Method inherited from \Illuminate\Queue\Queue         
+                        /** @var \Illuminate\Queue\SyncQueue $instance */
+                        return $instance->getJobRetryDelay($job);
+        }
+                    /**
+         * Get the expiration timestamp for an object-based queue handler.
+         *
+         * @param mixed $job
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getJobExpiration($job)
+        {            //Method inherited from \Illuminate\Queue\Queue         
+                        /** @var \Illuminate\Queue\SyncQueue $instance */
+                        return $instance->getJobExpiration($job);
+        }
+                    /**
+         * Register a callback to be executed when creating job payloads.
+         *
+         * @param callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function createPayloadUsing($callback)
+        {            //Method inherited from \Illuminate\Queue\Queue         
+                        \Illuminate\Queue\SyncQueue::createPayloadUsing($callback);
+        }
+                    /**
+         * Set the IoC container instance.
+         *
+         * @param \Illuminate\Container\Container $container
+         * @return void 
+         * @static 
+         */ 
+        public static function setContainer($container)
+        {            //Method inherited from \Illuminate\Queue\Queue         
+                        /** @var \Illuminate\Queue\SyncQueue $instance */
+                        $instance->setContainer($container);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Routing\Redirector
+     */ 
+        class Redirect {
+                    /**
+         * Create a new redirect response to the "home" route.
+         *
+         * @param int $status
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function home($status = 302)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->home($status);
+        }
+                    /**
+         * Create a new redirect response to the previous location.
+         *
+         * @param int $status
+         * @param array $headers
+         * @param mixed $fallback
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function back($status = 302, $headers = [], $fallback = false)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->back($status, $headers, $fallback);
+        }
+                    /**
+         * Create a new redirect response to the current URI.
+         *
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function refresh($status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->refresh($status, $headers);
+        }
+                    /**
+         * Create a new redirect response, while putting the current URL in the session.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function guest($path, $status = 302, $headers = [], $secure = null)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->guest($path, $status, $headers, $secure);
+        }
+                    /**
+         * Create a new redirect response to the previously intended location.
+         *
+         * @param string $default
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function intended($default = '/', $status = 302, $headers = [], $secure = null)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->intended($default, $status, $headers, $secure);
+        }
+                    /**
+         * Set the intended url.
+         *
+         * @param string $url
+         * @return void 
+         * @static 
+         */ 
+        public static function setIntendedUrl($url)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        $instance->setIntendedUrl($url);
+        }
+                    /**
+         * Create a new redirect response to the given path.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function to($path, $status = 302, $headers = [], $secure = null)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->to($path, $status, $headers, $secure);
+        }
+                    /**
+         * Create a new redirect response to an external URL (no validation).
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function away($path, $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->away($path, $status, $headers);
+        }
+                    /**
+         * Create a new redirect response to the given HTTPS path.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function secure($path, $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->secure($path, $status, $headers);
+        }
+                    /**
+         * Create a new redirect response to a named route.
+         *
+         * @param string $route
+         * @param mixed $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function route($route, $parameters = [], $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->route($route, $parameters, $status, $headers);
+        }
+                    /**
+         * Create a new redirect response to a signed named route.
+         *
+         * @param string $route
+         * @param mixed $parameters
+         * @param \DateTimeInterface|\DateInterval|int|null $expiration
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function signedRoute($route, $parameters = [], $expiration = null, $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->signedRoute($route, $parameters, $expiration, $status, $headers);
+        }
+                    /**
+         * Create a new redirect response to a signed named route.
+         *
+         * @param string $route
+         * @param \DateTimeInterface|\DateInterval|int|null $expiration
+         * @param mixed $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function temporarySignedRoute($route, $expiration, $parameters = [], $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->temporarySignedRoute($route, $expiration, $parameters, $status, $headers);
+        }
+                    /**
+         * Create a new redirect response to a controller action.
+         *
+         * @param string|array $action
+         * @param mixed $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function action($action, $parameters = [], $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->action($action, $parameters, $status, $headers);
+        }
+                    /**
+         * Get the URL generator instance.
+         *
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function getUrlGenerator()
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        return $instance->getUrlGenerator();
+        }
+                    /**
+         * Set the active session store.
+         *
+         * @param \Illuminate\Session\Store $session
+         * @return void 
+         * @static 
+         */ 
+        public static function setSession($session)
+        {
+                        /** @var \Illuminate\Routing\Redirector $instance */
+                        $instance->setSession($session);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\Redirector::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Routing\Redirector::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\Redirector::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @method static \Illuminate\Redis\Limiters\ConcurrencyLimiterBuilder funnel(string $name)
+     * @method static \Illuminate\Redis\Limiters\DurationLimiterBuilder throttle(string $name)
+     * @see \Illuminate\Redis\RedisManager
+     * @see \Illuminate\Contracts\Redis\Factory
+     */ 
+        class Redis {
+                    /**
+         * Get a Redis connection by name.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Redis\Connections\Connection 
+         * @static 
+         */ 
+        public static function connection($name = null)
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        return $instance->connection($name);
+        }
+                    /**
+         * Resolve the given connection by name.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Redis\Connections\Connection 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function resolve($name = null)
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        return $instance->resolve($name);
+        }
+                    /**
+         * Return all of the created connections.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function connections()
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        return $instance->connections();
+        }
+                    /**
+         * Enable the firing of Redis command events.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function enableEvents()
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        $instance->enableEvents();
+        }
+                    /**
+         * Disable the firing of Redis command events.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function disableEvents()
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        $instance->disableEvents();
+        }
+                    /**
+         * Set the default driver.
+         *
+         * @param string $driver
+         * @return void 
+         * @static 
+         */ 
+        public static function setDriver($driver)
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        $instance->setDriver($driver);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Redis\RedisManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Redis\RedisManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @method static mixed filterFiles(mixed $files)
+     * @see \Illuminate\Http\Request
+     */ 
+        class Request {
+                    /**
+         * Create a new Illuminate HTTP request from server variables.
+         *
+         * @return static 
+         * @static 
+         */ 
+        public static function capture()
+        {
+                        return \Illuminate\Http\Request::capture();
+        }
+                    /**
+         * Return the Request instance.
+         *
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function instance()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->instance();
+        }
+                    /**
+         * Get the request method.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function method()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->method();
+        }
+                    /**
+         * Get the root URL for the application.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function root()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->root();
+        }
+                    /**
+         * Get the URL (no query string) for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function url()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->url();
+        }
+                    /**
+         * Get the full URL for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function fullUrl()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fullUrl();
+        }
+                    /**
+         * Get the full URL for the request with the added query string parameters.
+         *
+         * @param array $query
+         * @return string 
+         * @static 
+         */ 
+        public static function fullUrlWithQuery($query)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fullUrlWithQuery($query);
+        }
+                    /**
+         * Get the current path info for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function path()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->path();
+        }
+                    /**
+         * Get the current decoded path info for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function decodedPath()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->decodedPath();
+        }
+                    /**
+         * Get a segment from the URI (1 based index).
+         *
+         * @param int $index
+         * @param string|null $default
+         * @return string|null 
+         * @static 
+         */ 
+        public static function segment($index, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->segment($index, $default);
+        }
+                    /**
+         * Get all of the segments for the request path.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function segments()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->segments();
+        }
+                    /**
+         * Determine if the current request URI matches a pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function is(...$patterns)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->is(...$patterns);
+        }
+                    /**
+         * Determine if the route name matches a given pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function routeIs(...$patterns)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->routeIs(...$patterns);
+        }
+                    /**
+         * Determine if the current request URL and query string matches a pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function fullUrlIs(...$patterns)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fullUrlIs(...$patterns);
+        }
+                    /**
+         * Determine if the request is the result of an AJAX call.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function ajax()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->ajax();
+        }
+                    /**
+         * Determine if the request is the result of an PJAX call.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function pjax()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->pjax();
+        }
+                    /**
+         * Determine if the request is the result of an prefetch call.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function prefetch()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->prefetch();
+        }
+                    /**
+         * Determine if the request is over HTTPS.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function secure()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->secure();
+        }
+                    /**
+         * Get the client IP address.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function ip()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->ip();
+        }
+                    /**
+         * Get the client IP addresses.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function ips()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->ips();
+        }
+                    /**
+         * Get the client user agent.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function userAgent()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->userAgent();
+        }
+                    /**
+         * Merge new input into the current request's input array.
+         *
+         * @param array $input
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function merge($input)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->merge($input);
+        }
+                    /**
+         * Replace the input for the current request.
+         *
+         * @param array $input
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function replace($input)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->replace($input);
+        }
+                    /**
+         * This method belongs to Symfony HttpFoundation and is not usually needed when using Laravel.
+         * 
+         * Instead, you may use the "input" method.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->get($key, $default);
+        }
+                    /**
+         * Get the JSON payload for the request.
+         *
+         * @param string|null $key
+         * @param mixed $default
+         * @return \Symfony\Component\HttpFoundation\ParameterBag|mixed 
+         * @static 
+         */ 
+        public static function json($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->json($key, $default);
+        }
+                    /**
+         * Create a new request instance from the given Laravel request.
+         *
+         * @param \Illuminate\Http\Request $from
+         * @param \Illuminate\Http\Request|null $to
+         * @return static 
+         * @static 
+         */ 
+        public static function createFrom($from, $to = null)
+        {
+                        return \Illuminate\Http\Request::createFrom($from, $to);
+        }
+                    /**
+         * Create an Illuminate request from a Symfony instance.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @return static 
+         * @static 
+         */ 
+        public static function createFromBase($request)
+        {
+                        return \Illuminate\Http\Request::createFromBase($request);
+        }
+                    /**
+         * Clones a request and overrides some of its parameters.
+         *
+         * @param array $query The GET parameters
+         * @param array $request The POST parameters
+         * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+         * @param array $cookies The COOKIE parameters
+         * @param array $files The FILES parameters
+         * @param array $server The SERVER parameters
+         * @return static 
+         * @static 
+         */ 
+        public static function duplicate($query = null, $request = null, $attributes = null, $cookies = null, $files = null, $server = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->duplicate($query, $request, $attributes, $cookies, $files, $server);
+        }
+                    /**
+         * Get the session associated with the request.
+         *
+         * @return \Illuminate\Session\Store 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function session()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->session();
+        }
+                    /**
+         * Get the session associated with the request.
+         *
+         * @return \Illuminate\Session\Store|null 
+         * @static 
+         */ 
+        public static function getSession()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getSession();
+        }
+                    /**
+         * Set the session instance on the request.
+         *
+         * @param \Illuminate\Contracts\Session\Session $session
+         * @return void 
+         * @static 
+         */ 
+        public static function setLaravelSession($session)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->setLaravelSession($session);
+        }
+                    /**
+         * Get the user making the request.
+         *
+         * @param string|null $guard
+         * @return mixed 
+         * @static 
+         */ 
+        public static function user($guard = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->user($guard);
+        }
+                    /**
+         * Get the route handling the request.
+         *
+         * @param string|null $param
+         * @param mixed $default
+         * @return \Illuminate\Routing\Route|object|string|null 
+         * @static 
+         */ 
+        public static function route($param = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->route($param, $default);
+        }
+                    /**
+         * Get a unique fingerprint for the request / route / IP address.
+         *
+         * @return string 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function fingerprint()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->fingerprint();
+        }
+                    /**
+         * Set the JSON payload for the request.
+         *
+         * @param \Symfony\Component\HttpFoundation\ParameterBag $json
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function setJson($json)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setJson($json);
+        }
+                    /**
+         * Get the user resolver callback.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function getUserResolver()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUserResolver();
+        }
+                    /**
+         * Set the user resolver callback.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function setUserResolver($callback)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setUserResolver($callback);
+        }
+                    /**
+         * Get the route resolver callback.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function getRouteResolver()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRouteResolver();
+        }
+                    /**
+         * Set the route resolver callback.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function setRouteResolver($callback)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setRouteResolver($callback);
+        }
+                    /**
+         * Get all of the input and files for the request.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function toArray()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->toArray();
+        }
+                    /**
+         * Determine if the given offset exists.
+         *
+         * @param string $offset
+         * @return bool 
+         * @static 
+         */ 
+        public static function offsetExists($offset)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->offsetExists($offset);
+        }
+                    /**
+         * Get the value at the given offset.
+         *
+         * @param string $offset
+         * @return mixed 
+         * @static 
+         */ 
+        public static function offsetGet($offset)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->offsetGet($offset);
+        }
+                    /**
+         * Set the value at the given offset.
+         *
+         * @param string $offset
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetSet($offset, $value)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->offsetSet($offset, $value);
+        }
+                    /**
+         * Remove the value at the given offset.
+         *
+         * @param string $offset
+         * @return void 
+         * @static 
+         */ 
+        public static function offsetUnset($offset)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->offsetUnset($offset);
+        }
+                    /**
+         * Sets the parameters for this request.
+         * 
+         * This method also re-initializes all properties.
+         *
+         * @param array $query The GET parameters
+         * @param array $request The POST parameters
+         * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+         * @param array $cookies The COOKIE parameters
+         * @param array $files The FILES parameters
+         * @param array $server The SERVER parameters
+         * @param string|resource|null $content The raw body data
+         * @static 
+         */ 
+        public static function initialize($query = [], $request = [], $attributes = [], $cookies = [], $files = [], $server = [], $content = null)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
+        }
+                    /**
+         * Creates a new request with values from PHP's super globals.
+         *
+         * @return static 
+         * @static 
+         */ 
+        public static function createFromGlobals()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::createFromGlobals();
+        }
+                    /**
+         * Creates a Request based on a given URI and configuration.
+         * 
+         * The information contained in the URI always take precedence
+         * over the other information (server and parameters).
+         *
+         * @param string $uri The URI
+         * @param string $method The HTTP method
+         * @param array $parameters The query (GET) or request (POST) parameters
+         * @param array $cookies The request cookies ($_COOKIE)
+         * @param array $files The request files ($_FILES)
+         * @param array $server The server parameters ($_SERVER)
+         * @param string|resource|null $content The raw body data
+         * @return static 
+         * @static 
+         */ 
+        public static function create($uri, $method = 'GET', $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::create($uri, $method, $parameters, $cookies, $files, $server, $content);
+        }
+                    /**
+         * Sets a callable able to create a Request instance.
+         * 
+         * This is mainly useful when you need to override the Request class
+         * to keep BC with an existing system. It should not be used for any
+         * other purpose.
+         *
+         * @static 
+         */ 
+        public static function setFactory($callable)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::setFactory($callable);
+        }
+                    /**
+         * Overrides the PHP global variables according to this request instance.
+         * 
+         * It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
+         * $_FILES is never overridden, see rfc1867
+         *
+         * @static 
+         */ 
+        public static function overrideGlobals()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->overrideGlobals();
+        }
+                    /**
+         * Sets a list of trusted proxies.
+         * 
+         * You should only list the reverse proxies that you manage directly.
+         *
+         * @param array $proxies A list of trusted proxies, the string 'REMOTE_ADDR' will be replaced with $_SERVER['REMOTE_ADDR']
+         * @param int $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies
+         * @throws \InvalidArgumentException When $trustedHeaderSet is invalid
+         * @static 
+         */ 
+        public static function setTrustedProxies($proxies, $trustedHeaderSet)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::setTrustedProxies($proxies, $trustedHeaderSet);
+        }
+                    /**
+         * Gets the list of trusted proxies.
+         *
+         * @return array An array of trusted proxies
+         * @static 
+         */ 
+        public static function getTrustedProxies()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::getTrustedProxies();
+        }
+                    /**
+         * Gets the set of trusted headers from trusted proxies.
+         *
+         * @return int A bit field of Request::HEADER_* that defines which headers are trusted from your proxies
+         * @static 
+         */ 
+        public static function getTrustedHeaderSet()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::getTrustedHeaderSet();
+        }
+                    /**
+         * Sets a list of trusted host patterns.
+         * 
+         * You should only list the hosts you manage using regexs.
+         *
+         * @param array $hostPatterns A list of trusted host patterns
+         * @static 
+         */ 
+        public static function setTrustedHosts($hostPatterns)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::setTrustedHosts($hostPatterns);
+        }
+                    /**
+         * Gets the list of trusted host patterns.
+         *
+         * @return array An array of trusted host patterns
+         * @static 
+         */ 
+        public static function getTrustedHosts()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::getTrustedHosts();
+        }
+                    /**
+         * Normalizes a query string.
+         * 
+         * It builds a normalized query string, where keys/value pairs are alphabetized,
+         * have consistent escaping and unneeded delimiters are removed.
+         *
+         * @return string A normalized query string for the Request
+         * @static 
+         */ 
+        public static function normalizeQueryString($qs)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::normalizeQueryString($qs);
+        }
+                    /**
+         * Enables support for the _method request parameter to determine the intended HTTP method.
+         * 
+         * Be warned that enabling this feature might lead to CSRF issues in your code.
+         * Check that you are using CSRF tokens when required.
+         * If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered
+         * and used to send a "PUT" or "DELETE" request via the _method request parameter.
+         * If these methods are not protected against CSRF, this presents a possible vulnerability.
+         * 
+         * The HTTP method can only be overridden when the real HTTP method is POST.
+         *
+         * @static 
+         */ 
+        public static function enableHttpMethodParameterOverride()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::enableHttpMethodParameterOverride();
+        }
+                    /**
+         * Checks whether support for the _method request parameter is enabled.
+         *
+         * @return bool True when the _method request parameter is enabled, false otherwise
+         * @static 
+         */ 
+        public static function getHttpMethodParameterOverride()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::getHttpMethodParameterOverride();
+        }
+                    /**
+         * Whether the request contains a Session which was started in one of the
+         * previous requests.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasPreviousSession()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasPreviousSession();
+        }
+                    /**
+         * Whether the request contains a Session object.
+         * 
+         * This method does not give any information about the state of the session object,
+         * like whether the session is started or not. It is just a way to check if this Request
+         * is associated with a Session instance.
+         *
+         * @return bool true when the Request contains a Session object, false otherwise
+         * @static 
+         */ 
+        public static function hasSession()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasSession();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function setSession($session)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setSession($session);
+        }
+                    /**
+         * 
+         *
+         * @internal 
+         * @static 
+         */ 
+        public static function setSessionFactory($factory)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setSessionFactory($factory);
+        }
+                    /**
+         * Returns the client IP addresses.
+         * 
+         * In the returned array the most trusted IP address is first, and the
+         * least trusted one last. The "real" client IP address is the last one,
+         * but this is also the least trusted one. Trusted proxies are stripped.
+         * 
+         * Use this method carefully; you should use getClientIp() instead.
+         *
+         * @return array The client IP addresses
+         * @see getClientIp()
+         * @static 
+         */ 
+        public static function getClientIps()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getClientIps();
+        }
+                    /**
+         * Returns the client IP address.
+         * 
+         * This method can read the client IP address from the "X-Forwarded-For" header
+         * when trusted proxies were set via "setTrustedProxies()". The "X-Forwarded-For"
+         * header value is a comma+space separated list of IP addresses, the left-most
+         * being the original client, and each successive proxy that passed the request
+         * adding the IP address where it received the request from.
+         * 
+         * If your reverse proxy uses a different header name than "X-Forwarded-For",
+         * ("Client-Ip" for instance), configure it via the $trustedHeaderSet
+         * argument of the Request::setTrustedProxies() method instead.
+         *
+         * @return string|null The client IP address
+         * @see getClientIps()
+         * @see https://wikipedia.org/wiki/X-Forwarded-For
+         * @static 
+         */ 
+        public static function getClientIp()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getClientIp();
+        }
+                    /**
+         * Returns current script name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getScriptName()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getScriptName();
+        }
+                    /**
+         * Returns the path being requested relative to the executed script.
+         * 
+         * The path info always starts with a /.
+         * 
+         * Suppose this request is instantiated from /mysite on localhost:
+         * 
+         *  * http://localhost/mysite              returns an empty string
+         *  * http://localhost/mysite/about        returns '/about'
+         *  * http://localhost/mysite/enco%20ded   returns '/enco%20ded'
+         *  * http://localhost/mysite/about?var=1  returns '/about'
+         *
+         * @return string The raw path (i.e. not urldecoded)
+         * @static 
+         */ 
+        public static function getPathInfo()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPathInfo();
+        }
+                    /**
+         * Returns the root path from which this request is executed.
+         * 
+         * Suppose that an index.php file instantiates this request object:
+         * 
+         *  * http://localhost/index.php         returns an empty string
+         *  * http://localhost/index.php/page    returns an empty string
+         *  * http://localhost/web/index.php     returns '/web'
+         *  * http://localhost/we%20b/index.php  returns '/we%20b'
+         *
+         * @return string The raw path (i.e. not urldecoded)
+         * @static 
+         */ 
+        public static function getBasePath()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getBasePath();
+        }
+                    /**
+         * Returns the root URL from which this request is executed.
+         * 
+         * The base URL never ends with a /.
+         * 
+         * This is similar to getBasePath(), except that it also includes the
+         * script filename (e.g. index.php) if one exists.
+         *
+         * @return string The raw URL (i.e. not urldecoded)
+         * @static 
+         */ 
+        public static function getBaseUrl()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getBaseUrl();
+        }
+                    /**
+         * Gets the request's scheme.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getScheme()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getScheme();
+        }
+                    /**
+         * Returns the port on which the request is made.
+         * 
+         * This method can read the client port from the "X-Forwarded-Port" header
+         * when trusted proxies were set via "setTrustedProxies()".
+         * 
+         * The "X-Forwarded-Port" header must contain the client port.
+         *
+         * @return int|string can be a string if fetched from the server bag
+         * @static 
+         */ 
+        public static function getPort()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPort();
+        }
+                    /**
+         * Returns the user.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function getUser()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUser();
+        }
+                    /**
+         * Returns the password.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function getPassword()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPassword();
+        }
+                    /**
+         * Gets the user info.
+         *
+         * @return string A user name and, optionally, scheme-specific information about how to gain authorization to access the server
+         * @static 
+         */ 
+        public static function getUserInfo()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUserInfo();
+        }
+                    /**
+         * Returns the HTTP host being requested.
+         * 
+         * The port name will be appended to the host if it's non-standard.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getHttpHost()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getHttpHost();
+        }
+                    /**
+         * Returns the requested URI (path and query string).
+         *
+         * @return string The raw URI (i.e. not URI decoded)
+         * @static 
+         */ 
+        public static function getRequestUri()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRequestUri();
+        }
+                    /**
+         * Gets the scheme and HTTP host.
+         * 
+         * If the URL was called with basic authentication, the user
+         * and the password are not added to the generated string.
+         *
+         * @return string The scheme and HTTP host
+         * @static 
+         */ 
+        public static function getSchemeAndHttpHost()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getSchemeAndHttpHost();
+        }
+                    /**
+         * Generates a normalized URI (URL) for the Request.
+         *
+         * @return string A normalized URI (URL) for the Request
+         * @see getQueryString()
+         * @static 
+         */ 
+        public static function getUri()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUri();
+        }
+                    /**
+         * Generates a normalized URI for the given path.
+         *
+         * @param string $path A path to use instead of the current one
+         * @return string The normalized URI for the path
+         * @static 
+         */ 
+        public static function getUriForPath($path)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getUriForPath($path);
+        }
+                    /**
+         * Returns the path as relative reference from the current Request path.
+         * 
+         * Only the URIs path component (no schema, host etc.) is relevant and must be given.
+         * Both paths must be absolute and not contain relative parts.
+         * Relative URLs from one resource to another are useful when generating self-contained downloadable document archives.
+         * Furthermore, they can be used to reduce the link size in documents.
+         * 
+         * Example target paths, given a base path of "/a/b/c/d":
+         * - "/a/b/c/d"     -> ""
+         * - "/a/b/c/"      -> "./"
+         * - "/a/b/"        -> "../"
+         * - "/a/b/c/other" -> "other"
+         * - "/a/x/y"       -> "../../x/y"
+         *
+         * @return string The relative target path
+         * @static 
+         */ 
+        public static function getRelativeUriForPath($path)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRelativeUriForPath($path);
+        }
+                    /**
+         * Generates the normalized query string for the Request.
+         * 
+         * It builds a normalized query string, where keys/value pairs are alphabetized
+         * and have consistent escaping.
+         *
+         * @return string|null A normalized query string for the Request
+         * @static 
+         */ 
+        public static function getQueryString()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getQueryString();
+        }
+                    /**
+         * Checks whether the request is secure or not.
+         * 
+         * This method can read the client protocol from the "X-Forwarded-Proto" header
+         * when trusted proxies were set via "setTrustedProxies()".
+         * 
+         * The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isSecure()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isSecure();
+        }
+                    /**
+         * Returns the host name.
+         * 
+         * This method can read the client host name from the "X-Forwarded-Host" header
+         * when trusted proxies were set via "setTrustedProxies()".
+         * 
+         * The "X-Forwarded-Host" header must contain the client host name.
+         *
+         * @return string 
+         * @throws SuspiciousOperationException when the host name is invalid or not trusted
+         * @static 
+         */ 
+        public static function getHost()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getHost();
+        }
+                    /**
+         * Sets the request method.
+         *
+         * @static 
+         */ 
+        public static function setMethod($method)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setMethod($method);
+        }
+                    /**
+         * Gets the request "intended" method.
+         * 
+         * If the X-HTTP-Method-Override header is set, and if the method is a POST,
+         * then it is used to determine the "real" intended HTTP method.
+         * 
+         * The _method request parameter can also be used to determine the HTTP method,
+         * but only if enableHttpMethodParameterOverride() has been called.
+         * 
+         * The method is always an uppercased string.
+         *
+         * @return string The request method
+         * @see getRealMethod()
+         * @static 
+         */ 
+        public static function getMethod()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getMethod();
+        }
+                    /**
+         * Gets the "real" request method.
+         *
+         * @return string The request method
+         * @see getMethod()
+         * @static 
+         */ 
+        public static function getRealMethod()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRealMethod();
+        }
+                    /**
+         * Gets the mime type associated with the format.
+         *
+         * @return string|null The associated mime type (null if not found)
+         * @static 
+         */ 
+        public static function getMimeType($format)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getMimeType($format);
+        }
+                    /**
+         * Gets the mime types associated with the format.
+         *
+         * @return array The associated mime types
+         * @static 
+         */ 
+        public static function getMimeTypes($format)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        return \Illuminate\Http\Request::getMimeTypes($format);
+        }
+                    /**
+         * Gets the format associated with the mime type.
+         *
+         * @return string|null The format (null if not found)
+         * @static 
+         */ 
+        public static function getFormat($mimeType)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getFormat($mimeType);
+        }
+                    /**
+         * Associates a format with mime types.
+         *
+         * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type)
+         * @static 
+         */ 
+        public static function setFormat($format, $mimeTypes)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setFormat($format, $mimeTypes);
+        }
+                    /**
+         * Gets the request format.
+         * 
+         * Here is the process to determine the format:
+         * 
+         *  * format defined by the user (with setRequestFormat())
+         *  * _format request attribute
+         *  * $default
+         *
+         * @see getPreferredFormat
+         * @return string|null The request format
+         * @static 
+         */ 
+        public static function getRequestFormat($default = 'html')
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getRequestFormat($default);
+        }
+                    /**
+         * Sets the request format.
+         *
+         * @static 
+         */ 
+        public static function setRequestFormat($format)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setRequestFormat($format);
+        }
+                    /**
+         * Gets the format associated with the request.
+         *
+         * @return string|null The format (null if no content type is present)
+         * @static 
+         */ 
+        public static function getContentType()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getContentType();
+        }
+                    /**
+         * Sets the default locale.
+         *
+         * @static 
+         */ 
+        public static function setDefaultLocale($locale)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setDefaultLocale($locale);
+        }
+                    /**
+         * Get the default locale.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultLocale()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getDefaultLocale();
+        }
+                    /**
+         * Sets the locale.
+         *
+         * @static 
+         */ 
+        public static function setLocale($locale)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->setLocale($locale);
+        }
+                    /**
+         * Get the locale.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLocale()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getLocale();
+        }
+                    /**
+         * Checks if the request method is of specified type.
+         *
+         * @param string $method Uppercase request method (GET, POST etc)
+         * @return bool 
+         * @static 
+         */ 
+        public static function isMethod($method)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethod($method);
+        }
+                    /**
+         * Checks whether or not the method is safe.
+         *
+         * @see https://tools.ietf.org/html/rfc7231#section-4.2.1
+         * @return bool 
+         * @static 
+         */ 
+        public static function isMethodSafe()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethodSafe();
+        }
+                    /**
+         * Checks whether or not the method is idempotent.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isMethodIdempotent()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethodIdempotent();
+        }
+                    /**
+         * Checks whether the method is cacheable or not.
+         *
+         * @see https://tools.ietf.org/html/rfc7231#section-4.2.3
+         * @return bool True for GET and HEAD, false otherwise
+         * @static 
+         */ 
+        public static function isMethodCacheable()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isMethodCacheable();
+        }
+                    /**
+         * Returns the protocol version.
+         * 
+         * If the application is behind a proxy, the protocol version used in the
+         * requests between the client and the proxy and between the proxy and the
+         * server might be different. This returns the former (from the "Via" header)
+         * if the proxy is trusted (see "setTrustedProxies()"), otherwise it returns
+         * the latter (from the "SERVER_PROTOCOL" server parameter).
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getProtocolVersion()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getProtocolVersion();
+        }
+                    /**
+         * Returns the request body content.
+         *
+         * @param bool $asResource If true, a resource will be returned
+         * @return string|resource The request body content or a resource to read the body stream
+         * @throws \LogicException
+         * @static 
+         */ 
+        public static function getContent($asResource = false)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getContent($asResource);
+        }
+                    /**
+         * Gets the Etags.
+         *
+         * @return array The entity tags
+         * @static 
+         */ 
+        public static function getETags()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getETags();
+        }
+                    /**
+         * 
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isNoCache()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isNoCache();
+        }
+                    /**
+         * Gets the preferred format for the response by inspecting, in the following order:
+         *   * the request format set using setRequestFormat;
+         *   * the values of the Accept HTTP header.
+         * 
+         * Note that if you use this method, you should send the "Vary: Accept" header
+         * in the response to prevent any issues with intermediary HTTP caches.
+         *
+         * @static 
+         */ 
+        public static function getPreferredFormat($default = 'html')
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPreferredFormat($default);
+        }
+                    /**
+         * Returns the preferred language.
+         *
+         * @param string[] $locales An array of ordered available locales
+         * @return string|null The preferred locale
+         * @static 
+         */ 
+        public static function getPreferredLanguage($locales = null)
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getPreferredLanguage($locales);
+        }
+                    /**
+         * Gets a list of languages acceptable by the client browser.
+         *
+         * @return array Languages ordered in the user browser preferences
+         * @static 
+         */ 
+        public static function getLanguages()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getLanguages();
+        }
+                    /**
+         * Gets a list of charsets acceptable by the client browser.
+         *
+         * @return array List of charsets in preferable order
+         * @static 
+         */ 
+        public static function getCharsets()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getCharsets();
+        }
+                    /**
+         * Gets a list of encodings acceptable by the client browser.
+         *
+         * @return array List of encodings in preferable order
+         * @static 
+         */ 
+        public static function getEncodings()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getEncodings();
+        }
+                    /**
+         * Gets a list of content types acceptable by the client browser.
+         *
+         * @return array List of content types in preferable order
+         * @static 
+         */ 
+        public static function getAcceptableContentTypes()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->getAcceptableContentTypes();
+        }
+                    /**
+         * Returns true if the request is a XMLHttpRequest.
+         * 
+         * It works if your JavaScript library sets an X-Requested-With HTTP header.
+         * It is known to work with common JavaScript frameworks:
+         *
+         * @see https://wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
+         * @return bool true if the request is an XMLHttpRequest, false otherwise
+         * @static 
+         */ 
+        public static function isXmlHttpRequest()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isXmlHttpRequest();
+        }
+                    /**
+         * Checks whether the client browser prefers safe content or not according to RFC8674.
+         *
+         * @see https://tools.ietf.org/html/rfc8674
+         * @static 
+         */ 
+        public static function preferSafeContent()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->preferSafeContent();
+        }
+                    /**
+         * Indicates whether this request originated from a trusted proxy.
+         * 
+         * This can be useful to determine whether or not to trust the
+         * contents of a proxy-specific header.
+         *
+         * @return bool true if the request came from a trusted proxy, false otherwise
+         * @static 
+         */ 
+        public static function isFromTrustedProxy()
+        {            //Method inherited from \Symfony\Component\HttpFoundation\Request         
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isFromTrustedProxy();
+        }
+                    /**
+         * Determine if the given content types match.
+         *
+         * @param string $actual
+         * @param string $type
+         * @return bool 
+         * @static 
+         */ 
+        public static function matchesType($actual, $type)
+        {
+                        return \Illuminate\Http\Request::matchesType($actual, $type);
+        }
+                    /**
+         * Determine if the request is sending JSON.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isJson();
+        }
+                    /**
+         * Determine if the current request probably expects a JSON response.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function expectsJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->expectsJson();
+        }
+                    /**
+         * Determine if the current request is asking for JSON.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function wantsJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->wantsJson();
+        }
+                    /**
+         * Determines whether the current requests accepts a given content type.
+         *
+         * @param string|array $contentTypes
+         * @return bool 
+         * @static 
+         */ 
+        public static function accepts($contentTypes)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->accepts($contentTypes);
+        }
+                    /**
+         * Return the most suitable content type from the given array based on content negotiation.
+         *
+         * @param string|array $contentTypes
+         * @return string|null 
+         * @static 
+         */ 
+        public static function prefers($contentTypes)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->prefers($contentTypes);
+        }
+                    /**
+         * Determine if the current request accepts any content type.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function acceptsAnyContentType()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->acceptsAnyContentType();
+        }
+                    /**
+         * Determines whether a request accepts JSON.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function acceptsJson()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->acceptsJson();
+        }
+                    /**
+         * Determines whether a request accepts HTML.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function acceptsHtml()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->acceptsHtml();
+        }
+                    /**
+         * Get the data format expected in the response.
+         *
+         * @param string $default
+         * @return string 
+         * @static 
+         */ 
+        public static function format($default = 'html')
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->format($default);
+        }
+                    /**
+         * Retrieve an old input item.
+         *
+         * @param string|null $key
+         * @param string|array|null $default
+         * @return string|array 
+         * @static 
+         */ 
+        public static function old($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->old($key, $default);
+        }
+                    /**
+         * Flash the input for the current request to the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flash()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flash();
+        }
+                    /**
+         * Flash only some of the input to the session.
+         *
+         * @param array|mixed $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function flashOnly($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flashOnly($keys);
+        }
+                    /**
+         * Flash only some of the input to the session.
+         *
+         * @param array|mixed $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function flashExcept($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flashExcept($keys);
+        }
+                    /**
+         * Flush all of the old input from the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        $instance->flush();
+        }
+                    /**
+         * Retrieve a server variable from the request.
+         *
+         * @param string|null $key
+         * @param string|array|null $default
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function server($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->server($key, $default);
+        }
+                    /**
+         * Determine if a header is set on the request.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasHeader($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasHeader($key);
+        }
+                    /**
+         * Retrieve a header from the request.
+         *
+         * @param string|null $key
+         * @param string|array|null $default
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function header($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->header($key, $default);
+        }
+                    /**
+         * Get the bearer token from the request headers.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function bearerToken()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->bearerToken();
+        }
+                    /**
+         * Determine if the request contains a given input item key.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->exists($key);
+        }
+                    /**
+         * Determine if the request contains a given input item key.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->has($key);
+        }
+                    /**
+         * Determine if the request contains any of the given inputs.
+         *
+         * @param string|array $keys
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasAny($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasAny($keys);
+        }
+                    /**
+         * Apply the callback if the request contains the given input item key.
+         *
+         * @param string $key
+         * @param callable $callback
+         * @return $this|mixed 
+         * @static 
+         */ 
+        public static function whenHas($key, $callback)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->whenHas($key, $callback);
+        }
+                    /**
+         * Determine if the request contains a non-empty value for an input item.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function filled($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->filled($key);
+        }
+                    /**
+         * Determine if the request contains an empty value for an input item.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function isNotFilled($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->isNotFilled($key);
+        }
+                    /**
+         * Determine if the request contains a non-empty value for any of the given inputs.
+         *
+         * @param string|array $keys
+         * @return bool 
+         * @static 
+         */ 
+        public static function anyFilled($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->anyFilled($keys);
+        }
+                    /**
+         * Apply the callback if the request contains a non-empty value for the given input item key.
+         *
+         * @param string $key
+         * @param callable $callback
+         * @return $this|mixed 
+         * @static 
+         */ 
+        public static function whenFilled($key, $callback)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->whenFilled($key, $callback);
+        }
+                    /**
+         * Determine if the request is missing a given input item key.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function missing($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->missing($key);
+        }
+                    /**
+         * Get the keys for all of the input and files.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function keys()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->keys();
+        }
+                    /**
+         * Get all of the input and files for the request.
+         *
+         * @param array|mixed|null $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function all($keys = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->all($keys);
+        }
+                    /**
+         * Retrieve an input item from the request.
+         *
+         * @param string|null $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function input($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->input($key, $default);
+        }
+                    /**
+         * Retrieve input as a boolean value.
+         * 
+         * Returns true when value is "1", "true", "on", and "yes". Otherwise, returns false.
+         *
+         * @param string|null $key
+         * @param bool $default
+         * @return bool 
+         * @static 
+         */ 
+        public static function boolean($key = null, $default = false)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->boolean($key, $default);
+        }
+                    /**
+         * Get a subset containing the provided keys with values from the input data.
+         *
+         * @param array|mixed $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function only($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->only($keys);
+        }
+                    /**
+         * Get all of the input except for a specified array of items.
+         *
+         * @param array|mixed $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function except($keys)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->except($keys);
+        }
+                    /**
+         * Retrieve a query string item from the request.
+         *
+         * @param string|null $key
+         * @param string|array|null $default
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function query($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->query($key, $default);
+        }
+                    /**
+         * Retrieve a request payload item from the request.
+         *
+         * @param string|null $key
+         * @param string|array|null $default
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function post($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->post($key, $default);
+        }
+                    /**
+         * Determine if a cookie is set on the request.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasCookie($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasCookie($key);
+        }
+                    /**
+         * Retrieve a cookie from the request.
+         *
+         * @param string|null $key
+         * @param string|array|null $default
+         * @return string|array|null 
+         * @static 
+         */ 
+        public static function cookie($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->cookie($key, $default);
+        }
+                    /**
+         * Get an array of all of the files on the request.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function allFiles()
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->allFiles();
+        }
+                    /**
+         * Determine if the uploaded data contains a file.
+         *
+         * @param string $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasFile($key)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->hasFile($key);
+        }
+                    /**
+         * Retrieve a file from the request.
+         *
+         * @param string|null $key
+         * @param mixed $default
+         * @return \Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|array|null 
+         * @static 
+         */ 
+        public static function file($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Http\Request $instance */
+                        return $instance->file($key, $default);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Http\Request::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Http\Request::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Http\Request::hasMacro($name);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function validate($rules, ...$params)
+        {
+                        return \Illuminate\Http\Request::validate($rules, ...$params);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function validateWithBag($errorBag, $rules, ...$params)
+        {
+                        return \Illuminate\Http\Request::validateWithBag($errorBag, $rules, ...$params);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function hasValidSignature($absolute = true)
+        {
+                        return \Illuminate\Http\Request::hasValidSignature($absolute);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Contracts\Routing\ResponseFactory
+     */ 
+        class Response {
+                    /**
+         * Create a new response instance.
+         *
+         * @param string $content
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\Response 
+         * @static 
+         */ 
+        public static function make($content = '', $status = 200, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->make($content, $status, $headers);
+        }
+                    /**
+         * Create a new "no content" response.
+         *
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\Response 
+         * @static 
+         */ 
+        public static function noContent($status = 204, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->noContent($status, $headers);
+        }
+                    /**
+         * Create a new response for a given view.
+         *
+         * @param string|array $view
+         * @param array $data
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\Response 
+         * @static 
+         */ 
+        public static function view($view, $data = [], $status = 200, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->view($view, $data, $status, $headers);
+        }
+                    /**
+         * Create a new JSON response instance.
+         *
+         * @param mixed $data
+         * @param int $status
+         * @param array $headers
+         * @param int $options
+         * @return \Illuminate\Http\JsonResponse 
+         * @static 
+         */ 
+        public static function json($data = [], $status = 200, $headers = [], $options = 0)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->json($data, $status, $headers, $options);
+        }
+                    /**
+         * Create a new JSONP response instance.
+         *
+         * @param string $callback
+         * @param mixed $data
+         * @param int $status
+         * @param array $headers
+         * @param int $options
+         * @return \Illuminate\Http\JsonResponse 
+         * @static 
+         */ 
+        public static function jsonp($callback, $data = [], $status = 200, $headers = [], $options = 0)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->jsonp($callback, $data, $status, $headers, $options);
+        }
+                    /**
+         * Create a new streamed response instance.
+         *
+         * @param \Closure $callback
+         * @param int $status
+         * @param array $headers
+         * @return \Symfony\Component\HttpFoundation\StreamedResponse 
+         * @static 
+         */ 
+        public static function stream($callback, $status = 200, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->stream($callback, $status, $headers);
+        }
+                    /**
+         * Create a new streamed response instance as a file download.
+         *
+         * @param \Closure $callback
+         * @param string|null $name
+         * @param array $headers
+         * @param string|null $disposition
+         * @return \Symfony\Component\HttpFoundation\StreamedResponse 
+         * @static 
+         */ 
+        public static function streamDownload($callback, $name = null, $headers = [], $disposition = 'attachment')
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->streamDownload($callback, $name, $headers, $disposition);
+        }
+                    /**
+         * Create a new file download response.
+         *
+         * @param \SplFileInfo|string $file
+         * @param string|null $name
+         * @param array $headers
+         * @param string|null $disposition
+         * @return \Symfony\Component\HttpFoundation\BinaryFileResponse 
+         * @static 
+         */ 
+        public static function download($file, $name = null, $headers = [], $disposition = 'attachment')
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->download($file, $name, $headers, $disposition);
+        }
+                    /**
+         * Return the raw contents of a binary file.
+         *
+         * @param \SplFileInfo|string $file
+         * @param array $headers
+         * @return \Symfony\Component\HttpFoundation\BinaryFileResponse 
+         * @static 
+         */ 
+        public static function file($file, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->file($file, $headers);
+        }
+                    /**
+         * Create a new redirect response to the given path.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectTo($path, $status = 302, $headers = [], $secure = null)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectTo($path, $status, $headers, $secure);
+        }
+                    /**
+         * Create a new redirect response to a named route.
+         *
+         * @param string $route
+         * @param mixed $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectToRoute($route, $parameters = [], $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectToRoute($route, $parameters, $status, $headers);
+        }
+                    /**
+         * Create a new redirect response to a controller action.
+         *
+         * @param string $action
+         * @param mixed $parameters
+         * @param int $status
+         * @param array $headers
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectToAction($action, $parameters = [], $status = 302, $headers = [])
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectToAction($action, $parameters, $status, $headers);
+        }
+                    /**
+         * Create a new redirect response, while putting the current URL in the session.
+         *
+         * @param string $path
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectGuest($path, $status = 302, $headers = [], $secure = null)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectGuest($path, $status, $headers, $secure);
+        }
+                    /**
+         * Create a new redirect response to the previously intended location.
+         *
+         * @param string $default
+         * @param int $status
+         * @param array $headers
+         * @param bool|null $secure
+         * @return \Illuminate\Http\RedirectResponse 
+         * @static 
+         */ 
+        public static function redirectToIntended($default = '/', $status = 302, $headers = [], $secure = null)
+        {
+                        /** @var \Illuminate\Routing\ResponseFactory $instance */
+                        return $instance->redirectToIntended($default, $status, $headers, $secure);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\ResponseFactory::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Routing\ResponseFactory::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\ResponseFactory::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @method static \Illuminate\Routing\RouteRegistrar as(string $value)
+     * @method static \Illuminate\Routing\RouteRegistrar domain(string $value)
+     * @method static \Illuminate\Routing\RouteRegistrar middleware(array|string|null $middleware)
+     * @method static \Illuminate\Routing\RouteRegistrar name(string $value)
+     * @method static \Illuminate\Routing\RouteRegistrar namespace(string $value)
+     * @method static \Illuminate\Routing\RouteRegistrar prefix(string  $prefix)
+     * @method static \Illuminate\Routing\RouteRegistrar where(array  $where)
+     * @see \Illuminate\Routing\Router
+     */ 
+        class Route {
+                    /**
+         * Register a new GET route with the router.
+         *
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function get($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->get($uri, $action);
+        }
+                    /**
+         * Register a new POST route with the router.
+         *
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function post($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->post($uri, $action);
+        }
+                    /**
+         * Register a new PUT route with the router.
+         *
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function put($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->put($uri, $action);
+        }
+                    /**
+         * Register a new PATCH route with the router.
+         *
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function patch($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->patch($uri, $action);
+        }
+                    /**
+         * Register a new DELETE route with the router.
+         *
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function delete($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->delete($uri, $action);
+        }
+                    /**
+         * Register a new OPTIONS route with the router.
+         *
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function options($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->options($uri, $action);
+        }
+                    /**
+         * Register a new route responding to all verbs.
+         *
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function any($uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->any($uri, $action);
+        }
+                    /**
+         * Register a new Fallback route with the router.
+         *
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function fallback($action)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->fallback($action);
+        }
+                    /**
+         * Create a redirect from one URI to another.
+         *
+         * @param string $uri
+         * @param string $destination
+         * @param int $status
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function redirect($uri, $destination, $status = 302)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->redirect($uri, $destination, $status);
+        }
+                    /**
+         * Create a permanent redirect from one URI to another.
+         *
+         * @param string $uri
+         * @param string $destination
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function permanentRedirect($uri, $destination)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->permanentRedirect($uri, $destination);
+        }
+                    /**
+         * Register a new route that returns a view.
+         *
+         * @param string $uri
+         * @param string $view
+         * @param array $data
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function view($uri, $view, $data = [])
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->view($uri, $view, $data);
+        }
+                    /**
+         * Register a new route with the given verbs.
+         *
+         * @param array|string $methods
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function match($methods, $uri, $action = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->match($methods, $uri, $action);
+        }
+                    /**
+         * Register an array of resource controllers.
+         *
+         * @param array $resources
+         * @param array $options
+         * @return void 
+         * @static 
+         */ 
+        public static function resources($resources, $options = [])
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->resources($resources, $options);
+        }
+                    /**
+         * Route a resource to a controller.
+         *
+         * @param string $name
+         * @param string $controller
+         * @param array $options
+         * @return \Illuminate\Routing\PendingResourceRegistration 
+         * @static 
+         */ 
+        public static function resource($name, $controller, $options = [])
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->resource($name, $controller, $options);
+        }
+                    /**
+         * Register an array of API resource controllers.
+         *
+         * @param array $resources
+         * @param array $options
+         * @return void 
+         * @static 
+         */ 
+        public static function apiResources($resources, $options = [])
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->apiResources($resources, $options);
+        }
+                    /**
+         * Route an API resource to a controller.
+         *
+         * @param string $name
+         * @param string $controller
+         * @param array $options
+         * @return \Illuminate\Routing\PendingResourceRegistration 
+         * @static 
+         */ 
+        public static function apiResource($name, $controller, $options = [])
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->apiResource($name, $controller, $options);
+        }
+                    /**
+         * Create a route group with shared attributes.
+         *
+         * @param array $attributes
+         * @param \Closure|string $routes
+         * @return void 
+         * @static 
+         */ 
+        public static function group($attributes, $routes)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->group($attributes, $routes);
+        }
+                    /**
+         * Merge the given array with the last group stack.
+         *
+         * @param array $new
+         * @param bool $prependExistingPrefix
+         * @return array 
+         * @static 
+         */ 
+        public static function mergeWithLastGroup($new, $prependExistingPrefix = true)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->mergeWithLastGroup($new, $prependExistingPrefix);
+        }
+                    /**
+         * Get the prefix from the last group on the stack.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getLastGroupPrefix()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getLastGroupPrefix();
+        }
+                    /**
+         * Add a route to the underlying route collection.
+         *
+         * @param array|string $methods
+         * @param string $uri
+         * @param array|string|callable|null $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function addRoute($methods, $uri, $action)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->addRoute($methods, $uri, $action);
+        }
+                    /**
+         * Create a new Route object.
+         *
+         * @param array|string $methods
+         * @param string $uri
+         * @param mixed $action
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function newRoute($methods, $uri, $action)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->newRoute($methods, $uri, $action);
+        }
+                    /**
+         * Return the response returned by the given route.
+         *
+         * @param string $name
+         * @return \Symfony\Component\HttpFoundation\Response 
+         * @static 
+         */ 
+        public static function respondWithRoute($name)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->respondWithRoute($name);
+        }
+                    /**
+         * Dispatch the request to the application.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return \Symfony\Component\HttpFoundation\Response 
+         * @static 
+         */ 
+        public static function dispatch($request)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->dispatch($request);
+        }
+                    /**
+         * Dispatch the request to a route and return the response.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return \Symfony\Component\HttpFoundation\Response 
+         * @static 
+         */ 
+        public static function dispatchToRoute($request)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->dispatchToRoute($request);
+        }
+                    /**
+         * Gather the middleware for the given route with resolved class names.
+         *
+         * @param \Illuminate\Routing\Route $route
+         * @return array 
+         * @static 
+         */ 
+        public static function gatherRouteMiddleware($route)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->gatherRouteMiddleware($route);
+        }
+                    /**
+         * Create a response instance from the given value.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @param mixed $response
+         * @return \Symfony\Component\HttpFoundation\Response 
+         * @static 
+         */ 
+        public static function prepareResponse($request, $response)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->prepareResponse($request, $response);
+        }
+                    /**
+         * Static version of prepareResponse.
+         *
+         * @param \Symfony\Component\HttpFoundation\Request $request
+         * @param mixed $response
+         * @return \Symfony\Component\HttpFoundation\Response 
+         * @static 
+         */ 
+        public static function toResponse($request, $response)
+        {
+                        return \Illuminate\Routing\Router::toResponse($request, $response);
+        }
+                    /**
+         * Substitute the route bindings onto the route.
+         *
+         * @param \Illuminate\Routing\Route $route
+         * @return \Illuminate\Routing\Route 
+         * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+         * @static 
+         */ 
+        public static function substituteBindings($route)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->substituteBindings($route);
+        }
+                    /**
+         * Substitute the implicit Eloquent model bindings for the route.
+         *
+         * @param \Illuminate\Routing\Route $route
+         * @return void 
+         * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+         * @static 
+         */ 
+        public static function substituteImplicitBindings($route)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->substituteImplicitBindings($route);
+        }
+                    /**
+         * Register a route matched event listener.
+         *
+         * @param string|callable $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function matched($callback)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->matched($callback);
+        }
+                    /**
+         * Get all of the defined middleware short-hand names.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getMiddleware()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getMiddleware();
+        }
+                    /**
+         * Register a short-hand name for a middleware.
+         *
+         * @param string $name
+         * @param string $class
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function aliasMiddleware($name, $class)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->aliasMiddleware($name, $class);
+        }
+                    /**
+         * Check if a middlewareGroup with the given name exists.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMiddlewareGroup($name)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->hasMiddlewareGroup($name);
+        }
+                    /**
+         * Get all of the defined middleware groups.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getMiddlewareGroups()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getMiddlewareGroups();
+        }
+                    /**
+         * Register a group of middleware.
+         *
+         * @param string $name
+         * @param array $middleware
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function middlewareGroup($name, $middleware)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->middlewareGroup($name, $middleware);
+        }
+                    /**
+         * Add a middleware to the beginning of a middleware group.
+         * 
+         * If the middleware is already in the group, it will not be added again.
+         *
+         * @param string $group
+         * @param string $middleware
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function prependMiddlewareToGroup($group, $middleware)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->prependMiddlewareToGroup($group, $middleware);
+        }
+                    /**
+         * Add a middleware to the end of a middleware group.
+         * 
+         * If the middleware is already in the group, it will not be added again.
+         *
+         * @param string $group
+         * @param string $middleware
+         * @return \Illuminate\Routing\Router 
+         * @static 
+         */ 
+        public static function pushMiddlewareToGroup($group, $middleware)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->pushMiddlewareToGroup($group, $middleware);
+        }
+                    /**
+         * Add a new route parameter binder.
+         *
+         * @param string $key
+         * @param string|callable $binder
+         * @return void 
+         * @static 
+         */ 
+        public static function bind($key, $binder)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->bind($key, $binder);
+        }
+                    /**
+         * Register a model binder for a wildcard.
+         *
+         * @param string $key
+         * @param string $class
+         * @param \Closure|null $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function model($key, $class, $callback = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->model($key, $class, $callback);
+        }
+                    /**
+         * Get the binding callback for a given binding.
+         *
+         * @param string $key
+         * @return \Closure|null 
+         * @static 
+         */ 
+        public static function getBindingCallback($key)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getBindingCallback($key);
+        }
+                    /**
+         * Get the global "where" patterns.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getPatterns()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getPatterns();
+        }
+                    /**
+         * Set a global where pattern on all routes.
+         *
+         * @param string $key
+         * @param string $pattern
+         * @return void 
+         * @static 
+         */ 
+        public static function pattern($key, $pattern)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->pattern($key, $pattern);
+        }
+                    /**
+         * Set a group of global where patterns on all routes.
+         *
+         * @param array $patterns
+         * @return void 
+         * @static 
+         */ 
+        public static function patterns($patterns)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->patterns($patterns);
+        }
+                    /**
+         * Determine if the router currently has a group stack.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasGroupStack()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->hasGroupStack();
+        }
+                    /**
+         * Get the current group stack for the router.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getGroupStack()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getGroupStack();
+        }
+                    /**
+         * Get a route parameter for the current route.
+         *
+         * @param string $key
+         * @param string|null $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function input($key, $default = null)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->input($key, $default);
+        }
+                    /**
+         * Get the request currently being dispatched.
+         *
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function getCurrentRequest()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getCurrentRequest();
+        }
+                    /**
+         * Get the currently dispatched route instance.
+         *
+         * @return \Illuminate\Routing\Route 
+         * @static 
+         */ 
+        public static function getCurrentRoute()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getCurrentRoute();
+        }
+                    /**
+         * Get the currently dispatched route instance.
+         *
+         * @return \Illuminate\Routing\Route|null 
+         * @static 
+         */ 
+        public static function current()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->current();
+        }
+                    /**
+         * Check if a route with the given name exists.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($name)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->has($name);
+        }
+                    /**
+         * Get the current route name.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function currentRouteName()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteName();
+        }
+                    /**
+         * Alias for the "currentRouteNamed" method.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function is(...$patterns)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->is(...$patterns);
+        }
+                    /**
+         * Determine if the current route matches a pattern.
+         *
+         * @param mixed $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function currentRouteNamed(...$patterns)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteNamed(...$patterns);
+        }
+                    /**
+         * Get the current route action.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function currentRouteAction()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteAction();
+        }
+                    /**
+         * Alias for the "currentRouteUses" method.
+         *
+         * @param array $patterns
+         * @return bool 
+         * @static 
+         */ 
+        public static function uses(...$patterns)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->uses(...$patterns);
+        }
+                    /**
+         * Determine if the current route action matches a given action.
+         *
+         * @param string $action
+         * @return bool 
+         * @static 
+         */ 
+        public static function currentRouteUses($action)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->currentRouteUses($action);
+        }
+                    /**
+         * Set the unmapped global resource parameters to singular.
+         *
+         * @param bool $singular
+         * @return void 
+         * @static 
+         */ 
+        public static function singularResourceParameters($singular = true)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->singularResourceParameters($singular);
+        }
+                    /**
+         * Set the global resource parameter mapping.
+         *
+         * @param array $parameters
+         * @return void 
+         * @static 
+         */ 
+        public static function resourceParameters($parameters = [])
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->resourceParameters($parameters);
+        }
+                    /**
+         * Get or set the verbs used in the resource URIs.
+         *
+         * @param array $verbs
+         * @return array|null 
+         * @static 
+         */ 
+        public static function resourceVerbs($verbs = [])
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->resourceVerbs($verbs);
+        }
+                    /**
+         * Get the underlying route collection.
+         *
+         * @return \Illuminate\Routing\RouteCollectionInterface 
+         * @static 
+         */ 
+        public static function getRoutes()
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->getRoutes();
+        }
+                    /**
+         * Set the route collection instance.
+         *
+         * @param \Illuminate\Routing\RouteCollection $routes
+         * @return void 
+         * @static 
+         */ 
+        public static function setRoutes($routes)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->setRoutes($routes);
+        }
+                    /**
+         * Set the compiled route collection instance.
+         *
+         * @param array $routes
+         * @return void 
+         * @static 
+         */ 
+        public static function setCompiledRoutes($routes)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        $instance->setCompiledRoutes($routes);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\Router::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Routing\Router::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\Router::hasMacro($name);
+        }
+                    /**
+         * Dynamically handle calls to the class.
+         *
+         * @param string $method
+         * @param array $parameters
+         * @return mixed 
+         * @throws \BadMethodCallException
+         * @static 
+         */ 
+        public static function macroCall($method, $parameters)
+        {
+                        /** @var \Illuminate\Routing\Router $instance */
+                        return $instance->macroCall($method, $parameters);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Database\Schema\Builder
+     */ 
+        class Schema {
+                    /**
+         * Determine if the given table exists.
+         *
+         * @param string $table
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasTable($table)
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->hasTable($table);
+        }
+                    /**
+         * Get the column listing for a given table.
+         *
+         * @param string $table
+         * @return array 
+         * @static 
+         */ 
+        public static function getColumnListing($table)
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getColumnListing($table);
+        }
+                    /**
+         * Drop all tables from the database.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function dropAllTables()
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->dropAllTables();
+        }
+                    /**
+         * Drop all views from the database.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function dropAllViews()
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->dropAllViews();
+        }
+                    /**
+         * Get all of the table names for the database.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getAllTables()
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getAllTables();
+        }
+                    /**
+         * Get all of the view names for the database.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getAllViews()
+        {
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getAllViews();
+        }
+                    /**
+         * Set the default string length for migrations.
+         *
+         * @param int $length
+         * @return void 
+         * @static 
+         */ 
+        public static function defaultStringLength($length)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        \Illuminate\Database\Schema\MySqlBuilder::defaultStringLength($length);
+        }
+                    /**
+         * Determine if the given table has a given column.
+         *
+         * @param string $table
+         * @param string $column
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasColumn($table, $column)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->hasColumn($table, $column);
+        }
+                    /**
+         * Determine if the given table has given columns.
+         *
+         * @param string $table
+         * @param array $columns
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasColumns($table, $columns)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->hasColumns($table, $columns);
+        }
+                    /**
+         * Get the data type for the given column name.
+         *
+         * @param string $table
+         * @param string $column
+         * @return string 
+         * @static 
+         */ 
+        public static function getColumnType($table, $column)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getColumnType($table, $column);
+        }
+                    /**
+         * Modify a table on the schema.
+         *
+         * @param string $table
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function table($table, $callback)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->table($table, $callback);
+        }
+                    /**
+         * Create a new table on the schema.
+         *
+         * @param string $table
+         * @param \Closure $callback
+         * @return void 
+         * @static 
+         */ 
+        public static function create($table, $callback)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->create($table, $callback);
+        }
+                    /**
+         * Drop a table from the schema.
+         *
+         * @param string $table
+         * @return void 
+         * @static 
+         */ 
+        public static function drop($table)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->drop($table);
+        }
+                    /**
+         * Drop a table from the schema if it exists.
+         *
+         * @param string $table
+         * @return void 
+         * @static 
+         */ 
+        public static function dropIfExists($table)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->dropIfExists($table);
+        }
+                    /**
+         * Drop all types from the database.
+         *
+         * @return void 
+         * @throws \LogicException
+         * @static 
+         */ 
+        public static function dropAllTypes()
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->dropAllTypes();
+        }
+                    /**
+         * Rename a table on the schema.
+         *
+         * @param string $from
+         * @param string $to
+         * @return void 
+         * @static 
+         */ 
+        public static function rename($from, $to)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->rename($from, $to);
+        }
+                    /**
+         * Enable foreign key constraints.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function enableForeignKeyConstraints()
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->enableForeignKeyConstraints();
+        }
+                    /**
+         * Disable foreign key constraints.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function disableForeignKeyConstraints()
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->disableForeignKeyConstraints();
+        }
+                    /**
+         * Register a custom Doctrine mapping type.
+         *
+         * @param string $class
+         * @param string $name
+         * @param string $type
+         * @return void 
+         * @throws \Doctrine\DBAL\DBALException
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function registerCustomDoctrineType($class, $name, $type)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->registerCustomDoctrineType($class, $name, $type);
+        }
+                    /**
+         * Get the database connection instance.
+         *
+         * @return \Illuminate\Database\Connection 
+         * @static 
+         */ 
+        public static function getConnection()
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->getConnection();
+        }
+                    /**
+         * Set the database connection instance.
+         *
+         * @param \Illuminate\Database\Connection $connection
+         * @return \Illuminate\Database\Schema\MySqlBuilder 
+         * @static 
+         */ 
+        public static function setConnection($connection)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        return $instance->setConnection($connection);
+        }
+                    /**
+         * Set the Schema Blueprint resolver callback.
+         *
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function blueprintResolver($resolver)
+        {            //Method inherited from \Illuminate\Database\Schema\Builder         
+                        /** @var \Illuminate\Database\Schema\MySqlBuilder $instance */
+                        $instance->blueprintResolver($resolver);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Session\SessionManager
+     * @see \Illuminate\Session\Store
+     */ 
+        class Session {
+                    /**
+         * Determine if requests for the same session should wait for each to finish before executing.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function shouldBlock()
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->shouldBlock();
+        }
+                    /**
+         * Get the name of the cache store / driver that should be used to acquire session locks.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function blockDriver()
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->blockDriver();
+        }
+                    /**
+         * Get the session configuration.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getSessionConfig()
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->getSessionConfig();
+        }
+                    /**
+         * Get the default session driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Set the default session driver name.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setDefaultDriver($name)
+        {
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        $instance->setDefaultDriver($name);
+        }
+                    /**
+         * Get a driver instance.
+         *
+         * @param string|null $driver
+         * @return mixed 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function driver($driver = null)
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->driver($driver);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Session\SessionManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Get all of the created "drivers".
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDrivers()
+        {            //Method inherited from \Illuminate\Support\Manager         
+                        /** @var \Illuminate\Session\SessionManager $instance */
+                        return $instance->getDrivers();
+        }
+                    /**
+         * Start the session, reading the data from a handler.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function start()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->start();
+        }
+                    /**
+         * Save the session data to storage.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function save()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->save();
+        }
+                    /**
+         * Age the flash data for the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function ageFlashData()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->ageFlashData();
+        }
+                    /**
+         * Get all of the session data.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function all()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->all();
+        }
+                    /**
+         * Get a subset of the session data.
+         *
+         * @param array $keys
+         * @return array 
+         * @static 
+         */ 
+        public static function only($keys)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->only($keys);
+        }
+                    /**
+         * Checks if a key exists.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($key)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->exists($key);
+        }
+                    /**
+         * Checks if a key is present and not null.
+         *
+         * @param string|array $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function has($key)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->has($key);
+        }
+                    /**
+         * Get an item from the session.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function get($key, $default = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->get($key, $default);
+        }
+                    /**
+         * Get the value of a given key and then forget it.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function pull($key, $default = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->pull($key, $default);
+        }
+                    /**
+         * Determine if the session contains old input.
+         *
+         * @param string|null $key
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasOldInput($key = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->hasOldInput($key);
+        }
+                    /**
+         * Get the requested item from the flashed input array.
+         *
+         * @param string|null $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getOldInput($key = null, $default = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getOldInput($key, $default);
+        }
+                    /**
+         * Replace the given session attributes entirely.
+         *
+         * @param array $attributes
+         * @return void 
+         * @static 
+         */ 
+        public static function replace($attributes)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->replace($attributes);
+        }
+                    /**
+         * Put a key / value pair or array of key / value pairs in the session.
+         *
+         * @param string|array $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function put($key, $value = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->put($key, $value);
+        }
+                    /**
+         * Get an item from the session, or store the default value.
+         *
+         * @param string $key
+         * @param \Closure $callback
+         * @return mixed 
+         * @static 
+         */ 
+        public static function remember($key, $callback)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->remember($key, $callback);
+        }
+                    /**
+         * Push a value onto a session array.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function push($key, $value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->push($key, $value);
+        }
+                    /**
+         * Increment the value of an item in the session.
+         *
+         * @param string $key
+         * @param int $amount
+         * @return mixed 
+         * @static 
+         */ 
+        public static function increment($key, $amount = 1)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->increment($key, $amount);
+        }
+                    /**
+         * Decrement the value of an item in the session.
+         *
+         * @param string $key
+         * @param int $amount
+         * @return int 
+         * @static 
+         */ 
+        public static function decrement($key, $amount = 1)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->decrement($key, $amount);
+        }
+                    /**
+         * Flash a key / value pair to the session.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function flash($key, $value = true)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->flash($key, $value);
+        }
+                    /**
+         * Flash a key / value pair to the session for immediate use.
+         *
+         * @param string $key
+         * @param mixed $value
+         * @return void 
+         * @static 
+         */ 
+        public static function now($key, $value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->now($key, $value);
+        }
+                    /**
+         * Reflash all of the session flash data.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function reflash()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->reflash();
+        }
+                    /**
+         * Reflash a subset of the current flash data.
+         *
+         * @param array|mixed $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function keep($keys = null)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->keep($keys);
+        }
+                    /**
+         * Flash an input array to the session.
+         *
+         * @param array $value
+         * @return void 
+         * @static 
+         */ 
+        public static function flashInput($value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->flashInput($value);
+        }
+                    /**
+         * Remove an item from the session, returning its value.
+         *
+         * @param string $key
+         * @return mixed 
+         * @static 
+         */ 
+        public static function remove($key)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->remove($key);
+        }
+                    /**
+         * Remove one or many items from the session.
+         *
+         * @param string|array $keys
+         * @return void 
+         * @static 
+         */ 
+        public static function forget($keys)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->forget($keys);
+        }
+                    /**
+         * Remove all of the items from the session.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flush()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->flush();
+        }
+                    /**
+         * Flush the session data and regenerate the ID.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function invalidate()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->invalidate();
+        }
+                    /**
+         * Generate a new session identifier.
+         *
+         * @param bool $destroy
+         * @return bool 
+         * @static 
+         */ 
+        public static function regenerate($destroy = false)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->regenerate($destroy);
+        }
+                    /**
+         * Generate a new session ID for the session.
+         *
+         * @param bool $destroy
+         * @return bool 
+         * @static 
+         */ 
+        public static function migrate($destroy = false)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->migrate($destroy);
+        }
+                    /**
+         * Determine if the session has been started.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function isStarted()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->isStarted();
+        }
+                    /**
+         * Get the name of the session.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getName()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getName();
+        }
+                    /**
+         * Set the name of the session.
+         *
+         * @param string $name
+         * @return void 
+         * @static 
+         */ 
+        public static function setName($name)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setName($name);
+        }
+                    /**
+         * Get the current session ID.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getId()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getId();
+        }
+                    /**
+         * Set the session ID.
+         *
+         * @param string $id
+         * @return void 
+         * @static 
+         */ 
+        public static function setId($id)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setId($id);
+        }
+                    /**
+         * Determine if this is a valid session ID.
+         *
+         * @param string $id
+         * @return bool 
+         * @static 
+         */ 
+        public static function isValidId($id)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->isValidId($id);
+        }
+                    /**
+         * Set the existence of the session on the handler if applicable.
+         *
+         * @param bool $value
+         * @return void 
+         * @static 
+         */ 
+        public static function setExists($value)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setExists($value);
+        }
+                    /**
+         * Get the CSRF token value.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function token()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->token();
+        }
+                    /**
+         * Regenerate the CSRF token value.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function regenerateToken()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->regenerateToken();
+        }
+                    /**
+         * Get the previous URL from the session.
+         *
+         * @return string|null 
+         * @static 
+         */ 
+        public static function previousUrl()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->previousUrl();
+        }
+                    /**
+         * Set the "previous" URL in the session.
+         *
+         * @param string $url
+         * @return void 
+         * @static 
+         */ 
+        public static function setPreviousUrl($url)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setPreviousUrl($url);
+        }
+                    /**
+         * Get the underlying session handler implementation.
+         *
+         * @return \SessionHandlerInterface 
+         * @static 
+         */ 
+        public static function getHandler()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->getHandler();
+        }
+                    /**
+         * Determine if the session handler needs a request.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function handlerNeedsRequest()
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        return $instance->handlerNeedsRequest();
+        }
+                    /**
+         * Set the request on the handler instance.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return void 
+         * @static 
+         */ 
+        public static function setRequestOnHandler($request)
+        {
+                        /** @var \Illuminate\Session\Store $instance */
+                        $instance->setRequestOnHandler($request);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Filesystem\FilesystemManager
+     */ 
+        class Storage {
+                    /**
+         * Get a filesystem instance.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function drive($name = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->drive($name);
+        }
+                    /**
+         * Get a filesystem instance.
+         *
+         * @param string|null $name
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function disk($name = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->disk($name);
+        }
+                    /**
+         * Get a default cloud filesystem instance.
+         *
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function cloud()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->cloud();
+        }
+                    /**
+         * Create an instance of the local driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function createLocalDriver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createLocalDriver($config);
+        }
+                    /**
+         * Create an instance of the ftp driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function createFtpDriver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createFtpDriver($config);
+        }
+                    /**
+         * Create an instance of the sftp driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function createSftpDriver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createSftpDriver($config);
+        }
+                    /**
+         * Create an instance of the Amazon S3 driver.
+         *
+         * @param array $config
+         * @return \Illuminate\Contracts\Filesystem\Cloud 
+         * @static 
+         */ 
+        public static function createS3Driver($config)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->createS3Driver($config);
+        }
+                    /**
+         * Set the given disk instance.
+         *
+         * @param string $name
+         * @param mixed $disk
+         * @return \Illuminate\Filesystem\FilesystemManager 
+         * @static 
+         */ 
+        public static function set($name, $disk)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->set($name, $disk);
+        }
+                    /**
+         * Get the default driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultDriver()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->getDefaultDriver();
+        }
+                    /**
+         * Get the default cloud driver name.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getDefaultCloudDriver()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->getDefaultCloudDriver();
+        }
+                    /**
+         * Unset the given disk instances.
+         *
+         * @param array|string $disk
+         * @return \Illuminate\Filesystem\FilesystemManager 
+         * @static 
+         */ 
+        public static function forgetDisk($disk)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->forgetDisk($disk);
+        }
+                    /**
+         * Register a custom driver creator Closure.
+         *
+         * @param string $driver
+         * @param \Closure $callback
+         * @return \Illuminate\Filesystem\FilesystemManager 
+         * @static 
+         */ 
+        public static function extend($driver, $callback)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemManager $instance */
+                        return $instance->extend($driver, $callback);
+        }
+                    /**
+         * Assert that the given file exists.
+         *
+         * @param string|array $path
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function assertExists($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->assertExists($path);
+        }
+                    /**
+         * Assert that the given file does not exist.
+         *
+         * @param string|array $path
+         * @return \Illuminate\Filesystem\FilesystemAdapter 
+         * @static 
+         */ 
+        public static function assertMissing($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->assertMissing($path);
+        }
+                    /**
+         * Determine if a file exists.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->exists($path);
+        }
+                    /**
+         * Determine if a file or directory is missing.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function missing($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->missing($path);
+        }
+                    /**
+         * Get the full path for the file at the given "short" path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function path($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->path($path);
+        }
+                    /**
+         * Get the contents of a file.
+         *
+         * @param string $path
+         * @return string 
+         * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+         * @static 
+         */ 
+        public static function get($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->get($path);
+        }
+                    /**
+         * Create a streamed response for a given file.
+         *
+         * @param string $path
+         * @param string|null $name
+         * @param array|null $headers
+         * @param string|null $disposition
+         * @return \Symfony\Component\HttpFoundation\StreamedResponse 
+         * @static 
+         */ 
+        public static function response($path, $name = null, $headers = [], $disposition = 'inline')
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->response($path, $name, $headers, $disposition);
+        }
+                    /**
+         * Create a streamed download response for a given file.
+         *
+         * @param string $path
+         * @param string|null $name
+         * @param array|null $headers
+         * @return \Symfony\Component\HttpFoundation\StreamedResponse 
+         * @static 
+         */ 
+        public static function download($path, $name = null, $headers = [])
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->download($path, $name, $headers);
+        }
+                    /**
+         * Write the contents of a file.
+         *
+         * @param string $path
+         * @param string|resource $contents
+         * @param mixed $options
+         * @return bool 
+         * @static 
+         */ 
+        public static function put($path, $contents, $options = [])
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->put($path, $contents, $options);
+        }
+                    /**
+         * Store the uploaded file on the disk.
+         *
+         * @param string $path
+         * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file
+         * @param mixed $options
+         * @return string|false 
+         * @static 
+         */ 
+        public static function putFile($path, $file, $options = [])
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->putFile($path, $file, $options);
+        }
+                    /**
+         * Store the uploaded file on the disk with a given name.
+         *
+         * @param string $path
+         * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file
+         * @param string $name
+         * @param mixed $options
+         * @return string|false 
+         * @static 
+         */ 
+        public static function putFileAs($path, $file, $name, $options = [])
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->putFileAs($path, $file, $name, $options);
+        }
+                    /**
+         * Get the visibility for the given path.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function getVisibility($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->getVisibility($path);
+        }
+                    /**
+         * Set the visibility for the given path.
+         *
+         * @param string $path
+         * @param string $visibility
+         * @return bool 
+         * @static 
+         */ 
+        public static function setVisibility($path, $visibility)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->setVisibility($path, $visibility);
+        }
+                    /**
+         * Prepend to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @param string $separator
+         * @return bool 
+         * @static 
+         */ 
+        public static function prepend($path, $data, $separator = '
+')
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->prepend($path, $data, $separator);
+        }
+                    /**
+         * Append to a file.
+         *
+         * @param string $path
+         * @param string $data
+         * @param string $separator
+         * @return bool 
+         * @static 
+         */ 
+        public static function append($path, $data, $separator = '
+')
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->append($path, $data, $separator);
+        }
+                    /**
+         * Delete the file at a given path.
+         *
+         * @param string|array $paths
+         * @return bool 
+         * @static 
+         */ 
+        public static function delete($paths)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->delete($paths);
+        }
+                    /**
+         * Copy a file to a new location.
+         *
+         * @param string $from
+         * @param string $to
+         * @return bool 
+         * @static 
+         */ 
+        public static function copy($from, $to)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->copy($from, $to);
+        }
+                    /**
+         * Move a file to a new location.
+         *
+         * @param string $from
+         * @param string $to
+         * @return bool 
+         * @static 
+         */ 
+        public static function move($from, $to)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->move($from, $to);
+        }
+                    /**
+         * Get the file size of a given file.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function size($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->size($path);
+        }
+                    /**
+         * Get the mime-type of a given file.
+         *
+         * @param string $path
+         * @return string|false 
+         * @static 
+         */ 
+        public static function mimeType($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->mimeType($path);
+        }
+                    /**
+         * Get the file's last modification time.
+         *
+         * @param string $path
+         * @return int 
+         * @static 
+         */ 
+        public static function lastModified($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->lastModified($path);
+        }
+                    /**
+         * Get the URL for the file at the given path.
+         *
+         * @param string $path
+         * @return string 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function url($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->url($path);
+        }
+                    /**
+         * Get a resource to read the file.
+         *
+         * @param string $path
+         * @return resource|null The path resource or null on failure.
+         * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
+         * @static 
+         */ 
+        public static function readStream($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->readStream($path);
+        }
+                    /**
+         * Write a new file using a stream.
+         *
+         * @param string $path
+         * @param resource $resource
+         * @param array $options
+         * @return bool 
+         * @throws \InvalidArgumentException If $resource is not a file handle.
+         * @throws \Illuminate\Contracts\Filesystem\FileExistsException
+         * @static 
+         */ 
+        public static function writeStream($path, $resource, $options = [])
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->writeStream($path, $resource, $options);
+        }
+                    /**
+         * Get a temporary URL for the file at the given path.
+         *
+         * @param string $path
+         * @param \DateTimeInterface $expiration
+         * @param array $options
+         * @return string 
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function temporaryUrl($path, $expiration, $options = [])
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->temporaryUrl($path, $expiration, $options);
+        }
+                    /**
+         * Get a temporary URL for the file at the given path.
+         *
+         * @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter
+         * @param string $path
+         * @param \DateTimeInterface $expiration
+         * @param array $options
+         * @return string 
+         * @static 
+         */ 
+        public static function getAwsTemporaryUrl($adapter, $path, $expiration, $options)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->getAwsTemporaryUrl($adapter, $path, $expiration, $options);
+        }
+                    /**
+         * Get an array of all files in a directory.
+         *
+         * @param string|null $directory
+         * @param bool $recursive
+         * @return array 
+         * @static 
+         */ 
+        public static function files($directory = null, $recursive = false)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->files($directory, $recursive);
+        }
+                    /**
+         * Get all of the files from the given directory (recursive).
+         *
+         * @param string|null $directory
+         * @return array 
+         * @static 
+         */ 
+        public static function allFiles($directory = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->allFiles($directory);
+        }
+                    /**
+         * Get all of the directories within a given directory.
+         *
+         * @param string|null $directory
+         * @param bool $recursive
+         * @return array 
+         * @static 
+         */ 
+        public static function directories($directory = null, $recursive = false)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->directories($directory, $recursive);
+        }
+                    /**
+         * Get all (recursive) of the directories within a given directory.
+         *
+         * @param string|null $directory
+         * @return array 
+         * @static 
+         */ 
+        public static function allDirectories($directory = null)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->allDirectories($directory);
+        }
+                    /**
+         * Create a directory.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function makeDirectory($path)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->makeDirectory($path);
+        }
+                    /**
+         * Recursively delete a directory.
+         *
+         * @param string $directory
+         * @return bool 
+         * @static 
+         */ 
+        public static function deleteDirectory($directory)
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->deleteDirectory($directory);
+        }
+                    /**
+         * Flush the Flysystem cache.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushCache()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        $instance->flushCache();
+        }
+                    /**
+         * Get the Flysystem driver.
+         *
+         * @return \League\Flysystem\FilesystemInterface 
+         * @static 
+         */ 
+        public static function getDriver()
+        {
+                        /** @var \Illuminate\Filesystem\FilesystemAdapter $instance */
+                        return $instance->getDriver();
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Routing\UrlGenerator
+     */ 
+        class URL {
+                    /**
+         * Get the full URL for the current request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function full()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->full();
+        }
+                    /**
+         * Get the current URL for the request.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function current()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->current();
+        }
+                    /**
+         * Get the URL for the previous request.
+         *
+         * @param mixed $fallback
+         * @return string 
+         * @static 
+         */ 
+        public static function previous($fallback = false)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->previous($fallback);
+        }
+                    /**
+         * Generate an absolute URL to the given path.
+         *
+         * @param string $path
+         * @param mixed $extra
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function to($path, $extra = [], $secure = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->to($path, $extra, $secure);
+        }
+                    /**
+         * Generate a secure, absolute URL to the given path.
+         *
+         * @param string $path
+         * @param array $parameters
+         * @return string 
+         * @static 
+         */ 
+        public static function secure($path, $parameters = [])
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->secure($path, $parameters);
+        }
+                    /**
+         * Generate the URL to an application asset.
+         *
+         * @param string $path
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function asset($path, $secure = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->asset($path, $secure);
+        }
+                    /**
+         * Generate the URL to a secure asset.
+         *
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function secureAsset($path)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->secureAsset($path);
+        }
+                    /**
+         * Generate the URL to an asset from a custom root domain such as CDN, etc.
+         *
+         * @param string $root
+         * @param string $path
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function assetFrom($root, $path, $secure = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->assetFrom($root, $path, $secure);
+        }
+                    /**
+         * Get the default scheme for a raw URL.
+         *
+         * @param bool|null $secure
+         * @return string 
+         * @static 
+         */ 
+        public static function formatScheme($secure = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatScheme($secure);
+        }
+                    /**
+         * Create a signed route URL for a named route.
+         *
+         * @param string $name
+         * @param array $parameters
+         * @param \DateTimeInterface|\DateInterval|int|null $expiration
+         * @param bool $absolute
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function signedRoute($name, $parameters = [], $expiration = null, $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->signedRoute($name, $parameters, $expiration, $absolute);
+        }
+                    /**
+         * Create a temporary signed route URL for a named route.
+         *
+         * @param string $name
+         * @param \DateTimeInterface|\DateInterval|int $expiration
+         * @param array $parameters
+         * @param bool $absolute
+         * @return string 
+         * @static 
+         */ 
+        public static function temporarySignedRoute($name, $expiration, $parameters = [], $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->temporarySignedRoute($name, $expiration, $parameters, $absolute);
+        }
+                    /**
+         * Determine if the given request has a valid signature.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @param bool $absolute
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasValidSignature($request, $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->hasValidSignature($request, $absolute);
+        }
+                    /**
+         * Determine if the signature from the given request matches the URL.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @param bool $absolute
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasCorrectSignature($request, $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->hasCorrectSignature($request, $absolute);
+        }
+                    /**
+         * Determine if the expires timestamp from the given request is not from the past.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return bool 
+         * @static 
+         */ 
+        public static function signatureHasNotExpired($request)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->signatureHasNotExpired($request);
+        }
+                    /**
+         * Get the URL to a named route.
+         *
+         * @param string $name
+         * @param mixed $parameters
+         * @param bool $absolute
+         * @return string 
+         * @throws \Symfony\Component\Routing\Exception\RouteNotFoundException
+         * @static 
+         */ 
+        public static function route($name, $parameters = [], $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->route($name, $parameters, $absolute);
+        }
+                    /**
+         * Get the URL for a given route instance.
+         *
+         * @param \Illuminate\Routing\Route $route
+         * @param mixed $parameters
+         * @param bool $absolute
+         * @return string 
+         * @throws \Illuminate\Routing\Exceptions\UrlGenerationException
+         * @static 
+         */ 
+        public static function toRoute($route, $parameters, $absolute)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->toRoute($route, $parameters, $absolute);
+        }
+                    /**
+         * Get the URL to a controller action.
+         *
+         * @param string|array $action
+         * @param mixed $parameters
+         * @param bool $absolute
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function action($action, $parameters = [], $absolute = true)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->action($action, $parameters, $absolute);
+        }
+                    /**
+         * Format the array of URL parameters.
+         *
+         * @param mixed|array $parameters
+         * @return array 
+         * @static 
+         */ 
+        public static function formatParameters($parameters)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatParameters($parameters);
+        }
+                    /**
+         * Get the base URL for the request.
+         *
+         * @param string $scheme
+         * @param string|null $root
+         * @return string 
+         * @static 
+         */ 
+        public static function formatRoot($scheme, $root = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatRoot($scheme, $root);
+        }
+                    /**
+         * Format the given URL segments into a single URL.
+         *
+         * @param string $root
+         * @param string $path
+         * @param \Illuminate\Routing\Route|null $route
+         * @return string 
+         * @static 
+         */ 
+        public static function format($root, $path, $route = null)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->format($root, $path, $route);
+        }
+                    /**
+         * Determine if the given path is a valid URL.
+         *
+         * @param string $path
+         * @return bool 
+         * @static 
+         */ 
+        public static function isValidUrl($path)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->isValidUrl($path);
+        }
+                    /**
+         * Set the default named parameters used by the URL generator.
+         *
+         * @param array $defaults
+         * @return void 
+         * @static 
+         */ 
+        public static function defaults($defaults)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->defaults($defaults);
+        }
+                    /**
+         * Get the default named parameters used by the URL generator.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getDefaultParameters()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->getDefaultParameters();
+        }
+                    /**
+         * Force the scheme for URLs.
+         *
+         * @param string $scheme
+         * @return void 
+         * @static 
+         */ 
+        public static function forceScheme($scheme)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->forceScheme($scheme);
+        }
+                    /**
+         * Set the forced root URL.
+         *
+         * @param string $root
+         * @return void 
+         * @static 
+         */ 
+        public static function forceRootUrl($root)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->forceRootUrl($root);
+        }
+                    /**
+         * Set a callback to be used to format the host of generated URLs.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function formatHostUsing($callback)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatHostUsing($callback);
+        }
+                    /**
+         * Set a callback to be used to format the path of generated URLs.
+         *
+         * @param \Closure $callback
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function formatPathUsing($callback)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->formatPathUsing($callback);
+        }
+                    /**
+         * Get the path formatter being used by the URL generator.
+         *
+         * @return \Closure 
+         * @static 
+         */ 
+        public static function pathFormatter()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->pathFormatter();
+        }
+                    /**
+         * Get the request instance.
+         *
+         * @return \Illuminate\Http\Request 
+         * @static 
+         */ 
+        public static function getRequest()
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->getRequest();
+        }
+                    /**
+         * Set the current request instance.
+         *
+         * @param \Illuminate\Http\Request $request
+         * @return void 
+         * @static 
+         */ 
+        public static function setRequest($request)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        $instance->setRequest($request);
+        }
+                    /**
+         * Set the route collection.
+         *
+         * @param \Illuminate\Routing\RouteCollectionInterface $routes
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setRoutes($routes)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setRoutes($routes);
+        }
+                    /**
+         * Set the session resolver for the generator.
+         *
+         * @param callable $sessionResolver
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setSessionResolver($sessionResolver)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setSessionResolver($sessionResolver);
+        }
+                    /**
+         * Set the encryption key resolver.
+         *
+         * @param callable $keyResolver
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setKeyResolver($keyResolver)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setKeyResolver($keyResolver);
+        }
+                    /**
+         * Set the root controller namespace.
+         *
+         * @param string $rootNamespace
+         * @return \Illuminate\Routing\UrlGenerator 
+         * @static 
+         */ 
+        public static function setRootControllerNamespace($rootNamespace)
+        {
+                        /** @var \Illuminate\Routing\UrlGenerator $instance */
+                        return $instance->setRootControllerNamespace($rootNamespace);
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\Routing\UrlGenerator::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\Routing\UrlGenerator::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\Routing\UrlGenerator::hasMacro($name);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\Validation\Factory
+     */ 
+        class Validator {
+                    /**
+         * Create a new Validator instance.
+         *
+         * @param array $data
+         * @param array $rules
+         * @param array $messages
+         * @param array $customAttributes
+         * @return \Illuminate\Validation\Validator 
+         * @static 
+         */ 
+        public static function make($data, $rules, $messages = [], $customAttributes = [])
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->make($data, $rules, $messages, $customAttributes);
+        }
+                    /**
+         * Validate the given data against the provided rules.
+         *
+         * @param array $data
+         * @param array $rules
+         * @param array $messages
+         * @param array $customAttributes
+         * @return array 
+         * @throws \Illuminate\Validation\ValidationException
+         * @static 
+         */ 
+        public static function validate($data, $rules, $messages = [], $customAttributes = [])
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->validate($data, $rules, $messages, $customAttributes);
+        }
+                    /**
+         * Register a custom validator extension.
+         *
+         * @param string $rule
+         * @param \Closure|string $extension
+         * @param string|null $message
+         * @return void 
+         * @static 
+         */ 
+        public static function extend($rule, $extension, $message = null)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->extend($rule, $extension, $message);
+        }
+                    /**
+         * Register a custom implicit validator extension.
+         *
+         * @param string $rule
+         * @param \Closure|string $extension
+         * @param string|null $message
+         * @return void 
+         * @static 
+         */ 
+        public static function extendImplicit($rule, $extension, $message = null)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->extendImplicit($rule, $extension, $message);
+        }
+                    /**
+         * Register a custom dependent validator extension.
+         *
+         * @param string $rule
+         * @param \Closure|string $extension
+         * @param string|null $message
+         * @return void 
+         * @static 
+         */ 
+        public static function extendDependent($rule, $extension, $message = null)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->extendDependent($rule, $extension, $message);
+        }
+                    /**
+         * Register a custom validator message replacer.
+         *
+         * @param string $rule
+         * @param \Closure|string $replacer
+         * @return void 
+         * @static 
+         */ 
+        public static function replacer($rule, $replacer)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->replacer($rule, $replacer);
+        }
+                    /**
+         * Set the Validator instance resolver.
+         *
+         * @param \Closure $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function resolver($resolver)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->resolver($resolver);
+        }
+                    /**
+         * Get the Translator implementation.
+         *
+         * @return \Illuminate\Contracts\Translation\Translator 
+         * @static 
+         */ 
+        public static function getTranslator()
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->getTranslator();
+        }
+                    /**
+         * Get the Presence Verifier implementation.
+         *
+         * @return \Illuminate\Validation\PresenceVerifierInterface 
+         * @static 
+         */ 
+        public static function getPresenceVerifier()
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        return $instance->getPresenceVerifier();
+        }
+                    /**
+         * Set the Presence Verifier implementation.
+         *
+         * @param \Illuminate\Validation\PresenceVerifierInterface $presenceVerifier
+         * @return void 
+         * @static 
+         */ 
+        public static function setPresenceVerifier($presenceVerifier)
+        {
+                        /** @var \Illuminate\Validation\Factory $instance */
+                        $instance->setPresenceVerifier($presenceVerifier);
+        }
+         
+    }
+            /**
+     * 
+     *
+     * @see \Illuminate\View\Factory
+     */ 
+        class View {
+                    /**
+         * Get the evaluated view contents for the given view.
+         *
+         * @param string $path
+         * @param \Illuminate\Contracts\Support\Arrayable|array $data
+         * @param array $mergeData
+         * @return \Illuminate\Contracts\View\View 
+         * @static 
+         */ 
+        public static function file($path, $data = [], $mergeData = [])
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->file($path, $data, $mergeData);
+        }
+                    /**
+         * Get the evaluated view contents for the given view.
+         *
+         * @param string $view
+         * @param \Illuminate\Contracts\Support\Arrayable|array $data
+         * @param array $mergeData
+         * @return \Illuminate\Contracts\View\View 
+         * @static 
+         */ 
+        public static function make($view, $data = [], $mergeData = [])
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->make($view, $data, $mergeData);
+        }
+                    /**
+         * Get the first view that actually exists from the given list.
+         *
+         * @param array $views
+         * @param \Illuminate\Contracts\Support\Arrayable|array $data
+         * @param array $mergeData
+         * @return \Illuminate\Contracts\View\View 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function first($views, $data = [], $mergeData = [])
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->first($views, $data, $mergeData);
+        }
+                    /**
+         * Get the rendered content of the view based on a given condition.
+         *
+         * @param bool $condition
+         * @param string $view
+         * @param \Illuminate\Contracts\Support\Arrayable|array $data
+         * @param array $mergeData
+         * @return string 
+         * @static 
+         */ 
+        public static function renderWhen($condition, $view, $data = [], $mergeData = [])
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderWhen($condition, $view, $data, $mergeData);
+        }
+                    /**
+         * Get the rendered contents of a partial from a loop.
+         *
+         * @param string $view
+         * @param array $data
+         * @param string $iterator
+         * @param string $empty
+         * @return string 
+         * @static 
+         */ 
+        public static function renderEach($view, $data, $iterator, $empty = 'raw|')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderEach($view, $data, $iterator, $empty);
+        }
+                    /**
+         * Determine if a given view exists.
+         *
+         * @param string $view
+         * @return bool 
+         * @static 
+         */ 
+        public static function exists($view)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->exists($view);
+        }
+                    /**
+         * Get the appropriate view engine for the given path.
+         *
+         * @param string $path
+         * @return \Illuminate\Contracts\View\Engine 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function getEngineFromPath($path)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getEngineFromPath($path);
+        }
+                    /**
+         * Add a piece of shared data to the environment.
+         *
+         * @param array|string $key
+         * @param mixed|null $value
+         * @return mixed 
+         * @static 
+         */ 
+        public static function share($key, $value = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->share($key, $value);
+        }
+                    /**
+         * Increment the rendering counter.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function incrementRender()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->incrementRender();
+        }
+                    /**
+         * Decrement the rendering counter.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function decrementRender()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->decrementRender();
+        }
+                    /**
+         * Check if there are no active render operations.
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function doneRendering()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->doneRendering();
+        }
+                    /**
+         * Determine if the given once token has been rendered.
+         *
+         * @param string $id
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasRenderedOnce($id)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->hasRenderedOnce($id);
+        }
+                    /**
+         * Mark the given once token as having been rendered.
+         *
+         * @param string $id
+         * @return void 
+         * @static 
+         */ 
+        public static function markAsRenderedOnce($id)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->markAsRenderedOnce($id);
+        }
+                    /**
+         * Add a location to the array of view locations.
+         *
+         * @param string $location
+         * @return void 
+         * @static 
+         */ 
+        public static function addLocation($location)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->addLocation($location);
+        }
+                    /**
+         * Add a new namespace to the loader.
+         *
+         * @param string $namespace
+         * @param string|array $hints
+         * @return \Illuminate\View\Factory 
+         * @static 
+         */ 
+        public static function addNamespace($namespace, $hints)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->addNamespace($namespace, $hints);
+        }
+                    /**
+         * Prepend a new namespace to the loader.
+         *
+         * @param string $namespace
+         * @param string|array $hints
+         * @return \Illuminate\View\Factory 
+         * @static 
+         */ 
+        public static function prependNamespace($namespace, $hints)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->prependNamespace($namespace, $hints);
+        }
+                    /**
+         * Replace the namespace hints for the given namespace.
+         *
+         * @param string $namespace
+         * @param string|array $hints
+         * @return \Illuminate\View\Factory 
+         * @static 
+         */ 
+        public static function replaceNamespace($namespace, $hints)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->replaceNamespace($namespace, $hints);
+        }
+                    /**
+         * Register a valid view extension and its engine.
+         *
+         * @param string $extension
+         * @param string $engine
+         * @param \Closure|null $resolver
+         * @return void 
+         * @static 
+         */ 
+        public static function addExtension($extension, $engine, $resolver = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->addExtension($extension, $engine, $resolver);
+        }
+                    /**
+         * Flush all of the factory state like sections and stacks.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushState()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushState();
+        }
+                    /**
+         * Flush all of the section contents if done rendering.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushStateIfDoneRendering()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushStateIfDoneRendering();
+        }
+                    /**
+         * Get the extension to engine bindings.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getExtensions()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getExtensions();
+        }
+                    /**
+         * Get the engine resolver instance.
+         *
+         * @return \Illuminate\View\Engines\EngineResolver 
+         * @static 
+         */ 
+        public static function getEngineResolver()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getEngineResolver();
+        }
+                    /**
+         * Get the view finder instance.
+         *
+         * @return \Illuminate\View\ViewFinderInterface 
+         * @static 
+         */ 
+        public static function getFinder()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getFinder();
+        }
+                    /**
+         * Set the view finder instance.
+         *
+         * @param \Illuminate\View\ViewFinderInterface $finder
+         * @return void 
+         * @static 
+         */ 
+        public static function setFinder($finder)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->setFinder($finder);
+        }
+                    /**
+         * Flush the cache of views located by the finder.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushFinderCache()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushFinderCache();
+        }
+                    /**
+         * Get the event dispatcher instance.
+         *
+         * @return \Illuminate\Contracts\Events\Dispatcher 
+         * @static 
+         */ 
+        public static function getDispatcher()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getDispatcher();
+        }
+                    /**
+         * Set the event dispatcher instance.
+         *
+         * @param \Illuminate\Contracts\Events\Dispatcher $events
+         * @return void 
+         * @static 
+         */ 
+        public static function setDispatcher($events)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->setDispatcher($events);
+        }
+                    /**
+         * Get the IoC container instance.
+         *
+         * @return \Illuminate\Contracts\Container\Container 
+         * @static 
+         */ 
+        public static function getContainer()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getContainer();
+        }
+                    /**
+         * Set the IoC container instance.
+         *
+         * @param \Illuminate\Contracts\Container\Container $container
+         * @return void 
+         * @static 
+         */ 
+        public static function setContainer($container)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->setContainer($container);
+        }
+                    /**
+         * Get an item from the shared data.
+         *
+         * @param string $key
+         * @param mixed $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function shared($key, $default = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->shared($key, $default);
+        }
+                    /**
+         * Get all of the shared data for the environment.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getShared()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getShared();
+        }
+                    /**
+         * Register a custom macro.
+         *
+         * @param string $name
+         * @param object|callable $macro
+         * @return void 
+         * @static 
+         */ 
+        public static function macro($name, $macro)
+        {
+                        \Illuminate\View\Factory::macro($name, $macro);
+        }
+                    /**
+         * Mix another object into the class.
+         *
+         * @param object $mixin
+         * @param bool $replace
+         * @return void 
+         * @throws \ReflectionException
+         * @static 
+         */ 
+        public static function mixin($mixin, $replace = true)
+        {
+                        \Illuminate\View\Factory::mixin($mixin, $replace);
+        }
+                    /**
+         * Checks if macro is registered.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasMacro($name)
+        {
+                        return \Illuminate\View\Factory::hasMacro($name);
+        }
+                    /**
+         * Start a component rendering process.
+         *
+         * @param \Illuminate\View\View|\Closure|string $view
+         * @param array $data
+         * @return void 
+         * @static 
+         */ 
+        public static function startComponent($view, $data = [])
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startComponent($view, $data);
+        }
+                    /**
+         * Get the first view that actually exists from the given list, and start a component.
+         *
+         * @param array $names
+         * @param array $data
+         * @return void 
+         * @static 
+         */ 
+        public static function startComponentFirst($names, $data = [])
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startComponentFirst($names, $data);
+        }
+                    /**
+         * Render the current component.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function renderComponent()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderComponent();
+        }
+                    /**
+         * Start the slot rendering process.
+         *
+         * @param string $name
+         * @param string|null $content
+         * @return void 
+         * @static 
+         */ 
+        public static function slot($name, $content = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->slot($name, $content);
+        }
+                    /**
+         * Save the slot content for rendering.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function endSlot()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->endSlot();
+        }
+                    /**
+         * Register a view creator event.
+         *
+         * @param array|string $views
+         * @param \Closure|string $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function creator($views, $callback)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->creator($views, $callback);
+        }
+                    /**
+         * Register multiple view composers via an array.
+         *
+         * @param array $composers
+         * @return array 
+         * @static 
+         */ 
+        public static function composers($composers)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->composers($composers);
+        }
+                    /**
+         * Register a view composer event.
+         *
+         * @param array|string $views
+         * @param \Closure|string $callback
+         * @return array 
+         * @static 
+         */ 
+        public static function composer($views, $callback)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->composer($views, $callback);
+        }
+                    /**
+         * Call the composer for a given view.
+         *
+         * @param \Illuminate\Contracts\View\View $view
+         * @return void 
+         * @static 
+         */ 
+        public static function callComposer($view)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->callComposer($view);
+        }
+                    /**
+         * Call the creator for a given view.
+         *
+         * @param \Illuminate\Contracts\View\View $view
+         * @return void 
+         * @static 
+         */ 
+        public static function callCreator($view)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->callCreator($view);
+        }
+                    /**
+         * Start injecting content into a section.
+         *
+         * @param string $section
+         * @param string|null $content
+         * @return void 
+         * @static 
+         */ 
+        public static function startSection($section, $content = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startSection($section, $content);
+        }
+                    /**
+         * Inject inline content into a section.
+         *
+         * @param string $section
+         * @param string $content
+         * @return void 
+         * @static 
+         */ 
+        public static function inject($section, $content)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->inject($section, $content);
+        }
+                    /**
+         * Stop injecting content into a section and return its contents.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function yieldSection()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->yieldSection();
+        }
+                    /**
+         * Stop injecting content into a section.
+         *
+         * @param bool $overwrite
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function stopSection($overwrite = false)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->stopSection($overwrite);
+        }
+                    /**
+         * Stop injecting content into a section and append it.
+         *
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function appendSection()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->appendSection();
+        }
+                    /**
+         * Get the string contents of a section.
+         *
+         * @param string $section
+         * @param string $default
+         * @return string 
+         * @static 
+         */ 
+        public static function yieldContent($section, $default = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->yieldContent($section, $default);
+        }
+                    /**
+         * Get the parent placeholder for the current request.
+         *
+         * @param string $section
+         * @return string 
+         * @static 
+         */ 
+        public static function parentPlaceholder($section = '')
+        {
+                        return \Illuminate\View\Factory::parentPlaceholder($section);
+        }
+                    /**
+         * Check if section exists.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function hasSection($name)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->hasSection($name);
+        }
+                    /**
+         * Check if section does not exist.
+         *
+         * @param string $name
+         * @return bool 
+         * @static 
+         */ 
+        public static function sectionMissing($name)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->sectionMissing($name);
+        }
+                    /**
+         * Get the contents of a section.
+         *
+         * @param string $name
+         * @param string|null $default
+         * @return mixed 
+         * @static 
+         */ 
+        public static function getSection($name, $default = null)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getSection($name, $default);
+        }
+                    /**
+         * Get the entire array of sections.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getSections()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getSections();
+        }
+                    /**
+         * Flush all of the sections.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushSections()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushSections();
+        }
+                    /**
+         * Add new loop to the stack.
+         *
+         * @param \Countable|array $data
+         * @return void 
+         * @static 
+         */ 
+        public static function addLoop($data)
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->addLoop($data);
+        }
+                    /**
+         * Increment the top loop's indices.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function incrementLoopIndices()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->incrementLoopIndices();
+        }
+                    /**
+         * Pop a loop from the top of the loop stack.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function popLoop()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->popLoop();
+        }
+                    /**
+         * Get an instance of the last loop in the stack.
+         *
+         * @return \stdClass|null 
+         * @static 
+         */ 
+        public static function getLastLoop()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getLastLoop();
+        }
+                    /**
+         * Get the entire loop stack.
+         *
+         * @return array 
+         * @static 
+         */ 
+        public static function getLoopStack()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->getLoopStack();
+        }
+                    /**
+         * Start injecting content into a push section.
+         *
+         * @param string $section
+         * @param string $content
+         * @return void 
+         * @static 
+         */ 
+        public static function startPush($section, $content = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startPush($section, $content);
+        }
+                    /**
+         * Stop injecting content into a push section.
+         *
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function stopPush()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->stopPush();
+        }
+                    /**
+         * Start prepending content into a push section.
+         *
+         * @param string $section
+         * @param string $content
+         * @return void 
+         * @static 
+         */ 
+        public static function startPrepend($section, $content = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startPrepend($section, $content);
+        }
+                    /**
+         * Stop prepending content into a push section.
+         *
+         * @return string 
+         * @throws \InvalidArgumentException
+         * @static 
+         */ 
+        public static function stopPrepend()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->stopPrepend();
+        }
+                    /**
+         * Get the string contents of a push section.
+         *
+         * @param string $section
+         * @param string $default
+         * @return string 
+         * @static 
+         */ 
+        public static function yieldPushContent($section, $default = '')
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->yieldPushContent($section, $default);
+        }
+                    /**
+         * Flush all of the stacks.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function flushStacks()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->flushStacks();
+        }
+                    /**
+         * Start a translation block.
+         *
+         * @param array $replacements
+         * @return void 
+         * @static 
+         */ 
+        public static function startTranslation($replacements = [])
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        $instance->startTranslation($replacements);
+        }
+                    /**
+         * Render the current translation.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function renderTranslation()
+        {
+                        /** @var \Illuminate\View\Factory $instance */
+                        return $instance->renderTranslation();
+        }
+         
+    }
+     
+}
+
+    namespace Illuminate\Support { 
+            /**
+     * 
+     *
+     */ 
+        class Arr {
+         
+    }
+            /**
+     * 
+     *
+     */ 
+        class Str {
+         
+    }
+     
+}
+
+        namespace Facade\Ignition\Facades { 
+            /**
+     * Class Flare.
+     *
+     * @see \Facade\FlareClient\Flare
+     */ 
+        class Flare {
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function register($apiKey, $apiSecret = null, $contextDetector = null, $container = null)
+        {
+                        return \Facade\FlareClient\Flare::register($apiKey, $apiSecret, $contextDetector, $container);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getMiddleware()
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->getMiddleware();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function registerFlareHandlers()
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->registerFlareHandlers();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function registerExceptionHandler()
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->registerExceptionHandler();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function registerErrorHandler()
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->registerErrorHandler();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function registerMiddleware($callable)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->registerMiddleware($callable);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getMiddlewares()
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->getMiddlewares();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function glow($name, $messageLevel = 'info', $metaData = [])
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->glow($name, $messageLevel, $metaData);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function handleException($throwable)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->handleException($throwable);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function handleError($code, $message, $file = '', $line = 0)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->handleError($code, $message, $file, $line);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function applicationPath($applicationPath)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->applicationPath($applicationPath);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function report($throwable, $callback = null)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->report($throwable, $callback);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function reportMessage($message, $logLevel, $callback = null)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->reportMessage($message, $logLevel, $callback);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function sendTestReport($throwable)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->sendTestReport($throwable);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function reset()
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->reset();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function anonymizeIp()
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->anonymizeIp();
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function createReport($throwable)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->createReport($throwable);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function createReportFromMessage($message, $logLevel)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->createReportFromMessage($message, $logLevel);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function stage($stage)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->stage($stage);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function messageLevel($messageLevel)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->messageLevel($messageLevel);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function getGroup($groupName = 'context', $default = [])
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->getGroup($groupName, $default);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function context($key, $value)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->context($key, $value);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function group($groupName, $properties)
+        {
+                        /** @var \Facade\FlareClient\Flare $instance */
+                        return $instance->group($groupName, $properties);
+        }
+         
+    }
+     
+}
+
+    namespace Maatwebsite\Excel\Facades { 
+            /**
+     * 
+     *
+     */ 
+        class Excel {
+                    /**
+         * 
+         *
+         * @param object $export
+         * @param string|null $fileName
+         * @param string $writerType
+         * @param array $headers
+         * @throws \PhpOffice\PhpSpreadsheet\Exception
+         * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
+         * @return \Maatwebsite\Excel\BinaryFileResponse 
+         * @static 
+         */ 
+        public static function download($export, $fileName, $writerType = null, $headers = [])
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->download($export, $fileName, $writerType, $headers);
+        }
+                    /**
+         * 
+         *
+         * @param object $export
+         * @param string $filePath
+         * @param string|null $disk
+         * @param string $writerType
+         * @param mixed $diskOptions
+         * @throws \PhpOffice\PhpSpreadsheet\Exception
+         * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
+         * @return bool 
+         * @static 
+         */ 
+        public static function store($export, $filePath, $diskName = null, $writerType = null, $diskOptions = [])
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->store($export, $filePath, $diskName, $writerType, $diskOptions);
+        }
+                    /**
+         * 
+         *
+         * @param object $export
+         * @param string $filePath
+         * @param string|null $disk
+         * @param string $writerType
+         * @param mixed $diskOptions
+         * @return \Maatwebsite\Excel\PendingDispatch 
+         * @static 
+         */ 
+        public static function queue($export, $filePath, $disk = null, $writerType = null, $diskOptions = [])
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->queue($export, $filePath, $disk, $writerType, $diskOptions);
+        }
+                    /**
+         * 
+         *
+         * @param object $export
+         * @param string $writerType
+         * @return string 
+         * @static 
+         */ 
+        public static function raw($export, $writerType)
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->raw($export, $writerType);
+        }
+                    /**
+         * 
+         *
+         * @param object $import
+         * @param string|\Maatwebsite\Excel\UploadedFile $filePath
+         * @param string|null $disk
+         * @param string|null $readerType
+         * @return \Maatwebsite\Excel\Reader|\Maatwebsite\Excel\PendingDispatch 
+         * @static 
+         */ 
+        public static function import($import, $filePath, $disk = null, $readerType = null)
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->import($import, $filePath, $disk, $readerType);
+        }
+                    /**
+         * 
+         *
+         * @param object $import
+         * @param string|\Maatwebsite\Excel\UploadedFile $filePath
+         * @param string|null $disk
+         * @param string|null $readerType
+         * @return array 
+         * @static 
+         */ 
+        public static function toArray($import, $filePath, $disk = null, $readerType = null)
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->toArray($import, $filePath, $disk, $readerType);
+        }
+                    /**
+         * 
+         *
+         * @param object $import
+         * @param string|\Maatwebsite\Excel\UploadedFile $filePath
+         * @param string|null $disk
+         * @param string|null $readerType
+         * @return \Maatwebsite\Excel\Collection 
+         * @static 
+         */ 
+        public static function toCollection($import, $filePath, $disk = null, $readerType = null)
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->toCollection($import, $filePath, $disk, $readerType);
+        }
+                    /**
+         * 
+         *
+         * @param \Maatwebsite\Excel\ShouldQueue $import
+         * @param string|\Maatwebsite\Excel\UploadedFile $filePath
+         * @param string|null $disk
+         * @param string $readerType
+         * @return \Maatwebsite\Excel\PendingDispatch 
+         * @static 
+         */ 
+        public static function queueImport($import, $filePath, $disk = null, $readerType = null)
+        {
+                        /** @var \Maatwebsite\Excel\Excel $instance */
+                        return $instance->queueImport($import, $filePath, $disk, $readerType);
+        }
+                    /**
+         * 
+         *
+         * @param string $concern
+         * @param callable $handler
+         * @param string $event
+         * @static 
+         */ 
+        public static function extend($concern, $handler, $event = 'Maatwebsite\\Excel\\Events\\BeforeWriting')
+        {
+                        return \Maatwebsite\Excel\Excel::extend($concern, $handler, $event);
+        }
+                    /**
+         * When asserting downloaded, stored, queued or imported, use regular expression
+         * to look for a matching file path.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function matchByRegex()
+        {
+                        /** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
+                        $instance->matchByRegex();
+        }
+                    /**
+         * When asserting downloaded, stored, queued or imported, use regular string
+         * comparison for matching file path.
+         *
+         * @return void 
+         * @static 
+         */ 
+        public static function doNotMatchByRegex()
+        {
+                        /** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
+                        $instance->doNotMatchByRegex();
+        }
+                    /**
+         * 
+         *
+         * @param string $fileName
+         * @param callable|null $callback
+         * @static 
+         */ 
+        public static function assertDownloaded($fileName, $callback = null)
+        {
+                        /** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
+                        return $instance->assertDownloaded($fileName, $callback);
+        }
+                    /**
+         * 
+         *
+         * @param string $filePath
+         * @param string|callable|null $disk
+         * @param callable|null $callback
+         * @static 
+         */ 
+        public static function assertStored($filePath, $disk = null, $callback = null)
+        {
+                        /** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
+                        return $instance->assertStored($filePath, $disk, $callback);
+        }
+                    /**
+         * 
+         *
+         * @param string $filePath
+         * @param string|callable|null $disk
+         * @param callable|null $callback
+         * @static 
+         */ 
+        public static function assertQueued($filePath, $disk = null, $callback = null)
+        {
+                        /** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
+                        return $instance->assertQueued($filePath, $disk, $callback);
+        }
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function assertQueuedWithChain($chain)
+        {
+                        /** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
+                        return $instance->assertQueuedWithChain($chain);
+        }
+                    /**
+         * 
+         *
+         * @param string $filePath
+         * @param string|callable|null $disk
+         * @param callable|null $callback
+         * @static 
+         */ 
+        public static function assertImported($filePath, $disk = null, $callback = null)
+        {
+                        /** @var \Maatwebsite\Excel\Fakes\ExcelFake $instance */
+                        return $instance->assertImported($filePath, $disk, $callback);
+        }
+         
+    }
+     
+}
+
+    namespace Madnest\Madzipper\Facades { 
+            /**
+     * 
+     *
+     */ 
+        class Madzipper {
+                    /**
+         * Create a new zip Archive if the file does not exists
+         * opens a zip archive if the file exists
+         *
+         * @param $pathToFile string The file to open
+         * @param \Madnest\Madzipper\RepositoryInterface|string $type The type of the archive, defaults to zip, possible are zip, phar
+         * @throws \RuntimeException
+         * @throws \Exception
+         * @throws \InvalidArgumentException
+         * @return \Madnest\Madzipper\Madzipper Madzipper instance
+         * @static 
+         */ 
+        public static function make($pathToFile, $type = 'zip')
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->make($pathToFile, $type);
+        }
+                    /**
+         * Create a new zip archive or open an existing one
+         *
+         * @param $pathToFile
+         * @throws \Exception
+         * @return \Madnest\Madzipper\Madzipper 
+         * @static 
+         */ 
+        public static function zip($pathToFile)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->zip($pathToFile);
+        }
+                    /**
+         * Create a new phar file or open one
+         *
+         * @param $pathToFile
+         * @throws \Exception
+         * @return \Madnest\Madzipper\Madzipper 
+         * @static 
+         */ 
+        public static function phar($pathToFile)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->phar($pathToFile);
+        }
+                    /**
+         * Create a new rar file or open one
+         *
+         * @param $pathToFile
+         * @throws \Exception
+         * @return \Madnest\Madzipper\Madzipper 
+         * @static 
+         */ 
+        public static function rar($pathToFile)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->rar($pathToFile);
+        }
+                    /**
+         * Extracts the opened zip archive to the specified location <br/>
+         * you can provide an array of files and folders and define if they should be a white list
+         * or a black list to extract. By default this method compares file names using "string starts with" logic
+         *
+         * @param $path string The path to extract to
+         * @param array $files An array of files
+         * @param int $methodFlags The Method the files should be treated
+         * @throws \Exception
+         * @static 
+         */ 
+        public static function extractTo($path, $files = [], $methodFlags = 2)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->extractTo($path, $files, $methodFlags);
+        }
+                    /**
+         * Extracts matching files/folders from the opened zip archive to the specified location.
+         *
+         * @param string $extractToPath The path to extract to
+         * @param string $regex regular expression used to match files. See @link http://php.net/manual/en/reference.pcre.pattern.syntax.php
+         * @throws \InvalidArgumentException
+         * @throws \RuntimeException
+         * @static 
+         */ 
+        public static function extractMatchingRegex($extractToPath, $regex)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->extractMatchingRegex($extractToPath, $regex);
+        }
+                    /**
+         * Gets the content of a single file if available
+         *
+         * @param $filePath string The full path (including all folders) of the file in the zip
+         * @throws \Exception
+         * @return mixed returns the content or throws an exception
+         * @static 
+         */ 
+        public static function getFileContent($filePath)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getFileContent($filePath);
+        }
+                    /**
+         * Add one or multiple files to the zip.
+         *
+         * @param $pathToAdd array|string An array or string of files and folders to add
+         * @param null|mixed $fileName
+         * @return \Madnest\Madzipper\Madzipper Madzipper instance
+         * @static 
+         */ 
+        public static function add($pathToAdd, $fileName = null)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->add($pathToAdd, $fileName);
+        }
+                    /**
+         * Add an empty directory
+         *
+         * @param $dirName
+         * @return \Madzipper 
+         * @static 
+         */ 
+        public static function addEmptyDir($dirName)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->addEmptyDir($dirName);
+        }
+                    /**
+         * Add a file to the zip using its contents
+         *
+         * @param $filename string The name of the file to create
+         * @param $content string The file contents
+         * @return \Madnest\Madzipper\Madzipper Madzipper instance
+         * @static 
+         */ 
+        public static function addString($filename, $content)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->addString($filename, $content);
+        }
+                    /**
+         * Gets the status of the zip.
+         *
+         * @return int The status of the internal zip file
+         * @static 
+         */ 
+        public static function getStatus()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getStatus();
+        }
+                    /**
+         * Remove a file or array of files and folders from the zip archive
+         *
+         * @param $fileToRemove array|string The path/array to the files in the zip
+         * @return \Madnest\Madzipper\Madzipper Madzipper instance
+         * @static 
+         */ 
+        public static function remove($fileToRemove)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->remove($fileToRemove);
+        }
+                    /**
+         * Returns the path of the current zip file if there is one.
+         *
+         * @return string The path to the file
+         * @static 
+         */ 
+        public static function getFilePath()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getFilePath();
+        }
+                    /**
+         * Sets the password to be used for decompressing
+         *
+         * @param $password
+         * @return bool 
+         * @static 
+         */ 
+        public static function usePassword($password)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->usePassword($password);
+        }
+                    /**
+         * Closes the zip file and frees all handles
+         *
+         * @static 
+         */ 
+        public static function close()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->close();
+        }
+                    /**
+         * Sets the internal folder to the given path.<br/>
+         * Useful for extracting only a segment of a zip file.
+         *
+         * @param $path
+         * @return \Madnest\Madzipper\Madzipper 
+         * @static 
+         */ 
+        public static function folder($path)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->folder($path);
+        }
+                    /**
+         * Resets the internal folder to the root of the zip file.
+         *
+         * @return \Madnest\Madzipper\Madzipper 
+         * @static 
+         */ 
+        public static function home()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->home();
+        }
+                    /**
+         * Deletes the archive file
+         *
+         * @static 
+         */ 
+        public static function delete()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->delete();
+        }
+                    /**
+         * Get the type of the Archive
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getArchiveType()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getArchiveType();
+        }
+                    /**
+         * Get the current internal folder pointer
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getCurrentFolderPath()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getCurrentFolderPath();
+        }
+                    /**
+         * Checks if a file is present in the archive
+         *
+         * @param $fileInArchive
+         * @return bool 
+         * @static 
+         */ 
+        public static function contains($fileInArchive)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->contains($fileInArchive);
+        }
+                    /**
+         * 
+         *
+         * @return \Madnest\Madzipper\RepositoryInterface 
+         * @static 
+         */ 
+        public static function getRepository()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getRepository();
+        }
+                    /**
+         * 
+         *
+         * @return \Madnest\Madzipper\Filesystem 
+         * @static 
+         */ 
+        public static function getFileHandler()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getFileHandler();
+        }
+                    /**
+         * Gets the path to the internal folder
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getInternalPath()
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->getInternalPath();
+        }
+                    /**
+         * List all files that are within the archive
+         *
+         * @param string|null $regexFilter regular expression to filter returned files/folders. See @link http://php.net/manual/en/reference.pcre.pattern.syntax.php
+         * @throws \RuntimeException
+         * @return array 
+         * @static 
+         */ 
+        public static function listFiles($regexFilter = null)
+        {
+                        /** @var \Madnest\Madzipper\Madzipper $instance */
+                        return $instance->listFiles($regexFilter);
+        }
+         
+    }
+     
+}
+
+    namespace Orangehill\Iseed\Facades { 
+            /**
+     * 
+     *
+     */ 
+        class Iseed {
+                    /**
+         * 
+         *
+         * @static 
+         */ 
+        public static function readStubFile($file)
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->readStubFile($file);
+        }
+                    /**
+         * Generates a seed file.
+         *
+         * @param string $table
+         * @param string $prefix
+         * @param string $suffix
+         * @param string $database
+         * @param int $max
+         * @param string $prerunEvent
+         * @param string $postunEvent
+         * @return bool 
+         * @throws Orangehill\Iseed\TableNotFoundException
+         * @static 
+         */ 
+        public static function generateSeed($table, $prefix = null, $suffix = null, $database = null, $max = 0, $chunkSize = 0, $exclude = null, $prerunEvent = null, $postrunEvent = null, $dumpAuto = true, $indexed = true, $orderBy = null, $direction = 'ASC')
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->generateSeed($table, $prefix, $suffix, $database, $max, $chunkSize, $exclude, $prerunEvent, $postrunEvent, $dumpAuto, $indexed, $orderBy, $direction);
+        }
+                    /**
+         * Get a seed folder path
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getSeedPath()
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->getSeedPath();
+        }
+                    /**
+         * Get the Data
+         *
+         * @param string $table
+         * @return Array 
+         * @static 
+         */ 
+        public static function getData($table, $max, $exclude = null, $orderBy = null, $direction = 'ASC')
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->getData($table, $max, $exclude, $orderBy, $direction);
+        }
+                    /**
+         * Repacks data read from the database
+         *
+         * @param array|object $data
+         * @return array 
+         * @static 
+         */ 
+        public static function repackSeedData($data)
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->repackSeedData($data);
+        }
+                    /**
+         * Checks if a database table exists
+         *
+         * @param string $table
+         * @return boolean 
+         * @static 
+         */ 
+        public static function hasTable($table)
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->hasTable($table);
+        }
+                    /**
+         * Generates a seed class name (also used as a filename)
+         *
+         * @param string $table
+         * @param string $prefix
+         * @param string $suffix
+         * @return string 
+         * @static 
+         */ 
+        public static function generateClassName($table, $prefix = null, $suffix = null)
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->generateClassName($table, $prefix, $suffix);
+        }
+                    /**
+         * Get the path to the stub file.
+         *
+         * @return string 
+         * @static 
+         */ 
+        public static function getStubPath()
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->getStubPath();
+        }
+                    /**
+         * Populate the place-holders in the seed stub.
+         *
+         * @param string $class
+         * @param string $stub
+         * @param string $table
+         * @param string $data
+         * @param int $chunkSize
+         * @param string $prerunEvent
+         * @param string $postunEvent
+         * @return string 
+         * @static 
+         */ 
+        public static function populateStub($class, $stub, $table, $data, $chunkSize = null, $prerunEvent = null, $postrunEvent = null, $indexed = true)
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->populateStub($class, $stub, $table, $data, $chunkSize, $prerunEvent, $postrunEvent, $indexed);
+        }
+                    /**
+         * Create the full path name to the seed file.
+         *
+         * @param string $name
+         * @param string $path
+         * @return string 
+         * @static 
+         */ 
+        public static function getPath($name, $path)
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->getPath($name, $path);
+        }
+                    /**
+         * Cleans the iSeed section
+         *
+         * @return bool 
+         * @static 
+         */ 
+        public static function cleanSection()
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->cleanSection();
+        }
+                    /**
+         * Updates the DatabaseSeeder file's run method (kudoz to: https://github.com/JeffreyWay/Laravel-4-Generators)
+         *
+         * @param string $className
+         * @return bool 
+         * @static 
+         */ 
+        public static function updateDatabaseSeederRunMethod($className)
+        {
+                        /** @var \Orangehill\Iseed\Iseed $instance */
+                        return $instance->updateDatabaseSeederRunMethod($className);
+        }
+         
+    }
+     
+}
+
+
+namespace  { 
+            class App extends \Illuminate\Support\Facades\App {}
+            class Arr extends \Illuminate\Support\Arr {}
+            class Artisan extends \Illuminate\Support\Facades\Artisan {}
+            class Auth extends \Illuminate\Support\Facades\Auth {}
+            class Blade extends \Illuminate\Support\Facades\Blade {}
+            class Broadcast extends \Illuminate\Support\Facades\Broadcast {}
+            class Bus extends \Illuminate\Support\Facades\Bus {}
+            class Cache extends \Illuminate\Support\Facades\Cache {}
+            class Config extends \Illuminate\Support\Facades\Config {}
+            class Cookie extends \Illuminate\Support\Facades\Cookie {}
+            class Crypt extends \Illuminate\Support\Facades\Crypt {}
+            class DB extends \Illuminate\Support\Facades\DB {}
+            class Eloquent extends \Illuminate\Database\Eloquent\Model {             
+                /**
+             * Create and return an un-saved model instance.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function make($attributes = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->make($attributes);
+            }
+             
+                /**
+             * Register a new global scope.
+             *
+             * @param string $identifier
+             * @param \Illuminate\Database\Eloquent\Scope|\Closure $scope
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function withGlobalScope($identifier, $scope)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withGlobalScope($identifier, $scope);
+            }
+             
+                /**
+             * Remove a registered global scope.
+             *
+             * @param \Illuminate\Database\Eloquent\Scope|string $scope
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function withoutGlobalScope($scope)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withoutGlobalScope($scope);
+            }
+             
+                /**
+             * Remove all or passed registered global scopes.
+             *
+             * @param array|null $scopes
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function withoutGlobalScopes($scopes = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withoutGlobalScopes($scopes);
+            }
+             
+                /**
+             * Get an array of global scopes that were removed from the query.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function removedScopes()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->removedScopes();
+            }
+             
+                /**
+             * Add a where clause on the primary key to the query.
+             *
+             * @param mixed $id
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereKey($id)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereKey($id);
+            }
+             
+                /**
+             * Add a where clause on the primary key to the query.
+             *
+             * @param mixed $id
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereKeyNot($id)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereKeyNot($id);
+            }
+             
+                /**
+             * Add a basic where clause to the query.
+             *
+             * @param \Closure|string|array $column
+             * @param mixed $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function where($column, $operator = null, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->where($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add a basic where clause to the query, and return the first result.
+             *
+             * @param \Closure|string|array $column
+             * @param mixed $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function firstWhere($column, $operator = null, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstWhere($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where" clause to the query.
+             *
+             * @param \Closure|array|string $column
+             * @param mixed $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhere($column, $operator = null, $value = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhere($column, $operator, $value);
+            }
+             
+                /**
+             * Add an "order by" clause for a timestamp to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function latest($column = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->latest($column);
+            }
+             
+                /**
+             * Add an "order by" clause for a timestamp to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function oldest($column = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->oldest($column);
+            }
+             
+                /**
+             * Create a collection of models from plain arrays.
+             *
+             * @param array $items
+             * @return \Illuminate\Database\Eloquent\Collection 
+             * @static 
+             */ 
+            public static function hydrate($items)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->hydrate($items);
+            }
+             
+                /**
+             * Create a collection of models from a raw query.
+             *
+             * @param string $query
+             * @param array $bindings
+             * @return \Illuminate\Database\Eloquent\Collection 
+             * @static 
+             */ 
+            public static function fromQuery($query, $bindings = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->fromQuery($query, $bindings);
+            }
+             
+                /**
+             * Find a model by its primary key.
+             *
+             * @param mixed $id
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null 
+             * @static 
+             */ 
+            public static function find($id, $columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->find($id, $columns);
+            }
+             
+                /**
+             * Find multiple models by their primary keys.
+             *
+             * @param \Illuminate\Contracts\Support\Arrayable|array $ids
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Collection 
+             * @static 
+             */ 
+            public static function findMany($ids, $columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->findMany($ids, $columns);
+            }
+             
+                /**
+             * Find a model by its primary key or throw an exception.
+             *
+             * @param mixed $id
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static|static[] 
+             * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+             * @static 
+             */ 
+            public static function findOrFail($id, $columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->findOrFail($id, $columns);
+            }
+             
+                /**
+             * Find a model by its primary key or return fresh model instance.
+             *
+             * @param mixed $id
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function findOrNew($id, $columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->findOrNew($id, $columns);
+            }
+             
+                /**
+             * Get the first record matching the attributes or instantiate it.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function firstOrNew($attributes = [], $values = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOrNew($attributes, $values);
+            }
+             
+                /**
+             * Get the first record matching the attributes or create it.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function firstOrCreate($attributes, $values = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOrCreate($attributes, $values);
+            }
+             
+                /**
+             * Create or update a record matching the attributes, and fill it with values.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function updateOrCreate($attributes, $values = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->updateOrCreate($attributes, $values);
+            }
+             
+                /**
+             * Execute the query and get the first result or throw an exception.
+             *
+             * @param array $columns
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
+             * @static 
+             */ 
+            public static function firstOrFail($columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOrFail($columns);
+            }
+             
+                /**
+             * Execute the query and get the first result or call a callback.
+             *
+             * @param \Closure|array $columns
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Model|static|mixed 
+             * @static 
+             */ 
+            public static function firstOr($columns = [], $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->firstOr($columns, $callback);
+            }
+             
+                /**
+             * Get a single column's value from the first result of a query.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function value($column)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->value($column);
+            }
+             
+                /**
+             * Execute the query as a "select" statement.
+             *
+             * @param array|string $columns
+             * @return \Illuminate\Database\Eloquent\Collection|static[] 
+             * @static 
+             */ 
+            public static function get($columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->get($columns);
+            }
+             
+                /**
+             * Get the hydrated models without eager loading.
+             *
+             * @param array|string $columns
+             * @return \Illuminate\Database\Eloquent\Model[]|static[] 
+             * @static 
+             */ 
+            public static function getModels($columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getModels($columns);
+            }
+             
+                /**
+             * Eager load the relationships for the models.
+             *
+             * @param array $models
+             * @return array 
+             * @static 
+             */ 
+            public static function eagerLoadRelations($models)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->eagerLoadRelations($models);
+            }
+             
+                /**
+             * Get a lazy collection for the given query.
+             *
+             * @return \Illuminate\Support\LazyCollection 
+             * @static 
+             */ 
+            public static function cursor()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->cursor();
+            }
+             
+                /**
+             * Get an array with the values of a given column.
+             *
+             * @param string $column
+             * @param string|null $key
+             * @return \Illuminate\Support\Collection 
+             * @static 
+             */ 
+            public static function pluck($column, $key = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->pluck($column, $key);
+            }
+             
+                /**
+             * Paginate the given query.
+             *
+             * @param int|null $perPage
+             * @param array $columns
+             * @param string $pageName
+             * @param int|null $page
+             * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function paginate($perPage = null, $columns = [], $pageName = 'page', $page = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->paginate($perPage, $columns, $pageName, $page);
+            }
+             
+                /**
+             * Paginate the given query into a simple paginator.
+             *
+             * @param int|null $perPage
+             * @param array $columns
+             * @param string $pageName
+             * @param int|null $page
+             * @return \Illuminate\Contracts\Pagination\Paginator 
+             * @static 
+             */ 
+            public static function simplePaginate($perPage = null, $columns = [], $pageName = 'page', $page = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->simplePaginate($perPage, $columns, $pageName, $page);
+            }
+             
+                /**
+             * Save a new model and return the instance.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model|$this 
+             * @static 
+             */ 
+            public static function create($attributes = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->create($attributes);
+            }
+             
+                /**
+             * Save a new model and return the instance. Allow mass-assignment.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model|$this 
+             * @static 
+             */ 
+            public static function forceCreate($attributes)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->forceCreate($attributes);
+            }
+             
+                /**
+             * Register a replacement for the default delete function.
+             *
+             * @param \Closure $callback
+             * @return void 
+             * @static 
+             */ 
+            public static function onDelete($callback)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                $instance->onDelete($callback);
+            }
+             
+                /**
+             * Call the given local model scopes.
+             *
+             * @param array|string $scopes
+             * @return static|mixed 
+             * @static 
+             */ 
+            public static function scopes($scopes)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->scopes($scopes);
+            }
+             
+                /**
+             * Apply the scopes to the Eloquent builder instance and return it.
+             *
+             * @return static 
+             * @static 
+             */ 
+            public static function applyScopes()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->applyScopes();
+            }
+             
+                /**
+             * Prevent the specified relations from being eager loaded.
+             *
+             * @param mixed $relations
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function without($relations)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->without($relations);
+            }
+             
+                /**
+             * Create a new instance of the model being queried.
+             *
+             * @param array $attributes
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function newModelInstance($attributes = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->newModelInstance($attributes);
+            }
+             
+                /**
+             * Apply query-time casts to the model instance.
+             *
+             * @param array $casts
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function withCasts($casts)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withCasts($casts);
+            }
+             
+                /**
+             * Get the underlying query builder instance.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function getQuery()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getQuery();
+            }
+             
+                /**
+             * Set the underlying query builder instance.
+             *
+             * @param \Illuminate\Database\Query\Builder $query
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function setQuery($query)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->setQuery($query);
+            }
+             
+                /**
+             * Get a base query builder instance.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function toBase()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->toBase();
+            }
+             
+                /**
+             * Get the relationships being eagerly loaded.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function getEagerLoads()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getEagerLoads();
+            }
+             
+                /**
+             * Set the relationships being eagerly loaded.
+             *
+             * @param array $eagerLoad
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function setEagerLoads($eagerLoad)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->setEagerLoads($eagerLoad);
+            }
+             
+                /**
+             * Get the model instance being queried.
+             *
+             * @return \Illuminate\Database\Eloquent\Model|static 
+             * @static 
+             */ 
+            public static function getModel()
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getModel();
+            }
+             
+                /**
+             * Set a model instance for the model being queried.
+             *
+             * @param \Illuminate\Database\Eloquent\Model $model
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function setModel($model)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->setModel($model);
+            }
+             
+                /**
+             * Get the given macro by name.
+             *
+             * @param string $name
+             * @return \Closure 
+             * @static 
+             */ 
+            public static function getMacro($name)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->getMacro($name);
+            }
+             
+                /**
+             * Checks if a macro is registered.
+             *
+             * @param string $name
+             * @return bool 
+             * @static 
+             */ 
+            public static function hasMacro($name)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->hasMacro($name);
+            }
+             
+                /**
+             * Get the given global macro by name.
+             *
+             * @param string $name
+             * @return \Closure 
+             * @static 
+             */ 
+            public static function getGlobalMacro($name)
+            {
+                                return \Illuminate\Database\Eloquent\Builder::getGlobalMacro($name);
+            }
+             
+                /**
+             * Checks if a global macro is registered.
+             *
+             * @param string $name
+             * @return bool 
+             * @static 
+             */ 
+            public static function hasGlobalMacro($name)
+            {
+                                return \Illuminate\Database\Eloquent\Builder::hasGlobalMacro($name);
+            }
+             
+                /**
+             * Chunk the results of the query.
+             *
+             * @param int $count
+             * @param callable $callback
+             * @return bool 
+             * @static 
+             */ 
+            public static function chunk($count, $callback)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->chunk($count, $callback);
+            }
+             
+                /**
+             * Execute a callback over each item while chunking.
+             *
+             * @param callable $callback
+             * @param int $count
+             * @return bool 
+             * @static 
+             */ 
+            public static function each($callback, $count = 1000)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->each($callback, $count);
+            }
+             
+                /**
+             * Chunk the results of a query by comparing IDs.
+             *
+             * @param int $count
+             * @param callable $callback
+             * @param string|null $column
+             * @param string|null $alias
+             * @return bool 
+             * @static 
+             */ 
+            public static function chunkById($count, $callback, $column = null, $alias = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->chunkById($count, $callback, $column, $alias);
+            }
+             
+                /**
+             * Execute a callback over each item while chunking by ID.
+             *
+             * @param callable $callback
+             * @param int $count
+             * @param string|null $column
+             * @param string|null $alias
+             * @return bool 
+             * @static 
+             */ 
+            public static function eachById($callback, $count = 1000, $column = null, $alias = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->eachById($callback, $count, $column, $alias);
+            }
+             
+                /**
+             * Execute the query and get the first result.
+             *
+             * @param array|string $columns
+             * @return \Illuminate\Database\Eloquent\Model|object|static|null 
+             * @static 
+             */ 
+            public static function first($columns = [])
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->first($columns);
+            }
+             
+                /**
+             * Apply the callback's query changes if the given "value" is true.
+             *
+             * @param mixed $value
+             * @param callable $callback
+             * @param callable|null $default
+             * @return mixed|$this 
+             * @static 
+             */ 
+            public static function when($value, $callback, $default = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->when($value, $callback, $default);
+            }
+             
+                /**
+             * Pass the query to a given callback.
+             *
+             * @param callable $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function tap($callback)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->tap($callback);
+            }
+             
+                /**
+             * Apply the callback's query changes if the given "value" is false.
+             *
+             * @param mixed $value
+             * @param callable $callback
+             * @param callable|null $default
+             * @return mixed|$this 
+             * @static 
+             */ 
+            public static function unless($value, $callback, $default = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->unless($value, $callback, $default);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query.
+             *
+             * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation
+             * @param string $operator
+             * @param int $count
+             * @param string $boolean
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @throws \RuntimeException
+             * @static 
+             */ 
+            public static function has($relation, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->has($relation, $operator, $count, $boolean, $callback);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query with an "or".
+             *
+             * @param string $relation
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orHas($relation, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orHas($relation, $operator, $count);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query.
+             *
+             * @param string $relation
+             * @param string $boolean
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function doesntHave($relation, $boolean = 'and', $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->doesntHave($relation, $boolean, $callback);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query with an "or".
+             *
+             * @param string $relation
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orDoesntHave($relation)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orDoesntHave($relation);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query with where clauses.
+             *
+             * @param string $relation
+             * @param \Closure|null $callback
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereHas($relation, $callback = null, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereHas($relation, $callback, $operator, $count);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query with where clauses and an "or".
+             *
+             * @param string $relation
+             * @param \Closure|null $callback
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereHas($relation, $callback = null, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhereHas($relation, $callback, $operator, $count);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query with where clauses.
+             *
+             * @param string $relation
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereDoesntHave($relation, $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereDoesntHave($relation, $callback);
+            }
+             
+                /**
+             * Add a relationship count / exists condition to the query with where clauses and an "or".
+             *
+             * @param string $relation
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereDoesntHave($relation, $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhereDoesntHave($relation, $callback);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query.
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @param string $operator
+             * @param int $count
+             * @param string $boolean
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function hasMorph($relation, $types, $operator = '>=', $count = 1, $boolean = 'and', $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->hasMorph($relation, $types, $operator, $count, $boolean, $callback);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query with an "or".
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orHasMorph($relation, $types, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orHasMorph($relation, $types, $operator, $count);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query.
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @param string $boolean
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function doesntHaveMorph($relation, $types, $boolean = 'and', $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->doesntHaveMorph($relation, $types, $boolean, $callback);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query with an "or".
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orDoesntHaveMorph($relation, $types)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orDoesntHaveMorph($relation, $types);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query with where clauses.
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @param \Closure|null $callback
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereHasMorph($relation, $types, $callback = null, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereHasMorph($relation, $types, $callback, $operator, $count);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or".
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @param \Closure|null $callback
+             * @param string $operator
+             * @param int $count
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereHasMorph($relation, $types, $callback = null, $operator = '>=', $count = 1)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhereHasMorph($relation, $types, $callback, $operator, $count);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query with where clauses.
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function whereDoesntHaveMorph($relation, $types, $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->whereDoesntHaveMorph($relation, $types, $callback);
+            }
+             
+                /**
+             * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or".
+             *
+             * @param string $relation
+             * @param string|array $types
+             * @param \Closure|null $callback
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function orWhereDoesntHaveMorph($relation, $types, $callback = null)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->orWhereDoesntHaveMorph($relation, $types, $callback);
+            }
+             
+                /**
+             * Add subselect queries to count the relations.
+             *
+             * @param mixed $relations
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function withCount($relations)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->withCount($relations);
+            }
+             
+                /**
+             * Merge the where constraints from another query to the current query.
+             *
+             * @param \Illuminate\Database\Eloquent\Builder $from
+             * @return \Illuminate\Database\Eloquent\Builder|static 
+             * @static 
+             */ 
+            public static function mergeConstraintsFrom($from)
+            {
+                                /** @var \Illuminate\Database\Eloquent\Builder $instance */
+                                return $instance->mergeConstraintsFrom($from);
+            }
+             
+                /**
+             * Set the columns to be selected.
+             *
+             * @param array|mixed $columns
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function select($columns = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->select($columns);
+            }
+             
+                /**
+             * Add a subselect expression to the query.
+             *
+             * @param \Closure|$this|string $query
+             * @param string $as
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function selectSub($query, $as)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->selectSub($query, $as);
+            }
+             
+                /**
+             * Add a new "raw" select expression to the query.
+             *
+             * @param string $expression
+             * @param array $bindings
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function selectRaw($expression, $bindings = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->selectRaw($expression, $bindings);
+            }
+             
+                /**
+             * Makes "from" fetch from a subquery.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function fromSub($query, $as)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->fromSub($query, $as);
+            }
+             
+                /**
+             * Add a raw from clause to the query.
+             *
+             * @param string $expression
+             * @param mixed $bindings
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function fromRaw($expression, $bindings = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->fromRaw($expression, $bindings);
+            }
+             
+                /**
+             * Add a new select column to the query.
+             *
+             * @param array|mixed $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function addSelect($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addSelect($column);
+            }
+             
+                /**
+             * Force the query to only return distinct results.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function distinct()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->distinct();
+            }
+             
+                /**
+             * Set the table which the query is targeting.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $table
+             * @param string|null $as
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function from($table, $as = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->from($table, $as);
+            }
+             
+                /**
+             * Add a join clause to the query.
+             *
+             * @param string $table
+             * @param \Closure|string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @param string $type
+             * @param bool $where
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->join($table, $first, $operator, $second, $type, $where);
+            }
+             
+                /**
+             * Add a "join where" clause to the query.
+             *
+             * @param string $table
+             * @param \Closure|string $first
+             * @param string $operator
+             * @param string $second
+             * @param string $type
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function joinWhere($table, $first, $operator, $second, $type = 'inner')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->joinWhere($table, $first, $operator, $second, $type);
+            }
+             
+                /**
+             * Add a subquery join clause to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @param \Closure|string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @param string $type
+             * @param bool $where
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->joinSub($query, $as, $first, $operator, $second, $type, $where);
+            }
+             
+                /**
+             * Add a left join to the query.
+             *
+             * @param string $table
+             * @param \Closure|string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function leftJoin($table, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->leftJoin($table, $first, $operator, $second);
+            }
+             
+                /**
+             * Add a "join where" clause to the query.
+             *
+             * @param string $table
+             * @param \Closure|string $first
+             * @param string $operator
+             * @param string $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function leftJoinWhere($table, $first, $operator, $second)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->leftJoinWhere($table, $first, $operator, $second);
+            }
+             
+                /**
+             * Add a subquery left join to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @param \Closure|string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function leftJoinSub($query, $as, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->leftJoinSub($query, $as, $first, $operator, $second);
+            }
+             
+                /**
+             * Add a right join to the query.
+             *
+             * @param string $table
+             * @param \Closure|string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function rightJoin($table, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->rightJoin($table, $first, $operator, $second);
+            }
+             
+                /**
+             * Add a "right join where" clause to the query.
+             *
+             * @param string $table
+             * @param \Closure|string $first
+             * @param string $operator
+             * @param string $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function rightJoinWhere($table, $first, $operator, $second)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->rightJoinWhere($table, $first, $operator, $second);
+            }
+             
+                /**
+             * Add a subquery right join to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @param string $as
+             * @param \Closure|string $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function rightJoinSub($query, $as, $first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->rightJoinSub($query, $as, $first, $operator, $second);
+            }
+             
+                /**
+             * Add a "cross join" clause to the query.
+             *
+             * @param string $table
+             * @param \Closure|string|null $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function crossJoin($table, $first = null, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->crossJoin($table, $first, $operator, $second);
+            }
+             
+                /**
+             * Merge an array of where clauses and bindings.
+             *
+             * @param array $wheres
+             * @param array $bindings
+             * @return void 
+             * @static 
+             */ 
+            public static function mergeWheres($wheres, $bindings)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                $instance->mergeWheres($wheres, $bindings);
+            }
+             
+                /**
+             * Prepare the value and operator for a where clause.
+             *
+             * @param string $value
+             * @param string $operator
+             * @param bool $useDefault
+             * @return array 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function prepareValueAndOperator($value, $operator, $useDefault = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->prepareValueAndOperator($value, $operator, $useDefault);
+            }
+             
+                /**
+             * Add a "where" clause comparing two columns to the query.
+             *
+             * @param string|array $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @param string|null $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereColumn($first, $operator = null, $second = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereColumn($first, $operator, $second, $boolean);
+            }
+             
+                /**
+             * Add an "or where" clause comparing two columns to the query.
+             *
+             * @param string|array $first
+             * @param string|null $operator
+             * @param string|null $second
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereColumn($first, $operator = null, $second = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereColumn($first, $operator, $second);
+            }
+             
+                /**
+             * Add a raw where clause to the query.
+             *
+             * @param string $sql
+             * @param mixed $bindings
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereRaw($sql, $bindings = [], $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereRaw($sql, $bindings, $boolean);
+            }
+             
+                /**
+             * Add a raw or where clause to the query.
+             *
+             * @param string $sql
+             * @param mixed $bindings
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereRaw($sql, $bindings = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereRaw($sql, $bindings);
+            }
+             
+                /**
+             * Add a "where in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereIn($column, $values, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereIn($column, $values, $boolean, $not);
+            }
+             
+                /**
+             * Add an "or where in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereIn($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereIn($column, $values);
+            }
+             
+                /**
+             * Add a "where not in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNotIn($column, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotIn($column, $values, $boolean);
+            }
+             
+                /**
+             * Add an "or where not in" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereNotIn($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotIn($column, $values);
+            }
+             
+                /**
+             * Add a "where in raw" clause for integer values to the query.
+             *
+             * @param string $column
+             * @param \Illuminate\Contracts\Support\Arrayable|array $values
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereIntegerInRaw($column, $values, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereIntegerInRaw($column, $values, $boolean, $not);
+            }
+             
+                /**
+             * Add an "or where in raw" clause for integer values to the query.
+             *
+             * @param string $column
+             * @param \Illuminate\Contracts\Support\Arrayable|array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereIntegerInRaw($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereIntegerInRaw($column, $values);
+            }
+             
+                /**
+             * Add a "where not in raw" clause for integer values to the query.
+             *
+             * @param string $column
+             * @param \Illuminate\Contracts\Support\Arrayable|array $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereIntegerNotInRaw($column, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereIntegerNotInRaw($column, $values, $boolean);
+            }
+             
+                /**
+             * Add an "or where not in raw" clause for integer values to the query.
+             *
+             * @param string $column
+             * @param \Illuminate\Contracts\Support\Arrayable|array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereIntegerNotInRaw($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereIntegerNotInRaw($column, $values);
+            }
+             
+                /**
+             * Add a "where null" clause to the query.
+             *
+             * @param string|array $columns
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNull($columns, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNull($columns, $boolean, $not);
+            }
+             
+                /**
+             * Add an "or where null" clause to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereNull($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNull($column);
+            }
+             
+                /**
+             * Add a "where not null" clause to the query.
+             *
+             * @param string|array $columns
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNotNull($columns, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotNull($columns, $boolean);
+            }
+             
+                /**
+             * Add a where between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereBetween($column, $values, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereBetween($column, $values, $boolean, $not);
+            }
+             
+                /**
+             * Add a where between statement using columns to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereBetweenColumns($column, $values, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereBetweenColumns($column, $values, $boolean, $not);
+            }
+             
+                /**
+             * Add an or where between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereBetween($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereBetween($column, $values);
+            }
+             
+                /**
+             * Add an or where between statement using columns to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereBetweenColumns($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereBetweenColumns($column, $values);
+            }
+             
+                /**
+             * Add a where not between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNotBetween($column, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotBetween($column, $values, $boolean);
+            }
+             
+                /**
+             * Add a where not between statement using columns to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNotBetweenColumns($column, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotBetweenColumns($column, $values, $boolean);
+            }
+             
+                /**
+             * Add an or where not between statement to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereNotBetween($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotBetween($column, $values);
+            }
+             
+                /**
+             * Add an or where not between statement using columns to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereNotBetweenColumns($column, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotBetweenColumns($column, $values);
+            }
+             
+                /**
+             * Add an "or where not null" clause to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereNotNull($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotNull($column);
+            }
+             
+                /**
+             * Add a "where date" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereDate($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereDate($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where date" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereDate($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereDate($column, $operator, $value);
+            }
+             
+                /**
+             * Add a "where time" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereTime($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereTime($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where time" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereTime($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereTime($column, $operator, $value);
+            }
+             
+                /**
+             * Add a "where day" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereDay($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereDay($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where day" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereDay($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereDay($column, $operator, $value);
+            }
+             
+                /**
+             * Add a "where month" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereMonth($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereMonth($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where month" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|null $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereMonth($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereMonth($column, $operator, $value);
+            }
+             
+                /**
+             * Add a "where year" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|int|null $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereYear($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereYear($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where year" statement to the query.
+             *
+             * @param string $column
+             * @param string $operator
+             * @param \DateTimeInterface|string|int|null $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereYear($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereYear($column, $operator, $value);
+            }
+             
+                /**
+             * Add a nested where statement to the query.
+             *
+             * @param \Closure $callback
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNested($callback, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNested($callback, $boolean);
+            }
+             
+                /**
+             * Create a new query instance for nested where condition.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function forNestedWhere()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->forNestedWhere();
+            }
+             
+                /**
+             * Add another query builder as a nested where to the query builder.
+             *
+             * @param \Illuminate\Database\Query\Builder $query
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function addNestedWhereQuery($query, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addNestedWhereQuery($query, $boolean);
+            }
+             
+                /**
+             * Add an exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereExists($callback, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereExists($callback, $boolean, $not);
+            }
+             
+                /**
+             * Add an or exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereExists($callback, $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereExists($callback, $not);
+            }
+             
+                /**
+             * Add a where not exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereNotExists($callback, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereNotExists($callback, $boolean);
+            }
+             
+                /**
+             * Add a where not exists clause to the query.
+             *
+             * @param \Closure $callback
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereNotExists($callback)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereNotExists($callback);
+            }
+             
+                /**
+             * Add an exists clause to the query.
+             *
+             * @param \Illuminate\Database\Query\Builder $query
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function addWhereExistsQuery($query, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addWhereExistsQuery($query, $boolean, $not);
+            }
+             
+                /**
+             * Adds a where condition using row values.
+             *
+             * @param array $columns
+             * @param string $operator
+             * @param array $values
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function whereRowValues($columns, $operator, $values, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereRowValues($columns, $operator, $values, $boolean);
+            }
+             
+                /**
+             * Adds an or where condition using row values.
+             *
+             * @param array $columns
+             * @param string $operator
+             * @param array $values
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereRowValues($columns, $operator, $values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereRowValues($columns, $operator, $values);
+            }
+             
+                /**
+             * Add a "where JSON contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereJsonContains($column, $value, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereJsonContains($column, $value, $boolean, $not);
+            }
+             
+                /**
+             * Add an "or where JSON contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereJsonContains($column, $value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereJsonContains($column, $value);
+            }
+             
+                /**
+             * Add a "where JSON not contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereJsonDoesntContain($column, $value, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereJsonDoesntContain($column, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where JSON not contains" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereJsonDoesntContain($column, $value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereJsonDoesntContain($column, $value);
+            }
+             
+                /**
+             * Add a "where JSON length" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $operator
+             * @param mixed $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function whereJsonLength($column, $operator, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->whereJsonLength($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or where JSON length" clause to the query.
+             *
+             * @param string $column
+             * @param mixed $operator
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orWhereJsonLength($column, $operator, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orWhereJsonLength($column, $operator, $value);
+            }
+             
+                /**
+             * Handles dynamic "where" clauses to the query.
+             *
+             * @param string $method
+             * @param array $parameters
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function dynamicWhere($method, $parameters)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->dynamicWhere($method, $parameters);
+            }
+             
+                /**
+             * Add a "group by" clause to the query.
+             *
+             * @param array|string $groups
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function groupBy(...$groups)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->groupBy(...$groups);
+            }
+             
+                /**
+             * Add a raw groupBy clause to the query.
+             *
+             * @param string $sql
+             * @param array $bindings
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function groupByRaw($sql, $bindings = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->groupByRaw($sql, $bindings);
+            }
+             
+                /**
+             * Add a "having" clause to the query.
+             *
+             * @param string $column
+             * @param string|null $operator
+             * @param string|null $value
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function having($column, $operator = null, $value = null, $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->having($column, $operator, $value, $boolean);
+            }
+             
+                /**
+             * Add an "or having" clause to the query.
+             *
+             * @param string $column
+             * @param string|null $operator
+             * @param string|null $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orHaving($column, $operator = null, $value = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orHaving($column, $operator, $value);
+            }
+             
+                /**
+             * Add a "having between " clause to the query.
+             *
+             * @param string $column
+             * @param array $values
+             * @param string $boolean
+             * @param bool $not
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function havingBetween($column, $values, $boolean = 'and', $not = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->havingBetween($column, $values, $boolean, $not);
+            }
+             
+                /**
+             * Add a raw having clause to the query.
+             *
+             * @param string $sql
+             * @param array $bindings
+             * @param string $boolean
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function havingRaw($sql, $bindings = [], $boolean = 'and')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->havingRaw($sql, $bindings, $boolean);
+            }
+             
+                /**
+             * Add a raw or having clause to the query.
+             *
+             * @param string $sql
+             * @param array $bindings
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orHavingRaw($sql, $bindings = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orHavingRaw($sql, $bindings);
+            }
+             
+                /**
+             * Add an "order by" clause to the query.
+             *
+             * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string $column
+             * @param string $direction
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function orderBy($column, $direction = 'asc')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orderBy($column, $direction);
+            }
+             
+                /**
+             * Add a descending "order by" clause to the query.
+             *
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orderByDesc($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orderByDesc($column);
+            }
+             
+                /**
+             * Put the query's results in random order.
+             *
+             * @param string $seed
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function inRandomOrder($seed = '')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->inRandomOrder($seed);
+            }
+             
+                /**
+             * Add a raw "order by" clause to the query.
+             *
+             * @param string $sql
+             * @param array $bindings
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function orderByRaw($sql, $bindings = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->orderByRaw($sql, $bindings);
+            }
+             
+                /**
+             * Alias to set the "offset" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function skip($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->skip($value);
+            }
+             
+                /**
+             * Set the "offset" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function offset($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->offset($value);
+            }
+             
+                /**
+             * Alias to set the "limit" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function take($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->take($value);
+            }
+             
+                /**
+             * Set the "limit" value of the query.
+             *
+             * @param int $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function limit($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->limit($value);
+            }
+             
+                /**
+             * Set the limit and offset for a given page.
+             *
+             * @param int $page
+             * @param int $perPage
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function forPage($page, $perPage = 15)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->forPage($page, $perPage);
+            }
+             
+                /**
+             * Constrain the query to the previous "page" of results before a given ID.
+             *
+             * @param int $perPage
+             * @param int|null $lastId
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function forPageBeforeId($perPage = 15, $lastId = 0, $column = 'id')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->forPageBeforeId($perPage, $lastId, $column);
+            }
+             
+                /**
+             * Constrain the query to the next "page" of results after a given ID.
+             *
+             * @param int $perPage
+             * @param int|null $lastId
+             * @param string $column
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->forPageAfterId($perPage, $lastId, $column);
+            }
+             
+                /**
+             * Remove all existing orders and optionally add a new order.
+             *
+             * @param string|null $column
+             * @param string $direction
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function reorder($column = null, $direction = 'asc')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->reorder($column, $direction);
+            }
+             
+                /**
+             * Add a union statement to the query.
+             *
+             * @param \Illuminate\Database\Query\Builder|\Closure $query
+             * @param bool $all
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function union($query, $all = false)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->union($query, $all);
+            }
+             
+                /**
+             * Add a union all statement to the query.
+             *
+             * @param \Illuminate\Database\Query\Builder|\Closure $query
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function unionAll($query)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->unionAll($query);
+            }
+             
+                /**
+             * Lock the selected rows in the table.
+             *
+             * @param string|bool $value
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function lock($value = true)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->lock($value);
+            }
+             
+                /**
+             * Lock the selected rows in the table for updating.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function lockForUpdate()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->lockForUpdate();
+            }
+             
+                /**
+             * Share lock the selected rows in the table.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function sharedLock()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->sharedLock();
+            }
+             
+                /**
+             * Get the SQL representation of the query.
+             *
+             * @return string 
+             * @static 
+             */ 
+            public static function toSql()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->toSql();
+            }
+             
+                /**
+             * Get the count of the total records for the paginator.
+             *
+             * @param array $columns
+             * @return int 
+             * @static 
+             */ 
+            public static function getCountForPagination($columns = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getCountForPagination($columns);
+            }
+             
+                /**
+             * Concatenate values of a given column as a string.
+             *
+             * @param string $column
+             * @param string $glue
+             * @return string 
+             * @static 
+             */ 
+            public static function implode($column, $glue = '')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->implode($column, $glue);
+            }
+             
+                /**
+             * Determine if any rows exist for the current query.
+             *
+             * @return bool 
+             * @static 
+             */ 
+            public static function exists()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->exists();
+            }
+             
+                /**
+             * Determine if no rows exist for the current query.
+             *
+             * @return bool 
+             * @static 
+             */ 
+            public static function doesntExist()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->doesntExist();
+            }
+             
+                /**
+             * Execute the given callback if no rows exist for the current query.
+             *
+             * @param \Closure $callback
+             * @return mixed 
+             * @static 
+             */ 
+            public static function existsOr($callback)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->existsOr($callback);
+            }
+             
+                /**
+             * Execute the given callback if rows exist for the current query.
+             *
+             * @param \Closure $callback
+             * @return mixed 
+             * @static 
+             */ 
+            public static function doesntExistOr($callback)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->doesntExistOr($callback);
+            }
+             
+                /**
+             * Retrieve the "count" result of the query.
+             *
+             * @param string $columns
+             * @return int 
+             * @static 
+             */ 
+            public static function count($columns = '*')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->count($columns);
+            }
+             
+                /**
+             * Retrieve the minimum value of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function min($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->min($column);
+            }
+             
+                /**
+             * Retrieve the maximum value of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function max($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->max($column);
+            }
+             
+                /**
+             * Retrieve the sum of the values of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function sum($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->sum($column);
+            }
+             
+                /**
+             * Retrieve the average of the values of a given column.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function avg($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->avg($column);
+            }
+             
+                /**
+             * Alias for the "avg" method.
+             *
+             * @param string $column
+             * @return mixed 
+             * @static 
+             */ 
+            public static function average($column)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->average($column);
+            }
+             
+                /**
+             * Execute an aggregate function on the database.
+             *
+             * @param string $function
+             * @param array $columns
+             * @return mixed 
+             * @static 
+             */ 
+            public static function aggregate($function, $columns = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->aggregate($function, $columns);
+            }
+             
+                /**
+             * Execute a numeric aggregate function on the database.
+             *
+             * @param string $function
+             * @param array $columns
+             * @return float|int 
+             * @static 
+             */ 
+            public static function numericAggregate($function, $columns = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->numericAggregate($function, $columns);
+            }
+             
+                /**
+             * Insert a new record into the database.
+             *
+             * @param array $values
+             * @return bool 
+             * @static 
+             */ 
+            public static function insert($values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->insert($values);
+            }
+             
+                /**
+             * Insert a new record into the database while ignoring errors.
+             *
+             * @param array $values
+             * @return int 
+             * @static 
+             */ 
+            public static function insertOrIgnore($values)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->insertOrIgnore($values);
+            }
+             
+                /**
+             * Insert a new record and get the value of the primary key.
+             *
+             * @param array $values
+             * @param string|null $sequence
+             * @return int 
+             * @static 
+             */ 
+            public static function insertGetId($values, $sequence = null)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->insertGetId($values, $sequence);
+            }
+             
+                /**
+             * Insert new records into the table using a subquery.
+             *
+             * @param array $columns
+             * @param \Closure|\Illuminate\Database\Query\Builder|string $query
+             * @return int 
+             * @static 
+             */ 
+            public static function insertUsing($columns, $query)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->insertUsing($columns, $query);
+            }
+             
+                /**
+             * Insert or update a record matching the attributes, and fill it with values.
+             *
+             * @param array $attributes
+             * @param array $values
+             * @return bool 
+             * @static 
+             */ 
+            public static function updateOrInsert($attributes, $values = [])
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->updateOrInsert($attributes, $values);
+            }
+             
+                /**
+             * Run a truncate statement on the table.
+             *
+             * @return void 
+             * @static 
+             */ 
+            public static function truncate()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                $instance->truncate();
+            }
+             
+                /**
+             * Create a raw database expression.
+             *
+             * @param mixed $value
+             * @return \Illuminate\Database\Query\Expression 
+             * @static 
+             */ 
+            public static function raw($value)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->raw($value);
+            }
+             
+                /**
+             * Get the current query value bindings in a flattened array.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function getBindings()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getBindings();
+            }
+             
+                /**
+             * Get the raw array of bindings.
+             *
+             * @return array 
+             * @static 
+             */ 
+            public static function getRawBindings()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getRawBindings();
+            }
+             
+                /**
+             * Set the bindings on the query builder.
+             *
+             * @param array $bindings
+             * @param string $type
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function setBindings($bindings, $type = 'where')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->setBindings($bindings, $type);
+            }
+             
+                /**
+             * Add a binding to the query.
+             *
+             * @param mixed $value
+             * @param string $type
+             * @return \Illuminate\Database\Query\Builder 
+             * @throws \InvalidArgumentException
+             * @static 
+             */ 
+            public static function addBinding($value, $type = 'where')
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->addBinding($value, $type);
+            }
+             
+                /**
+             * Merge an array of bindings into our bindings.
+             *
+             * @param \Illuminate\Database\Query\Builder $query
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function mergeBindings($query)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->mergeBindings($query);
+            }
+             
+                /**
+             * Get the database query processor instance.
+             *
+             * @return \Illuminate\Database\Query\Processors\Processor 
+             * @static 
+             */ 
+            public static function getProcessor()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getProcessor();
+            }
+             
+                /**
+             * Get the query grammar instance.
+             *
+             * @return \Illuminate\Database\Query\Grammars\Grammar 
+             * @static 
+             */ 
+            public static function getGrammar()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->getGrammar();
+            }
+             
+                /**
+             * Use the write pdo for query.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function useWritePdo()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->useWritePdo();
+            }
+             
+                /**
+             * Clone the query without the given properties.
+             *
+             * @param array $properties
+             * @return static 
+             * @static 
+             */ 
+            public static function cloneWithout($properties)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->cloneWithout($properties);
+            }
+             
+                /**
+             * Clone the query without the given bindings.
+             *
+             * @param array $except
+             * @return static 
+             * @static 
+             */ 
+            public static function cloneWithoutBindings($except)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->cloneWithoutBindings($except);
+            }
+             
+                /**
+             * Dump the current SQL and bindings.
+             *
+             * @return \Illuminate\Database\Query\Builder 
+             * @static 
+             */ 
+            public static function dump()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->dump();
+            }
+             
+                /**
+             * Die and dump the current SQL and bindings.
+             *
+             * @return void 
+             * @static 
+             */ 
+            public static function dd()
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                $instance->dd();
+            }
+             
+                /**
+             * Register a custom macro.
+             *
+             * @param string $name
+             * @param object|callable $macro
+             * @return void 
+             * @static 
+             */ 
+            public static function macro($name, $macro)
+            {
+                                \Illuminate\Database\Query\Builder::macro($name, $macro);
+            }
+             
+                /**
+             * Mix another object into the class.
+             *
+             * @param object $mixin
+             * @param bool $replace
+             * @return void 
+             * @throws \ReflectionException
+             * @static 
+             */ 
+            public static function mixin($mixin, $replace = true)
+            {
+                                \Illuminate\Database\Query\Builder::mixin($mixin, $replace);
+            }
+             
+                /**
+             * Dynamically handle calls to the class.
+             *
+             * @param string $method
+             * @param array $parameters
+             * @return mixed 
+             * @throws \BadMethodCallException
+             * @static 
+             */ 
+            public static function macroCall($method, $parameters)
+            {
+                                /** @var \Illuminate\Database\Query\Builder $instance */
+                                return $instance->macroCall($method, $parameters);
+            }
+                    }
+            class Event extends \Illuminate\Support\Facades\Event {}
+            class File extends \Illuminate\Support\Facades\File {}
+            class Gate extends \Illuminate\Support\Facades\Gate {}
+            class Hash extends \Illuminate\Support\Facades\Hash {}
+            class Http extends \Illuminate\Support\Facades\Http {}
+            class Lang extends \Illuminate\Support\Facades\Lang {}
+            class Log extends \Illuminate\Support\Facades\Log {}
+            class Mail extends \Illuminate\Support\Facades\Mail {}
+            class Notification extends \Illuminate\Support\Facades\Notification {}
+            class Password extends \Illuminate\Support\Facades\Password {}
+            class Queue extends \Illuminate\Support\Facades\Queue {}
+            class Redirect extends \Illuminate\Support\Facades\Redirect {}
+            class Redis extends \Illuminate\Support\Facades\Redis {}
+            class Request extends \Illuminate\Support\Facades\Request {}
+            class Response extends \Illuminate\Support\Facades\Response {}
+            class Route extends \Illuminate\Support\Facades\Route {}
+            class Schema extends \Illuminate\Support\Facades\Schema {}
+            class Session extends \Illuminate\Support\Facades\Session {}
+            class Storage extends \Illuminate\Support\Facades\Storage {}
+            class Str extends \Illuminate\Support\Str {}
+            class URL extends \Illuminate\Support\Facades\URL {}
+            class Validator extends \Illuminate\Support\Facades\Validator {}
+            class View extends \Illuminate\Support\Facades\View {}
+            class Flare extends \Facade\Ignition\Facades\Flare {}
+            class Excel extends \Maatwebsite\Excel\Facades\Excel {}
+            class Madzipper extends \Madnest\Madzipper\Facades\Madzipper {}
+            class Iseed extends \Orangehill\Iseed\Facades\Iseed {}
+     
+}
+
+
+
+

+ 77 - 0
app/Console/Commands/Action.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Illuminate\Http\Request;
+use Mockery\Exception;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class Action extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'action:call {uri}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     * @param OutputInterface $output
+     * @throws \Illuminate\Contracts\Container\BindingResolutionException
+     */
+    public function handle(Request $request)
+    {
+        $url = $this->argument('uri');
+
+        // 获取控制器+方法
+        $uri = parse_url($url, PHP_URL_PATH);
+        $uri = explode('@', $uri);
+
+        // 获取参数
+        parse_str(parse_url($url, PHP_URL_QUERY), $param);
+
+        $controller = $uri[0] ?? '';
+        $action = $uri[1] ?? '';
+        if (empty($controller) || empty($action)) {
+            $this->info('The format (Controller@method) is required');
+            return;
+        }
+
+
+
+        try {
+            $container = app()->make("App\Http\Controllers\\" . $controller);
+        } catch (Exception $e) {
+            $this->info($e->getMessage());
+            return;
+        }
+
+        if ($param) {
+            foreach ($param as $k => $v) {
+                $request->offsetSet($k, $v);
+            }
+        }
+
+        $result = app()->call([$container, $action], $param);
+        $this->info($result);
+    }
+}

+ 41 - 0
app/Console/Kernel.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace App\Console;
+
+use Illuminate\Console\Scheduling\Schedule;
+use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
+
+class Kernel extends ConsoleKernel
+{
+    /**
+     * The Artisan commands provided by your application.
+     *
+     * @var array
+     */
+    protected $commands = [
+        //
+    ];
+
+    /**
+     * Define the application's command schedule.
+     *
+     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
+     * @return void
+     */
+    protected function schedule(Schedule $schedule)
+    {
+        // $schedule->command('inspire')->hourly();
+    }
+
+    /**
+     * Register the commands for the application.
+     *
+     * @return void
+     */
+    protected function commands()
+    {
+        $this->load(__DIR__.'/Commands');
+
+        require base_path('routes/console.php');
+    }
+}

+ 28 - 0
app/Events/ServerStartEvent.php

@@ -0,0 +1,28 @@
+<?php
+
+
+namespace App\Events;
+
+
+use Hhxsv5\LaravelS\Swoole\Events\ServerStartInterface;
+use Swoole\Http\Server;
+
+class ServerStartEvent implements ServerStartInterface
+{
+
+    public function __construct()
+    {
+    }
+
+    public function handle(Server $server)
+    {
+        $server->startMsecTime = $this->msecTime();
+    }
+
+    private function msecTime()
+    {
+        list($msec, $sec) = explode(' ', microtime());
+        $time = explode(".", $sec . ($msec * 1000));
+        return $time[0];
+    }
+}

+ 24 - 0
app/Events/WorkerStartEvent.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Events;
+
+use Cache;
+use DB;
+use Hhxsv5\LaravelS\Swoole\Events\WorkerStartInterface;
+use Swoole\Http\Server;
+
+class WorkerStartEvent implements WorkerStartInterface
+{
+
+    public function __construct()
+    {
+    }
+
+    public function handle(Server $server, $workerId)
+    {
+        if (isset($server->startMsecTime) && Cache::get("swooleServerStartMsecTime") != $server->startMsecTime) {
+            Cache::forever("swooleServerStartMsecTime", $server->startMsecTime);
+            DB::table('ws')->delete();
+        }
+    }
+}

+ 62 - 0
app/Exceptions/Handler.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Exceptions;
+
+use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
+use Throwable;
+
+class Handler extends ExceptionHandler
+{
+    /**
+     * A list of the exception types that are not reported.
+     *
+     * @var array
+     */
+    protected $dontReport = [
+        //
+    ];
+
+    /**
+     * A list of the inputs that are never flashed for validation exceptions.
+     *
+     * @var array
+     */
+    protected $dontFlash = [
+        'password',
+        'password_confirmation',
+    ];
+
+    /**
+     * Report or log an exception.
+     *
+     * @param  \Throwable  $exception
+     * @return void
+     *
+     * @throws \Exception
+     */
+    public function report(Throwable $exception)
+    {
+        parent::report($exception);
+    }
+
+    /**
+     * Render an exception into an HTTP response.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Throwable  $exception
+     * @return \Symfony\Component\HttpFoundation\Response
+     *
+     * @throws \Throwable
+     */
+    public function render($request, Throwable $exception)
+    {
+        if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
+            if ($exception->getStatusCode() == 404) {
+                if (!\App\Module\Base::leftExists($request->getRequestUri(), '/api')) {
+                    return response()->view('main', ['version' => \App\Module\Base::getVersion()]);
+                }
+            }
+        }
+        return parent::render($request, $exception);
+    }
+}

+ 260 - 0
app/Http/Controllers/Api/ChatController.php

@@ -0,0 +1,260 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Module\Base;
+use App\Module\Chat;
+use App\Module\Users;
+use DB;
+use Request;
+
+/**
+ * @apiDefine chat
+ *
+ * 聊天
+ */
+class ChatController extends Controller
+{
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+    /**
+     * 对话列表
+     */
+    public function dialog__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $lists = Base::DBC2A(DB::table('chat_dialog')
+            ->where(function ($query) use ($user) {
+                return $query->where('user1', $user['username'])->where('del1', 0);
+            })
+            ->orWhere(function ($query) use ($user) {
+                return $query->where('user2', $user['username'])->where('del2', 0);
+            })
+            ->orderByDesc('lastdate')
+            ->take(200)
+            ->get());
+        if (count($lists) <= 0) {
+            return Base::retError('暂无对话记录');
+        }
+        $hasUnset = false;
+        foreach ($lists AS $key => $item) {
+            $tmpUserInfo = Users::username2basic($item['user1'] == $user['username'] ? $item['user2'] : $item['user1']);
+            if (empty($tmpUserInfo)) {
+                DB::table('chat_dialog')->where('id', $item['id'])->update(['del1' => 1, 'del2' => 1]);
+                $hasUnset = true;
+                unset($lists[$key]);
+                continue;
+            }
+            $lists[$key] = array_merge($item, $tmpUserInfo);
+            $lists[$key]['lastdate'] = $item['lastdate'] ?: $item['indate'];
+            $unread = 0;
+            if ($item['user1'] == $user['username']) $unread+= $item['unread1'];
+            if ($item['user2'] == $user['username']) $unread+= $item['unread2'];
+            $lists[$key]['unread'] = $unread;
+        }
+        if ($hasUnset) {
+            $lists = array_values($lists);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 清空聊天记录(删除对话)
+     *
+     * @apiParam {String} username             用户名
+     * @apiParam {Number} [delete]             是否删除对话,1:是
+     */
+    public function dialog__clear()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $delete = intval(Request::input('delete'));
+        $res = Chat::openDialog($user['username'], trim(Request::input('username')));
+        if (Base::isError($res)) {
+            return $res;
+        }
+        $dialog = $res['data'];
+        $lastMsg = Base::DBC2A(DB::table('chat_msg')
+            ->select(['id'])
+            ->where('did', $dialog['id'])
+            ->orderByDesc('indate')
+            ->orderByDesc('id')
+            ->first());
+        $upArray = [
+            ($dialog['recField'] == 1 ? 'lastid2' : 'lastid1') => $lastMsg ? $lastMsg['id'] : 0
+        ];
+        if ($delete === 1) {
+            $upArray[($dialog['recField'] == 1 ? 'del2' : 'del1')] = 1;
+        }
+        DB::table('chat_dialog')->where('id', $dialog['id'])->update($upArray);
+        Chat::forgetDialog($dialog['user1'], $dialog['user2']);
+        return Base::retSuccess($delete ? '删除成功!' : '清除成功!');
+    }
+
+    /**
+     * 消息列表
+     *
+     * @apiParam {String} username             用户名
+     * @apiParam {Number} [page]               当前页,默认:1
+     * @apiParam {Number} [pagesize]           每页显示数量,默认:20,最大:100
+     */
+    public function message__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $res = Chat::openDialog($user['username'], trim(Request::input('username')));
+        if (Base::isError($res)) {
+            return $res;
+        }
+        $dialog = $res['data'];
+        $lastid = $dialog[($dialog['recField'] == 1 ? 'lastid2' : 'lastid1')];
+        $whereArray = [];
+        $whereArray[] = ['did', '=', $dialog['id']];
+        if ($lastid > 0) {
+            $whereArray[] = ['id', '>', $lastid];
+        }
+        $lists = DB::table('chat_msg')
+            ->where($whereArray)
+            ->orderByDesc('indate')
+            ->orderByDesc('id')
+            ->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists, false);
+        //
+        foreach ($lists['lists'] AS $key => $item) {
+            $basic = Users::username2basic($item['username']);
+            $item['nickname'] = $basic ? $basic['nickname'] : ($item['nickname'] || '');
+            $item['userimg'] = $basic ? $basic['userimg'] : ($item['userimg'] || '');
+            $item['message'] = Base::string2array($item['message']);
+            $lists['lists'][$key] = $item;
+        }
+        //
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 文件 - 上传
+     *
+     * @apiParam {String} username            get-发给用户名(群组名)
+     * @apiParam {String} [filename]          post-文件名称
+     * @apiParam {String} [image64]           post-base64图片(二选一)
+     * @apiParam {File} [files]               post-文件对象(二选一)
+     */
+    public function files__upload()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $username = trim(Request::input('username'));
+        if (Base::leftExists($username, "group::")) {
+            //$res = Chat::groupOpen($username);
+            return Base::retError('参数错误');
+        } else {
+            $res = Chat::openDialog($user['username'], $username);
+        }
+        if (Base::isError($res)) {
+            return $res;
+        }
+        $did = $res['data']['id'];
+        //
+        $path = "uploads/chat/" . Users::token2userid() . "/";
+        $image64 = trim(Base::getPostValue('image64'));
+        $fileName = trim(Base::getPostValue('filename'));
+        if ($image64) {
+            $data = Base::image64save([
+                "image64" => $image64,
+                "path" => $path,
+                "fileName" => $fileName,
+            ]);
+        } else {
+            $data = Base::upload([
+                "file" => Request::file('files'),
+                "type" => 'file',
+                "path" => $path,
+                "fileName" => $fileName,
+            ]);
+        }
+        //
+        if (Base::isError($data)) {
+            return Base::retError($data['msg']);
+        } else {
+            $fileData = $data['data'];
+            $fileData['thumb'] = $fileData['thumb'] ?: 'images/files/file.png';
+            switch ($fileData['ext']) {
+                case "docx":
+                    $fileData['thumb'] = 'images/files/doc.png';
+                    break;
+                case "xlsx":
+                    $fileData['thumb'] = 'images/files/xls.png';
+                    break;
+                case "pptx":
+                    $fileData['thumb'] = 'images/files/ppt.png';
+                    break;
+                case "ai":
+                case "avi":
+                case "bmp":
+                case "cdr":
+                case "doc":
+                case "eps":
+                case "gif":
+                case "mov":
+                case "mp3":
+                case "mp4":
+                case "pdf":
+                case "ppt":
+                case "pr":
+                case "psd":
+                case "rar":
+                case "svg":
+                case "tif":
+                case "txt":
+                case "xls":
+                case "zip":
+                    $fileData['thumb'] = 'images/files/' . $fileData['ext'] . '.png';
+                    break;
+            }
+            $array = [
+                'did' => $did,
+                'group' => Base::leftExists($username, 'group::') ? $username : '',
+                'name' => $fileData['name'],
+                'size' => $fileData['size'] * 1024,
+                'ext' => $fileData['ext'],
+                'path' => $fileData['path'],
+                'thumb' => $fileData['thumb'],
+                'username' => $user['username'],
+                'indate' => Base::time(),
+            ];
+            DB::table('chat_files')->insertGetId($array);
+            //
+            $fileData['thumb'] = Base::fillUrl($fileData['thumb']);
+            return Base::retSuccess('success', $fileData);
+        }
+    }
+}

+ 347 - 0
app/Http/Controllers/Api/DingController.php

@@ -0,0 +1,347 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Module\Base;
+use App\Module\Project;
+use SimpleDingTalk\Config;
+use App\Http\Controllers\Controller;
+use SimpleDingTalk\User;
+use SimpleDingTalk\AccessToken;
+use Request;
+use DB;
+use App\Module\Users;
+
+class DingController extends Controller
+{
+
+
+    public function __construct()
+    {
+
+        // 配置信息
+        $apps=[
+            'miniprogram_app' => [
+                'info' => [
+                    'AGENT_ID' => '',
+                    'APP_KEY' => '',
+                    'APP_SECRET' => ''
+                ],
+                'access_token' => [
+                    'expires' => 0,
+                    'file_path' => ''
+                ],
+                'callback_info' => [
+                    'aes_key' => '',
+                    'token' => ''
+                ],
+                'login_info' => [
+                    'authorize' => [
+                        'redirect_uri' => '',
+                        'dingtalk_login_uri' => ''
+                    ]
+                ],
+                'v2' => [
+                    'access_token' => [
+                        'expires' => 0,
+                        'file_path' => ''
+                    ],
+
+                ],
+                'userAccessToken' => [
+                    'expires' => 0,
+                    'file_path' => ''
+                ]
+            ],
+            'micro_app' => [
+                'info' => [
+                    'AGENT_ID' => '1602970634',
+                    'APP_KEY' => 'dingoduj8nh4jsroanpr',
+                    'APP_SECRET' => '9qsEDDVN8sJ96GMe3pqHpiJuEwXnDBHg010kBJJc6GK--HDQ0Cnv5Twuv97ge_JS'
+                ],
+                'access_token' => [
+                    'expires' => 0,
+                    'file_path' => base_path('DingTalkToken')
+                ],
+                'callback_info' => [
+                    'aes_key' => '',
+                    'token' => ''
+                ],
+                'page' => [
+                    'app' => '',
+                    'pc' => '',
+                    'management' => ''
+                ],
+                'login_info' => [
+                    'authorize' => [
+                        'redirect_uri' => '',
+                        'dingtalk_login_uri'=>''
+                    ]
+                ],
+                'v2' => [
+                    'access_token' => [
+                        'expires' => 0,
+                        'file_path' => ''
+                    ],
+                ],
+                'userAccessToken' => [
+                    'expires' => 0,
+                    'file_path' => base_path('DingTalkToken')
+                ]
+            ]
+
+        ];
+
+        $robots=[
+            'robot1' => [
+                'info' => [
+                    'AGENT_ID' => 123456,
+                    'APP_KEY' => '',
+                    'APP_SECRET' => '',
+                    'access_token' => '',
+                    'SEC' => ''
+                ],
+                'access_token' => [
+                    'expires' => 180,
+                    'file_path' => './robot.json'
+                ]
+
+            ],
+        ];
+
+        Config::setRobot($robots)->
+        setApp($apps)->
+        setAppType('micro_app')->
+        setRobotType('robot1')->
+        setCorpId('dingc844bf6147f4d40c35c2f4657eb6378f');
+
+        AccessToken::generateToken();
+
+    }
+
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+
+    public function login()
+    {
+        $code = trim(Request::input('code'));
+        $ret = User::code_getuserinfo($code);
+        $result = json_decode($ret,true);
+        if($result['errcode'] === 0){
+            $get_user_ret = User::get($result['result']['userid']);
+            $user_result = json_decode($get_user_ret,true);
+            if($user_result['errcode'] === 0){
+                $user_info = $user_result['result'];
+                $user = Base::DBC2A(DB::table('users')->where('username', $user_info['mobile'])->where('nickname', $user_info['name'])->first());
+                if($user){
+                    $array = [
+                        'userid' => $result['result']['userid'],
+                        'token' => Users::token($user),
+                        'loginnum' => $user['loginnum'] + 1,
+                        'lastip' => Base::getIp(),
+                        'lastdate' => Base::time(),
+                        'lineip' => Base::getIp(),
+                        'linedate' => Base::time(),
+                    ];
+                    Base::array_over($user, $array);
+                    DB::table('users')->where('id', $user['id'])->update($array);
+                    return Base::retSuccess( "登陆成功!", Users::retInfo($user));
+                }else{
+                    return Base::retError( "您的姓名为:{$user_info['name']},手机号码为:{$user_info['mobile']},系统里面找不到该用户,请使用账号密码登录!");
+                }
+            }else{
+                return Base::retError( "无法获取钉钉信息,请使用账号密码登录!");
+            }
+        }else{
+            return Base::retError($result['errmsg']);
+        }
+    }
+
+    public function notice__push()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        $act = trim(Base::getPostValue('act'));
+        $taskid = intval(Base::getPostValue('taskid'));
+        $task = Base::DBC2A(DB::table('project_task')
+            ->where([
+                ['delete', '=', 0],
+                ['id', '=', $taskid],
+            ])
+            ->first());
+        if (empty($task)) {
+            return Base::retError('任务不存在!');
+        }
+        if ($task['projectid'] > 0) {
+            if (!Project::isPersons($task, $user['username'])) {
+                $inRes = Project::inThe($task['projectid'], $user['username']);
+                if (Base::isError($inRes)) {
+                    return $inRes;
+                }
+            }
+            if (!in_array($act, ['comment', 'attention'])) {
+                $checkRole = Project::role('edit_role', $task['projectid'], $task['id']);
+                if (Base::isError($checkRole)) {
+                    return $checkRole;
+                }
+                switch ($act) {
+                    case 'complete':
+                    case 'unfinished':
+                        $checkRole = Project::role('complete_role', $task['projectid'], $task['id']);
+                        if (Base::isError($checkRole)) {
+                            return $checkRole;
+                        }
+                        break;
+                    case 'archived':
+                    case 'unarchived':
+                        $checkRole = Project::role('archived_role', $task['projectid'], $task['id']);
+                        if (Base::isError($checkRole)) {
+                            return $checkRole;
+                        }
+                        break;
+                    case 'delete':
+                        $checkRole = Project::role('del_role', $task['projectid'], $task['id']);
+                        if (Base::isError($checkRole)) {
+                            return $checkRole;
+                        }
+                        break;
+                }
+            }
+        } else {
+            if (!Project::isPersons($task, $user['username'])) {
+                return Base::retError('此操作只允许任务负责人!');
+            }
+        }
+        $content = Base::newTrim(Base::getPostValue('content'));
+        $message = "";
+        $upArray = [];
+        $logArray = [];
+
+
+        switch ($act) {
+            /**
+             * 修改标题
+             */
+            case 'title': {
+                $upArray['title'] = $content;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '修改任务标题',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $content,
+                        'old_title' => $task['title'],
+                    ])
+                ];
+                break;
+            }
+            /**
+             * 修改子任务
+             */
+            case 'subtask': {
+                if (!is_array($content)) {
+                    $content = [];
+                }
+                $subNames = [];
+                foreach ($content AS $tmp) {
+                    if ($tmp['uname'] && !in_array($tmp['uname'], $subNames)) {
+                        $subNames[] = $tmp['uname'];
+                    }
+                }
+                $content = Base::array2string($content);
+                if ($content == $task['subtask']) {
+                    return Base::retError('子任务未做改变!');
+                }
+                $upArray['subtask'] = $content;
+                //
+                $detail = '修改子任务';
+                $subtype = 'modify';
+                $new_count = count(Base::string2array($content));
+                $old_count = count(Base::string2array($task['subtask']));
+                if ($new_count > $old_count) {
+                    $detail = '添加子任务';
+                    $subtype = 'add';
+                } elseif ($new_count < $old_count) {
+                    $detail = '删除子任务';
+                    $subtype = 'del';
+                }
+                //
+                if ($subNames) {
+                    DB::transaction(function() use ($task, $subNames) {
+                        foreach ($subNames AS $uname) {
+                            $row = Base::DBC2A(DB::table('project_users')->where([
+                                'type' => '负责人',
+                                'taskid' => $task['id'],
+                                'username' => $uname,
+                            ])->lockForUpdate()->first());
+                            if (empty($row)) {
+                                DB::table('project_users')->insert([
+                                    'type' => '负责人',
+                                    'projectid' => $task['projectid'],
+                                    'taskid' => $task['id'],
+                                    'isowner' => $task['username'] == $uname ? 1 : 0,
+                                    'username' => $uname,
+                                    'indate' => Base::time()
+                                ]);
+                            }
+                        }
+                        DB::table('project_users')->where([
+                            'type' => '负责人',
+                            'taskid' => $task['id'],
+                        ])->whereNotIn('username', $subNames)->delete();
+                    });
+                } else {
+                    DB::table('project_users')->where([
+                        'type' => '负责人',
+                        'taskid' => $task['id'],
+                    ])->delete();
+                }
+                //
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => $detail,
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'subtype' => $subtype,
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                        'subtask' => $content,
+                        'old_subtask' => $task['subtask'],
+                    ])
+                ];
+                break;
+            }
+
+            default: {
+                return Base::retError('参数错误!');
+            }
+
+
+        }
+
+    }
+
+    public function transfer(){
+        return Base::retSuccess( "登陆成功!");
+    }
+}

+ 680 - 0
app/Http/Controllers/Api/DocsController.php

@@ -0,0 +1,680 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Module\Base;
+use App\Module\Docs;
+use App\Module\Users;
+use App\Tasks\PushTask;
+use Cache;
+use DB;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+use Request;
+
+/**
+ * @apiDefine docs
+ *
+ * 知识库
+ */
+class DocsController extends Controller
+{
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+    /**
+     * 知识库列表
+     *
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     */
+    public function book__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $lists = DB::table('docs_book')
+            ->where('username', $user['username'])
+            ->orWhere('role_edit', 'reg')
+            ->orWhere('role_look', 'reg')
+            ->orWhere(function ($query) use ($user) {
+                $query->where('role_edit', 'private')->where('username', $user['username']);
+            })
+            ->orWhere(function ($query) use ($user) {
+                $query->where('role_edit', 'member')->whereIn('id', function ($query2) use ($user) {
+                    $query2->select('bookid')
+                        ->from('docs_users')
+                        ->where('username', $user['username'])
+                        ->whereRaw(env('DB_PREFIX') . 'docs_book.id = bookid');
+                });
+            })
+            ->orderByDesc('id')
+            ->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('暂无知识库', $lists);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 添加/修改知识库
+     *
+     * @apiParam {Number} id                知识库数据ID
+     * @apiParam {String} title             知识库名称
+     */
+    public function book__add()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $title = trim(Request::input('title'));
+        if ($id > 0) {
+            $role = Docs::checkRole($id, 'edit');
+            if (Base::isError($role)) {
+                return $role;
+            }
+        }
+        if (mb_strlen($title) < 2 || mb_strlen($title) > 100) {
+            return Base::retError('标题限制2-100个字!');
+        }
+        if ($id > 0) {
+            // 修改
+            $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
+            if (empty($row)) {
+                return Base::retError('知识库不存在或已被删除!');
+            }
+            $data = [
+                'title' => $title,
+            ];
+            DB::table('docs_book')->where('id', $id)->update($data);
+            return Base::retSuccess('修改成功!', $data);
+        } else {
+            // 添加
+            $data = [
+                'username' => $user['username'],
+                'title' => $title,
+                'indate' => Base::time(),
+            ];
+            $id = DB::table('docs_book')->insertGetId($data);
+            if (empty($id)) {
+                return Base::retError('系统繁忙,请稍后再试!');
+            }
+            $data['id'] = $id;
+            return Base::retSuccess('添加成功!', $data);
+        }
+    }
+
+    /**
+     * 设置知识库
+     *
+     * @apiParam {Number} id                知识库数据ID
+     * @apiParam {String} role_edit
+     * @apiParam {String} role_view
+     */
+    public function book__setting()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $type = trim(Request::input('type'));
+        $role = Docs::checkRole($id, 'edit');
+        if (Base::isError($role) && $role['ret'] < 0) {
+            return $role;
+        }
+        $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('知识库不存在或已被删除!');
+        }
+        $setting = Base::string2array($row['setting']);
+        if ($type == 'save') {
+            if (Base::isError($role)) {
+                return $role;
+            }
+            foreach (Request::input() AS $key => $value) {
+                if (in_array($key, ['role_edit', 'role_look', 'role_view'])) {
+                    $setting[$key] = $value;
+                }
+            }
+            DB::table('docs_book')->where('id', $id)->update([
+                'role_edit' => $setting['role_edit'],
+                'role_look' => $setting['role_look'],
+                'role_view' => $setting['role_view'],
+                'setting' => Base::array2string($setting),
+            ]);
+        }
+        return Base::retSuccess($type == 'save' ? '修改成功!' : 'success', $setting ?: json_decode('{}'));
+    }
+
+    /**
+     * 删除知识库
+     *
+     * @apiParam {Number} id                知识库数据ID
+     */
+    public function book__delete()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('知识库不存在或已被删除!');
+        }
+        if ($row['username'] != $user['username']) {
+            return Base::retError('此操作仅限知识库负责人!');
+        }
+        DB::table('docs_book')->where('id', $id)->delete();
+        DB::table('docs_section')->where('bookid', $id)->delete();
+        DB::table('docs_content')->where('bookid', $id)->delete();
+        return Base::retSuccess('删除成功!');
+    }
+
+    /**
+     * 成员-列表
+     *
+     * @apiParam {Number} id            知识库数据ID
+     * @apiParam {Number} [page]        当前页,默认:1
+     * @apiParam {Number} [pagesize]    每页显示数量,默认:20,最大:100
+     */
+    public function users__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $role = Docs::checkRole($id, 'edit');
+        if (Base::isError($role)) {
+            return $role;
+        }
+        $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('知识库不存在或已被删除!');
+        }
+        //
+        $lists = DB::table('docs_book')
+            ->join('docs_users', 'docs_book.id', '=', 'docs_users.bookid')
+            ->select(['docs_book.title', 'docs_users.*'])
+            ->where([
+                ['docs_book.id', $id],
+            ])
+            ->orderByDesc('docs_users.id')->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的成员');
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $userInfo = Users::username2basic($item['username']);
+            $lists['lists'][$key]['userimg'] = $userInfo['userimg'];
+            $lists['lists'][$key]['nickname'] = $userInfo['nickname'];
+            $lists['lists'][$key]['profession'] = $userInfo['profession'];
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 成员-添加、删除
+     *
+     * @apiParam {String} act
+     * - delete: 删除成员
+     * - else: 添加成员
+     * @apiParam {Number} id                    知识库数据ID
+     * @apiParam {Array|String} username        用户名(或用户名组)
+     */
+    public function users__join()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $role = Docs::checkRole($id, 'edit');
+        if (Base::isError($role)) {
+            return $role;
+        }
+        $row = Base::DBC2A(DB::table('docs_book')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('知识库不存在或已被删除!');
+        }
+        //
+        $usernames = Request::input('username');
+        if (empty($usernames)) {
+            return Base::retError('参数错误!');
+        }
+        if (!is_array($usernames)) {
+            if (Base::strExists($usernames, ',')) {
+                $usernames = explode(',', $usernames);
+            } else {
+                $usernames = [$usernames];
+            }
+        }
+        //
+        foreach ($usernames AS $username) {
+            $inRow = Base::DBC2A(DB::table('docs_users')->where(['bookid' => $id, 'username' => $username])->first());
+            switch (Request::input('act')) {
+                case 'delete': {
+                    if ($inRow) {
+                        DB::table('docs_users')->where([
+                            'bookid' => $id,
+                            'username' => $username
+                        ])->delete();
+                    }
+                    break;
+                }
+                default: {
+                    if (!$inRow && $username != $user['username']) {
+                        DB::table('docs_users')->insert([
+                            'bookid' => $id,
+                            'username' => $username,
+                            'indate' => Base::time()
+                        ]);
+                    }
+                    break;
+                }
+            }
+        }
+        return Base::retSuccess('操作完成!');
+    }
+
+    /**
+     * 章节列表
+     *
+     * @apiParam {String} act                   请求方式,用于判断权限
+     * - edit: 管理页请求
+     * - view: 阅读页请求
+     * @apiParam {Number} bookid                知识库数据ID
+     */
+    public function section__lists()
+    {
+        $bookid = intval(Request::input('bookid'));
+        $role = Docs::checkRole($bookid, Request::input('act'));
+        if (Base::isError($role) && $role['ret'] < 0) {
+            return $role;
+        }
+        $lists = Base::DBC2A(DB::table('docs_section')
+            ->where('bookid', $bookid)
+            ->orderByDesc('inorder')
+            ->orderByDesc('id')
+            ->take(500)
+            ->get());
+        if (empty($lists)) {
+            return Base::retError('暂无章节');
+        }
+        foreach ($lists AS $key => $item) {
+            $lists[$key]['icon'] = Base::fillUrl('images/files/' . $item['type'] . '.png');
+        }
+        $bookDetail = Base::DBC2A(DB::table('docs_book')->select(['title'])->where('id', $bookid)->first());
+        return Base::retSuccess('success', [
+            'book' => $bookDetail ?: json_decode('{}'),
+            'tree' => Base::list2Tree($lists, 'id', 'parentid')
+        ]);
+    }
+
+    /**
+     * 添加/修改章节
+     *
+     * @apiParam {Number} bookid                知识库数据ID
+     * @apiParam {String} title                 章节名称
+     * @apiParam {String} type                  章节类型
+     */
+    public function section__add()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $bookid = intval(Request::input('bookid'));
+        $role = Docs::checkRole($bookid, 'edit');
+        if (Base::isError($role)) {
+            return $role;
+        }
+        $bookRow = Base::DBC2A(DB::table('docs_book')->where('id', $bookid)->first());
+        if (empty($bookRow)) {
+            return Base::retError('知识库不存在或已被删除!');
+        }
+        $count = DB::table('docs_section')->where('bookid', $bookid)->count();
+        if ($count >= 500) {
+            return Base::retError(['知识库章节已经超过最大限制(%)!', 500]);
+        }
+        //
+        $id = intval(Request::input('id'));
+        $title = trim(Request::input('title'));
+        $type = trim(Request::input('type'));
+        if (mb_strlen($title) < 2 || mb_strlen($title) > 100) {
+            return Base::retError('标题限制2-100个字!');
+        }
+        if ($id > 0) {
+            // 修改
+            $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
+            if (empty($row)) {
+                return Base::retError('知识库不存在或已被删除!');
+            }
+            $data = [
+                'title' => $title,
+            ];
+            DB::table('docs_section')->where('id', $id)->update($data);
+            return Base::retSuccess('修改成功!', $data);
+        } else {
+            // 添加
+            if (!in_array($type, ['document', 'mind', 'sheet', 'flow', 'folder'])) {
+                return Base::retError('参数错误!');
+            }
+            $parentid = 0;
+            if ($id < 0) {
+                $count = Base::DBC2A(DB::table('docs_section')->where('id', abs($id))->where('bookid', $bookid)->count());
+                if ($count > 0) {
+                    $parentid = abs($id);
+                }
+            }
+            $data = [
+                'bookid' => $bookid,
+                'parentid' => $parentid,
+                'username' => $user['username'],
+                'title' => $title,
+                'type' => $type,
+                'inorder' => intval(DB::table('docs_section')->select(['inorder'])->where('bookid', $bookid)->orderByDesc('inorder')->value('inorder')) + 1,
+                'indate' => Base::time(),
+            ];
+            $id = DB::table('docs_section')->insertGetId($data);
+            if (empty($id)) {
+                return Base::retError('系统繁忙,请稍后再试!');
+            }
+            $data['id'] = $id;
+            return Base::retSuccess('添加成功!', $data);
+        }
+    }
+
+    /**
+     * 排序章节
+     *
+     * @apiParam {Number} bookid                知识库数据ID
+     * @apiParam {String} oldsort               旧排序数据
+     * @apiParam {String} newsort               新排序数据
+     */
+    public function section__sort()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $bookid = intval(Request::input('bookid'));
+        $role = Docs::checkRole($bookid, 'edit');
+        if (Base::isError($role)) {
+            return $role;
+        }
+        $bookRow = Base::DBC2A(DB::table('docs_book')->where('id', $bookid)->first());
+        if (empty($bookRow)) {
+            return Base::retError('知识库不存在或已被删除!');
+        }
+        //
+        $newSort = explode(";", Request::input('newsort'));
+        if (count($newSort) == 0) {
+            return Base::retError('参数错误!');
+        }
+        //
+        $count = count($newSort);
+        foreach ($newSort AS $sort => $item) {
+            list($newId, $newParentid) = explode(':', $item);
+            DB::table('docs_section')->where([
+                'id' => $newId,
+                'bookid' => $bookid
+            ])->update([
+                'inorder' => $count - intval($sort),
+                'parentid' => $newParentid
+            ]);
+        }
+        return Base::retSuccess('保存成功!');
+    }
+
+    /**
+     * 删除章节
+     *
+     * @apiParam {Number} id                章节数据ID
+     */
+    public function section__delete()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('文档不存在或已被删除!');
+        }
+        $role = Docs::checkRole($row['bookid'], 'edit');
+        if (Base::isError($role)) {
+            return $role;
+        }
+        DB::table('docs_section')->where('parentid', $id)->update([ 'parentid' => $row['parentid'] ]);
+        DB::table('docs_section')->where('id', $id)->delete();
+        DB::table('docs_content')->where('sid', $id)->delete();
+        return Base::retSuccess('删除成功!');
+    }
+
+    /**
+     * 获取章节内容
+     *
+     * @apiParam {String} act                   请求方式,用于判断权限
+     * - edit: 管理页请求
+     * - view: 阅读页请求
+     * @apiParam {Number|String} id             章节数据ID(或:章节数据ID-历史数据ID)
+     */
+    public function section__content()
+    {
+        $id = Request::input('id');
+        $hid = 0;
+        if (Base::strExists($id, '-')) {
+            list($id, $hid) = explode("-", $id);
+        }
+        $id = intval($id);
+        $hid = intval($hid);
+        $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('文档不存在或已被删除!');
+        }
+        $role = Docs::checkRole($row['bookid'], Request::input('act'));
+        if (Base::isError($role) && $role['ret'] < 0) {
+            return $role;
+        }
+        $whereArray = [];
+        if ($hid > 0) {
+            $whereArray[] = ['id', '=', $hid];
+        }
+        $whereArray[] = ['sid', '=', $id];
+        $cRow = Base::DBC2A(DB::table('docs_content')->select(['id AS hid', 'content'])->where($whereArray)->orderByDesc('id')->first());
+        if (empty($cRow)) {
+            $cRow = [ 'hid' => 0, 'content' => '' ];
+        }
+        return Base::retSuccess('success', array_merge($row, $cRow));
+    }
+
+    /**
+     * 获取章节历史内容
+     *
+     * @apiParam {Number} id                章节数据ID
+     */
+    public function section__history()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('文档不存在或已被删除!');
+        }
+        $role = Docs::checkRole($row['bookid'], 'edit');
+        if (Base::isError($role) && $role['ret'] < 0) {
+            return $role;
+        }
+        //
+        $lists = Base::DBC2A(DB::table('docs_content')
+            ->where('sid', $id)
+            ->orderByDesc('id')
+            ->take(50)
+            ->get());
+        if (count($lists) <= 1) {
+            return Base::retError('暂无历史数据');
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * {post} 保存章节内容
+     *
+     * @apiParam {Number} id                章节数据ID
+     * @apiParam {Object} [D]               Request Payload 提交
+     * - content: 内容
+     */
+    public function section__save()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Base::getPostValue('id'));
+        $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('文档不存在或已被删除!');
+        }
+        $role = Docs::checkRole($row['bookid'], 'edit');
+        if (Base::isError($role)) {
+            return $role;
+        }
+        if ($row['lockdate'] + 60 > Base::time() && $row['lockname'] != $user['username']) {
+            return Base::retError(['已被会员【%】锁定!', Users::nickname($row['lockname'])]);
+        }
+        $content = Base::getPostValue('content');
+        $text = '';
+        if ($row['type'] == 'document') {
+            $data = Base::json2array($content);
+            $isRep = false;
+            preg_match_all("/<img\s*src=\"data:image\/(png|jpg|jpeg);base64,(.*?)\"/s", $data['content'], $matchs);
+            foreach ($matchs[2] as $key => $text) {
+                $p = "uploads/docs/document/" . $id . "/";
+                Base::makeDir(public_path($p));
+                $p.= md5($text) . "." . $matchs[1][$key];
+                $r = file_put_contents(public_path($p), base64_decode($text));
+                if ($r) {
+                    $data['content'] = str_replace($matchs[0][$key], '<img src="' . Base::fillUrl($p) . '"', $data['content']);
+                    $isRep = true;
+                }
+            }
+            $text = strip_tags($data['content']);
+            if ($isRep == true) {
+                $content = Base::array2json($data);
+            }
+        }
+        DB::table('docs_content')->where('sid', $id)->update(['text' => '']);
+        DB::table('docs_content')->insert([
+            'bookid' => $row['bookid'],
+            'sid' => $id,
+            'content' => $content,
+            'text' => $text,
+            'username' => $user['username'],
+            'indate' => Base::time()
+        ]);
+        Docs::notice($id, [ 'type' => 'update' ]);
+        //
+        return Base::retSuccess('保存成功!', [
+            'sid' => $id,
+            'content' => Base::json2array($content),
+        ]);
+    }
+
+    /**
+     * 锁定章节内容
+     *
+     * @apiParam {String} act
+     * - lock: 锁定
+     * - unlock: 解锁
+     * @apiParam {Number} id                章节数据ID
+     */
+    public function section__lock()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Request::input('id'));
+        $act = trim(Request::input('act'));
+        $row = Base::DBC2A(DB::table('docs_section')->where('id', $id)->first());
+        if (empty($row)) {
+            return Base::retError('文档不存在或已被删除!');
+        }
+        $role = Docs::checkRole($row['bookid'], 'edit');
+        if (Base::isError($role)) {
+            return $role;
+        }
+        if ($row['lockdate'] + 60 > Base::time() && $row['lockname'] != $user['username']) {
+            return Base::retError(['已被会员【%】锁定!', Users::nickname($row['lockname'])]);
+        }
+        if ($act == 'lock') {
+            $upArray = [
+                'lockname' => $user['username'],
+                'lockdate' => Base::time(),
+            ];
+        } else {
+            $upArray = [
+                'lockname' => '',
+                'lockdate' => 0,
+            ];
+        }
+        DB::table('docs_section')->where('id', $id)->update($upArray);
+        $upArray['type'] = $act;
+        Docs::notice($id, $upArray);
+        //
+        return Base::retSuccess($act == 'lock' ? '锁定成功' : '已解除锁定', $upArray);
+    }
+}

+ 3154 - 0
app/Http/Controllers/Api/ProjectController.php

@@ -0,0 +1,3154 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Model\DBCache;
+use App\Module\Base;
+use App\Module\BillExport;
+use App\Module\Project;
+use App\Module\Users;
+use DB;
+use Madzipper;
+use Request;
+use Session;
+use SimpleDingTalk\AccessToken;
+use SimpleDingTalk\Notification;
+use SimpleDingTalk\Config;
+
+/**
+ * @apiDefine project
+ *
+ * 项目
+ */
+class ProjectController extends Controller
+{
+    public function __construct()
+    {
+
+        // 配置信息
+        $apps=[
+            'miniprogram_app' => [
+                'info' => [
+                    'AGENT_ID' => '',
+                    'APP_KEY' => '',
+                    'APP_SECRET' => ''
+                ],
+                'access_token' => [
+                    'expires' => 0,
+                    'file_path' => ''
+                ],
+                'callback_info' => [
+                    'aes_key' => '',
+                    'token' => ''
+                ],
+                'login_info' => [
+                    'authorize' => [
+                        'redirect_uri' => '',
+                        'dingtalk_login_uri' => ''
+                    ]
+                ],
+                'v2' => [
+                    'access_token' => [
+                        'expires' => 0,
+                        'file_path' => ''
+                    ],
+
+                ],
+                'userAccessToken' => [
+                    'expires' => 0,
+                    'file_path' => ''
+                ]
+            ],
+            'micro_app' => [
+                'info' => [
+                    'AGENT_ID' => '1602970634',
+                    'APP_KEY' => 'dingoduj8nh4jsroanpr',
+                    'APP_SECRET' => '9qsEDDVN8sJ96GMe3pqHpiJuEwXnDBHg010kBJJc6GK--HDQ0Cnv5Twuv97ge_JS'
+                ],
+                'access_token' => [
+                    'expires' => 0,
+                    'file_path' => base_path('DingTalkToken')
+                ],
+                'callback_info' => [
+                    'aes_key' => '',
+                    'token' => ''
+                ],
+                'page' => [
+                    'app' => '',
+                    'pc' => '',
+                    'management' => ''
+                ],
+                'login_info' => [
+                    'authorize' => [
+                        'redirect_uri' => '',
+                        'dingtalk_login_uri'=>''
+                    ]
+                ],
+                'v2' => [
+                    'access_token' => [
+                        'expires' => 0,
+                        'file_path' => ''
+                    ],
+                ],
+                'userAccessToken' => [
+                    'expires' => 0,
+                    'file_path' => base_path('DingTalkToken')
+                ]
+            ]
+
+        ];
+
+        $robots=[
+            'robot1' => [
+                'info' => [
+                    'AGENT_ID' => 123456,
+                    'APP_KEY' => '',
+                    'APP_SECRET' => '',
+                    'access_token' => '',
+                    'SEC' => ''
+                ],
+                'access_token' => [
+                    'expires' => 180,
+                    'file_path' => './robot.json'
+                ]
+
+            ],
+        ];
+
+        Config::setRobot($robots)->
+        setApp($apps)->
+        setAppType('micro_app')->
+        setRobotType('robot1')->
+        setCorpId('dingc844bf6147f4d40c35c2f4657eb6378f');
+
+    }
+
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+    /**
+     * 项目列表
+     *
+     * @apiParam {String} act           类型
+     * - join: 加入的项目(默认)
+     * - favor: 收藏的项目
+     * - manage: 管理的项目
+     * @apiParam {Number} [page]        当前页,默认:1
+     * @apiParam {Number} [pagesize]    每页显示数量,默认:20,最大:100
+     */
+    public function lists()
+    {
+
+//        AccessToken::generateToken();
+//        $users = DB::table('users')->whereIn("username",["18060002035"])->pluck("userid")->toArray();
+//        $json = [
+//            'userid_list' => implode(',',$users),
+//            'msg' => [
+//                'msgtype' => 'oa',
+//                'oa' => [
+//                    'message_url' => 'http://dingtalk.com',
+//                    'head' => [
+//                        'bgcolor' => 'FFBBBBBB',
+//                        'text' => '头部标题'
+//                    ],
+//                    'body' => [
+//                        'title' => '任务负责人通知',
+//                        'content' => '您被设置为XXX任务的负责人,请及时查看',
+//                        'author' => 'XXX'
+//                    ]
+//                ]
+//            ],
+//
+//        ];
+//
+
+        //$res = Users::username2basic("18060002035");
+        //\Log::channel("stderr")->info(print_r($res,true));
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $whereArray = [];
+        $whereArray[] = ['project_lists.delete', '=', 0];
+        if(!in_array('admin',$user['identity'])){
+            $whereArray[] = ['project_users.username', '=', $user['username']];
+            switch (Request::input('act')) {
+                case "favor": {
+                    $whereArray[] = ['project_users.type', '=', '收藏'];
+                    break;
+                }
+                case "manage": {
+                    $whereArray[] = ['project_users.type', '=', '成员'];
+                    $whereArray[] = ['project_users.isowner', '=', 1];
+                    break;
+                }
+                default: {
+                    $whereArray[] = ['project_users.type', '=', '成员'];
+                    break;
+                }
+            }
+            $lists = DB::table('project_lists')
+                ->join('project_users', 'project_lists.id', '=', 'project_users.projectid')
+                ->select(['project_lists.*', 'project_users.isowner', 'project_users.indate as uindate'])
+                ->where($whereArray)
+                ->orderByDesc('project_lists.id')->paginate(Base::getPaginate(100, 20));
+        }else{
+            $lists = DB::table('project_lists')
+                ->select(['project_lists.*'])
+                ->where($whereArray)
+                ->orderByDesc('project_lists.id')->paginate(Base::getPaginate(100, 20));
+        }
+
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的项目');
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $tmpBuilder = DB::table('project_task')->where([
+                'projectid' => $item['id'],
+                'delete' => 0,
+                'archived' => 0,
+            ]);
+            $tmpBuilder->where(function ($query) use ($user) {
+                $query->where('username', $user['username']);
+                $query->orWhereIn('id', function ($inQuery) use ($user) {
+                    $inQuery->from('project_users')
+                        ->select('taskid')
+                        ->where('username', $user['username'])
+                        ->where('type', '负责人');
+                });
+            });
+            $item['self_count'] = $tmpBuilder->count();
+            $item['self_complete'] = $tmpBuilder->where('complete', 1)->count();
+            //
+            $tmpBuilder = DB::table('project_users')
+                ->join('users', 'project_users.username', '=', 'users.username')
+                ->select(['users.username', 'users.nickname', 'users.userimg'])
+                ->where([
+                    ['project_users.projectid', $item['id']],
+                    ['project_users.type', '成员'],
+                ]);
+            $item['people_count'] = $tmpBuilder->count();
+            $item['people_lists'] = Users::userimg(Base::DBC2A($tmpBuilder->orderBy('project_users.id')->take(5)->get()));
+            //
+            $lists['lists'][$key] = $item;
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 项目详情
+     *
+     * @apiParam {Number} projectid     项目ID
+     */
+    public function detail()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        if(!in_array('admin',$user['identity'])){
+            $inRes = Project::inThe($projectid, $user['username']);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        }
+
+        $projectSetting = Base::string2array($projectDetail['setting']);
+        //子分类
+        $label = Base::DBC2A(DB::table('project_label')->where('projectid', $projectid)->orderBy('inorder')->orderBy('id')->get());
+        $simpleLabel = [];
+        //任务
+        $whereArray = [
+            'projectid' => $projectid,
+            'delete' => 0,
+            'archived' => 0,
+            'complete' => 0
+        ];
+        if ($projectSetting['complete_show'] == 'show') {
+            unset($whereArray['complete']);
+        }
+        $task = Base::DBC2A(DB::table('project_task')->where($whereArray)->orderByDesc('inorder')->orderByDesc('id')->get());
+        //任务归类
+        foreach ($label AS $index => $temp) {
+            $taskLists = [];
+            foreach ($task AS $info) {
+                if ($temp['id'] == $info['labelid']) {
+                    $info['persons'] = Project::taskPersons($info);
+                    $info['overdue'] = Project::taskIsOverdue($info);
+                    $subtask = Base::DBC2A(DB::table('project_sub_task')->where(['taskid'=>$info['id'], 'delete' => 0])->orderByDesc('userorder')->get());
+                    $info['subtask'] = $subtask;
+                    $info['follower'] = Base::string2array($info['follower']);
+                    $info['plantime'] = ($info['startdate'] > 0 ? date("Y-m-d",$info['startdate']) : "未设置") . "-" . ($info['enddate'] > 0 ? date("Y-m-d",$info['enddate']) : "未设置");
+                    $taskLists[] = array_merge($info, Users::username2basic($info['username']));
+                }
+            }
+            $label[$index]['taskLists'] = $taskLists;
+            $simpleLabel[] = ['id' => $temp['id'], 'title' => $temp['title']];
+        }
+        //
+        return Base::retSuccess('success', [
+            'project' => $projectDetail,
+            'label' => $label,
+            'simpleLabel' => $simpleLabel,
+        ]);
+    }
+
+    /**
+     * 获取项目负责人
+     *
+     * @apiParam {Number} projectid     项目ID
+     */
+    public function leader()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->select(['username'])->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        return Base::retSuccess('success', [
+            'username' => $projectDetail['username'],
+        ]);
+    }
+
+    /**
+     * 添加项目
+     *
+     * @apiParam {String} title         项目名称
+     * @apiParam {Array} labels         流程,格式[流程1, 流程2]
+     */
+    public function add()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //项目名称
+        $title = trim(Request::input('title'));
+        if (mb_strlen($title) < 2) {
+            return Base::retError('项目名称不可以少于2个字!');
+        } elseif (mb_strlen($title) > 32) {
+            return Base::retError('项目名称最多只能设置32个字!');
+        }
+        //流程
+        $labels = Request::input('labels');
+        if (!is_array($labels)) $labels = [];
+        $insertLabels = [];
+        $inorder = 0;
+        foreach ($labels AS $label) {
+            $label = trim($label);
+            if ($label) {
+                $insertLabels[] = [
+                    'title' => $label,
+                    'inorder' => $inorder++,
+                ];
+            }
+        }
+        if (empty($insertLabels)) {
+            $insertLabels[] = [
+                'title' => '默认',
+                'inorder' => 0,
+            ];
+        }
+        if (count($insertLabels) > 100) {
+            return Base::retError(['项目流程最多不能超过%个!', 100]);
+        }
+        //开始创建
+        $projectid = DB::table('project_lists')->insertGetId([
+            'title' => $title,
+            'username' => $user['username'],
+            'createuser' => $user['username'],
+            'indate' => Base::time()
+        ]);
+        if ($projectid) {
+            foreach ($insertLabels AS $key => $label) {
+                $insertLabels[$key]['projectid'] = $projectid;
+            }
+            DB::table('project_label')->insert($insertLabels);
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $projectid,
+                'username' => $user['username'],
+                'detail' => '创建项目',
+                'indate' => Base::time(),
+            ]);
+            DB::table('project_users')->insert([
+                'type' => '成员',
+                'projectid' => $projectid,
+                'isowner' => 1,
+                'username' => $user['username'],
+                'indate' => Base::time()
+            ]);
+            return Base::retSuccess('添加成功!');
+        } else {
+            return Base::retError('添加失败!');
+        }
+    }
+
+
+    /**
+     * 设置项目
+     *
+     * @apiParam {String} act           类型
+     * - save: 保存
+     * - other: 读取
+     * @apiParam {Number} projectid     项目ID
+     * @apiParam {Object} ...           其他保存参数
+     *
+     * @throws \Throwable
+     */
+    public function setting()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        //
+        $setting = Base::string2array($projectDetail['setting']);
+        $act = trim(Request::input('act'));
+        if ($act == 'save') {
+            if ($projectDetail['username'] != $user['username'] && !in_array('admin',$user['identity'])) {
+                return Base::retError('你不是项目负责人!');
+            }
+            foreach (Request::input() AS $key => $value) {
+                if (in_array($key, ['project_desc', 'add_role', 'edit_role', 'complete_role', 'archived_role', 'del_role', 'complete_show'])) {
+                    $setting[$key] = $value;
+                }
+            }
+            DB::table('project_lists')->where('id', $projectDetail['id'])->update([
+                'setting' => Base::string2array($setting)
+            ]);
+        }
+        //
+        foreach (['edit_role', 'complete_role', 'archived_role', 'del_role'] AS $key) {
+            $setting[$key] = is_array($setting[$key]) ? $setting[$key] : ['__', 'owner'];
+        }
+        $setting['add_role'] = is_array($setting['add_role']) ? $setting['add_role'] : ['__', 'member'];
+        $setting['complete_show'] = $setting['complete_show'] ?: 'hide';
+        //
+        return Base::retSuccess($act == 'save' ? '修改成功!' : 'success', $setting ?: json_decode('{}'));
+    }
+
+    /**
+     * 收藏项目
+     *
+     * @apiParam {String} act           类型
+     * - cancel: 取消收藏
+     * - else: 添加收藏
+     * @apiParam {Number} projectid     项目ID
+     *
+     * @throws \Throwable
+     */
+    public function favor()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        return DB::transaction(function () use ($projectDetail, $user) {
+            switch (Request::input('act')) {
+                case 'cancel': {
+                    if (DB::table('project_users')->where([
+                        'type' => '收藏',
+                        'projectid' => $projectDetail['id'],
+                        'username' => $user['username'],
+                    ])->delete()) {
+                        DB::table('project_log')->insert([
+                            'type' => '日志',
+                            'projectid' => $projectDetail['id'],
+                            'username' => $user['username'],
+                            'detail' => '取消收藏',
+                            'indate' => Base::time()
+                        ]);
+                        return Base::retSuccess('取消成功!');
+                    }
+                    return Base::retSuccess('已取消!');
+                }
+                default: {
+                    $row = Base::DBC2A(DB::table('project_users')->where([
+                        'type' => '收藏',
+                        'projectid' => $projectDetail['id'],
+                        'username' => $user['username'],
+                    ])->lockForUpdate()->first());
+                    if (empty($row)) {
+                        DB::table('project_users')->insert([
+                            'type' => '收藏',
+                            'projectid' => $projectDetail['id'],
+                            'isowner' => $projectDetail['username'] == $user['username'] ? 1 : 0,
+                            'username' => $user['username'],
+                            'indate' => Base::time()
+                        ]);
+                        DB::table('project_log')->insert([
+                            'type' => '日志',
+                            'projectid' => $projectDetail['id'],
+                            'username' => $user['username'],
+                            'detail' => '收藏项目',
+                            'indate' => Base::time()
+                        ]);
+                        return Base::retSuccess('收藏成功!');
+                    }
+                    return Base::retSuccess('已收藏!');
+                }
+            }
+        });
+    }
+
+    /**
+     * 重命名项目
+     *
+     * @apiParam {Number} projectid     项目ID
+     * @apiParam {String} title         项目新名称
+     */
+    public function rename()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        if ($projectDetail['username'] != $user['username']) {
+            return Base::retError('你不是项目负责人!');
+        }
+        //
+        $title = trim(Request::input('title'));
+        if (mb_strlen($title) < 2) {
+            return Base::retError('项目名称不可以少于2个字!');
+        } elseif (mb_strlen($title) > 32) {
+            return Base::retError('项目名称最多只能设置32个字!');
+        }
+        //
+        DB::table('project_lists')->where('id', $projectDetail['id'])->update([
+            'title' => $title
+        ]);
+        DB::table('project_log')->insert([
+            'type' => '日志',
+            'projectid' => $projectDetail['id'],
+            'username' => $user['username'],
+            'detail' => '【' . $projectDetail['title'] . '】重命名【' . $title . '】',
+            'indate' => Base::time()
+        ]);
+        //
+        return Base::retSuccess('修改成功!');
+    }
+
+    /**
+     * 移交项目
+     *
+     * @apiParam {Number} projectid     项目ID
+     * @apiParam {String} username      项目新负责人用户名
+     *
+     * @throws \Throwable
+     */
+    public function transfer()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        if ($projectDetail['username'] != $user['username']) {
+            return Base::retError('你不是项目负责人!');
+        }
+        //
+        $username = trim(Request::input('username'));
+        if ($username == $projectDetail['username']) {
+            return Base::retError('你已是项目负责人!');
+        }
+        $count = DB::table('users')->where('username', $username)->count();
+        if ($count <= 0) {
+            return Base::retError(['成员用户名(%)不存在!', $username]);
+        }
+        //判断是否已在项目成员内
+        $inRes = Project::inThe($projectDetail['id'], $username);
+        if (Base::isError($inRes)) {
+            DB::table('project_users')->insert([
+                'type' => '成员',
+                'projectid' => $projectDetail['id'],
+                'isowner' => 0,
+                'username' => $username,
+                'indate' => Base::time()
+            ]);
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $projectDetail['id'],
+                'username' => $username,
+                'detail' => '自动加入项目',
+                'indate' => Base::time()
+            ]);
+        }
+        //开始移交
+        return DB::transaction(function () use ($user, $username, $projectDetail) {
+            DB::table('project_lists')->where('id', $projectDetail['id'])->update([
+                'username' => $username
+            ]);
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $projectDetail['id'],
+                'username' => $user['username'],
+                'detail' => '【' . $projectDetail['username'] . '】移交给【' . $username . '】',
+                'indate' => Base::time()
+            ]);
+            DB::table('project_users')->where([
+                'projectid' => $projectDetail['id'],
+                'username' => $projectDetail['username'],
+            ])->update([
+                'isowner' => 0
+            ]);
+            DB::table('project_users')->where([
+                'projectid' => $projectDetail['id'],
+                'username' => $username,
+            ])->update([
+                'isowner' => 1
+            ]);
+            return Base::retSuccess('移交成功!');
+        });
+    }
+
+    /**
+     * 删除项目
+     *
+     * @apiParam {Number} projectid     项目ID
+     */
+    public function delete()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        if ($projectDetail['username'] != $user['username']) {
+            return Base::retError('你不是项目负责人!');
+        }
+        //
+        DB::table('project_lists')->where('id', $projectDetail['id'])->update([
+            'delete' => 1,
+            'deletedate' => Base::time()
+        ]);
+        DB::table('project_task')->where('projectid', $projectDetail['id'])->update([
+            'delete' => 1,
+            'deletedate' => Base::time()
+        ]);
+        DB::table('project_files')->where('projectid', $projectDetail['id'])->update([
+            'delete' => 1,
+            'deletedate' => Base::time()
+        ]);
+        DB::table('project_log')->insert([
+            'type' => '日志',
+            'projectid' => $projectDetail['id'],
+            'username' => $user['username'],
+            'detail' => '删除项目',
+            'indate' => Base::time()
+        ]);
+        //
+        return Base::retSuccess('删除成功!');
+    }
+
+    /**
+     * 排序任务
+     *
+     * @apiParam {Number} projectid     项目ID
+     * @apiParam {String} oldsort       旧排序数据
+     * @apiParam {String} newsort       新排序数据
+     * @apiParam {Number} label         赋值表示排序分类,否则排序任务(调整任务所属分类)
+     */
+    public function sort()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        if(!in_array('admin',$user['identity'])){
+            $inRes = Project::inThe($projectid, $user['username']);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        }
+
+        //
+        $oldSort = explode(";", Request::input('oldsort'));
+        $newSort = explode(";", Request::input('newsort'));
+        if (count($oldSort) != count($newSort)) {
+            return Base::retError('参数错误!');
+        }
+        if (intval(Request::input('label'))) {
+            //排序分类
+            foreach ($newSort AS $sort => $item) {
+                list($newLabelid, $newTask) = explode(':', $item);
+                list($oldLabelid, $oldTask) = explode(':', $oldSort[$sort]);
+                if ($newLabelid != $oldLabelid) {
+                    DB::table('project_label')->where([
+                        'id' => $newLabelid,
+                        'projectid' => $projectid
+                    ])->update([
+                        'inorder' => intval($sort)
+                    ]);
+                }
+            }
+            $detail = '调整任务列表排序';
+            $sortType = 'label';
+        } else {
+            //排序任务(调整任务归类)
+            foreach ($newSort AS $sort => $item) {
+                list($newLabelid, $newTask) = explode(':', $item);
+                list($oldLabelid, $oldTask) = explode(':', $oldSort[$sort]);
+                if ($newTask != $oldTask) {
+                    $newTask = explode('-', $newTask);
+                    $inorder = count($newTask);
+                    foreach ($newTask AS $taskid) {
+                        DB::table('project_task')->where([
+                            'id' => $taskid,
+                            'projectid' => $projectid
+                        ])->update([
+                            'labelid' => $newLabelid,
+                            'inorder' => $inorder
+                        ]);
+                        $inorder--;
+                    }
+                }
+            }
+            $detail = '调整任务排序';
+            $sortType = 'task';
+        }
+        //
+        $row = Base::DBC2A(DB::table('project_log')->where([ 'type' => '日志', 'projectid' => $projectid ])->orderByDesc('id')->first());
+        $continue = 1;
+        if ($row && $row['username'] == $user['username'] && $row['indate'] + 300 > Base::time()) {
+            $other = Base::string2array($row['other']);
+            if ($other['sortType'] == $sortType) {
+                $continue = intval($other['continue']) + 1;
+                if ($continue <= 100) {
+                    DB::table('project_log')->where('id', $row['id'])->update([
+                        'detail' => $detail . '(' . $continue . '次)',
+                        'other' => Base::array2string([
+                            'sortType' => $sortType,
+                            'continue' => $continue,
+                            'times' => $other['times'] . '|' . Base::time(),
+                        ])
+                    ]);
+                }
+            }
+        }
+        if ($continue == 1) {
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $projectid,
+                'username' => $user['username'],
+                'detail' => $detail,
+                'indate' => Base::time(),
+                'other' => Base::array2string([
+                    'sortType' => $sortType,
+                    'continue' => $continue,
+                    'times' => Base::time(),
+                ])
+            ]);
+        }
+        return Base::retSuccess('保存成功!');
+    }
+
+    /**
+     * 排序任务(todo待办)
+     *
+     * @apiParam {String} oldsort       旧排序数据
+     * @apiParam {String} newsort       新排序数据
+     */
+    public function sort__todo()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $oldSort = explode(";", Request::input('oldsort'));
+        $newSort = explode(";", Request::input('newsort'));
+        if (count($oldSort) != count($newSort)) {
+            return Base::retError('参数错误!');
+        }
+        //
+        $levels = [];
+        $logArray = [];
+        $taskLevel = [];
+        foreach ($newSort AS $sort => $item) {
+            list($newLevel, $newTask) = explode(':', $item);
+            list($oldLevel, $oldTask) = explode(':', $oldSort[$sort]);
+            if ($newTask != $oldTask) {
+                $newTask = explode('-', $newTask);
+                $oldTask = explode('-', $oldTask);
+                $userorder = intval(DB::table('project_task')->select('userorder')->where([
+                    'delete' => 0,
+                    'archived' => 0,
+                    'level' => $newLevel,
+                    'username' => $user['username'],
+                ])->orderByDesc('userorder')->value('userorder'));
+                if (count($newTask) < count($oldTask)) {
+                    $userorder--;
+                } else {
+                    $userorder++;
+                }
+                foreach ($newTask AS $taskid) {
+                    $task = Base::DBC2A(DB::table('project_task')->select(['id', 'title', 'projectid', 'level', 'userorder'])->where([
+                        'id' => $taskid,
+                        'username' => $user['username']
+                    ])->first());
+                    $upArray = [];
+                    if ($task) {
+                        if ($task['level'] != $newLevel) {
+                            $upArray['level'] = $newLevel;
+                            $logArray[] = [
+                                'type' => '日志',
+                                'projectid' => $task['projectid'],
+                                'taskid' => $task['id'],
+                                'username' => $user['username'],
+                                'detail' => '调整任务等级为【P' . $newLevel . '】',
+                                'indate' => Base::time(),
+                                'other' => Base::array2string([
+                                    'type' => 'task',
+                                    'id' => $task['id'],
+                                    'title' => $task['title'],
+                                ])
+                            ];
+                            $taskLevel[] = [
+                                'id' => $task['id'],
+                                'level' => $newLevel,
+                            ];
+                        }
+                        if ($task['userorder'] != $userorder) {
+                            $upArray['userorder'] = $userorder;
+                        }
+                    }
+                    if ($upArray) {
+                        DB::table('project_task')->where('id', $taskid)->update($upArray);
+                    }
+                    $userorder--;
+                }
+                $levels[] = $newLevel;
+            }
+        }
+        if ($logArray) {
+            DB::table('project_log')->insert($logArray);
+        }
+        //
+        return Base::retSuccess('保存成功!', [
+            'levels' => $levels,
+            'taskLevel' => $taskLevel,
+        ]);
+    }
+
+    /**
+     * 退出项目
+     *
+     * @apiParam {Number} projectid     项目ID
+     */
+    public function out()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        if ($projectDetail['username'] == $user['username']) {
+            return Base::retError('你是项目负责人,不可退出项目!');
+        }
+
+        if($user['id'] == 1){
+            return array(
+                'ret' => 0,
+                'msg' => '您没必要退出',
+                'data' => []
+            );
+        }
+        if(!in_array('admin',$user['identity'])){
+            $inRes = Project::inThe($projectid, $user['username']);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        }
+
+        //
+        DB::table('project_users')->where([
+            'type' => '成员',
+            'projectid' => $projectDetail['id'],
+            'username' => $user['username'],
+        ])->delete();
+        DB::table('project_log')->insert([
+            'type' => '日志',
+            'projectid' => $projectDetail['id'],
+            'username' => $user['username'],
+            'detail' => '退出项目',
+            'indate' => Base::time()
+        ]);
+        //
+        return Base::retSuccess('退出项目成功!');
+    }
+
+    /**
+     * 项目成员-列表
+     *
+     * @apiParam {Number} projectid     项目ID
+     * @apiParam {Number} [page]        当前页,默认:1
+     * @apiParam {Number} [pagesize]    每页显示数量,默认:20,最大:100
+     */
+    public function users__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = intval(Request::input('projectid'));
+        if(!in_array('admin',$user['identity'])){
+            $inRes = Project::inThe($projectid, $user['username']);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        }
+
+        //
+        $lists = DB::table('project_lists')
+            ->join('project_users', 'project_lists.id', '=', 'project_users.projectid')
+            ->select(['project_lists.title', 'project_users.*'])
+            ->where([
+                ['project_lists.id', $projectid],
+                ['project_lists.delete', 0],
+                ['project_users.type', '成员'],
+            ])
+            ->orderByDesc('project_users.isowner')->orderByDesc('project_users.id')->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的成员');
+        }
+        foreach ($lists['lists'] AS $key => $projectDetail) {
+            $userInfo = Users::username2basic($projectDetail['username']);
+            $lists['lists'][$key]['userimg'] = $userInfo['userimg'];
+            $lists['lists'][$key]['nickname'] = $userInfo['nickname'];
+            $lists['lists'][$key]['profession'] = $userInfo['profession'];
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 项目成员-添加、删除
+     *
+     * @apiParam {String} act
+     * - delete: 删除成员
+     * - else: 添加成员
+     * @apiParam {Number} projectid             项目ID
+     * @apiParam {Array|String} username        用户名(或用户名组)
+     */
+    public function users__join()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($projectDetail)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        $usernames = Request::input('username');
+        if (empty($usernames)) {
+            return Base::retError('参数错误!');
+        }
+        if (!is_array($usernames)) {
+            if (Base::strExists($usernames, ',')) {
+                $usernames = explode(',', $usernames);
+            } else {
+                $usernames = [$usernames];
+            }
+        }
+        //
+        $logArray = [];
+        foreach ($usernames AS $username) {
+            $inRes = Project::inThe($projectid, $username);
+            switch (Request::input('act')) {
+                case 'delete': {
+                    if (!Base::isError($inRes) && $projectDetail['username'] != $username) {
+                        DB::table('project_users')->where([
+                            'type' => '成员',
+                            'projectid' => $projectid,
+                            'username' => $username,
+                        ])->delete();
+                        $logArray[] = [
+                            'type' => '日志',
+                            'projectid' => $projectDetail['id'],
+                            'username' => $user['username'],
+                            'detail' => '将成员移出项目',
+                            'indate' => Base::time(),
+                            'other' => Base::array2string([
+                                'type' => 'username',
+                                'username' => $username,
+                            ])
+                        ];
+                    }
+                    break;
+                }
+                default: {
+                    if (Base::isError($inRes)) {
+                        DB::table('project_users')->insert([
+                            'type' => '成员',
+                            'projectid' => $projectid,
+                            'isowner' => 0,
+                            'username' => $username,
+                            'indate' => Base::time()
+                        ]);
+                        $logArray[] = [
+                            'type' => '日志',
+                            'projectid' => $projectDetail['id'],
+                            'username' => $user['username'],
+                            'detail' => '邀请成员加入项目',
+                            'indate' => Base::time(),
+                            'other' => Base::array2string([
+                                'type' => 'username',
+                                'username' => $username,
+                            ])
+                        ];
+                    }
+                    break;
+                }
+            }
+        }
+        if ($logArray) {
+            DB::table('project_log')->insert($logArray);
+        }
+        return Base::retSuccess('操作完成!');
+    }
+
+    /**
+     * 项目子分类-添加分类
+     *
+     * @apiParam {Number} projectid             项目ID
+     * @apiParam {String} title                 分类名称
+     */
+    public function label__add()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        if(!in_array('admin',$user['identity'])){
+            $inRes = Project::inThe($projectid, $user['username']);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        }
+
+        //
+        $title = trim(Request::input('title'));
+        if (empty($title)) {
+            return Base::retError('列表名称不能为空!');
+        } elseif (mb_strlen($title) > 32) {
+            return Base::retError('列表名称最多只能设置32个字!');
+        }
+        //
+        $count = DB::table('project_label')->where('projectid', $projectid)->where('title', $title)->count();
+        if ($count > 0) {
+            return Base::retError('列表名称已存在!');
+        }
+        if (DB::table('project_label')->where('projectid', $projectid)->count() + 1 >= 100) {
+            return Base::retError(['列表最多不能超过%个!', 100]);
+        }
+        //
+        $id = DB::table('project_label')->insertGetId([
+            'projectid' => $projectid,
+            'title' => $title,
+            'inorder' => intval(DB::table('project_label')->where('projectid', $projectid)->orderByDesc('inorder')->value('inorder')) + 1,
+        ]);
+        if (empty($id)) {
+            return Base::retError('系统繁忙,请稍后再试!');
+        }
+        DB::table('project_log')->insert([
+            'type' => '日志',
+            'projectid' => $projectid,
+            'username' => $user['username'],
+            'detail' => '添加任务列表【' . $title . '】',
+            'indate' => Base::time()
+        ]);
+        //
+        $row = Base::DBC2A(DB::table('project_label')->where('id', $id)->first());
+        $row['taskLists'] = [];
+        return Base::retSuccess('添加成功!', $row);
+    }
+
+    /**
+     * 项目子分类-重命名分类
+     *
+     * @apiParam {Number} projectid             项目ID
+     * @apiParam {Number} labelid               分类ID
+     * @apiParam {String} title                 新分类名称
+     */
+    public function label__rename()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        if(!in_array('admin',$user['identity'])){
+            $inRes = Project::inThe($projectid, $user['username']);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        }
+
+        //
+        $title = trim(Request::input('title'));
+        if (empty($title)) {
+            return Base::retError('列表名称不能为空!');
+        } elseif (mb_strlen($title) > 32) {
+            return Base::retError('列表名称最多只能设置32个字!');
+        }
+        //
+        $labelid = intval(Request::input('labelid'));
+        $count = DB::table('project_label')->where('id', '!=', $labelid)->where('projectid', $projectid)->where('title', $title)->count();
+        if ($count > 0) {
+            return Base::retError('列表名称已存在!');
+        }
+        //
+        $labelDetail = Base::DBC2A(DB::table('project_label')->where('id', $labelid)->where('projectid', $projectid)->first());
+        if (empty($labelDetail)) {
+            return Base::retError('列表不存在或已被删除!');
+        }
+        //
+        if (DB::table('project_label')->where('id', $labelDetail['id'])->update([ 'title' => $title ])) {
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $projectid,
+                'username' => $user['username'],
+                'detail' => '任务列表【' . $labelDetail['title'] . '】重命名【' . $title . '】',
+                'indate' => Base::time()
+            ]);
+        }
+        //
+        return Base::retSuccess('修改成功!');
+    }
+
+    /**
+     * 项目子分类-删除分类
+     *
+     * @apiParam {Number} projectid             项目ID
+     * @apiParam {Number} labelid               分类ID
+     *
+     * @throws \Throwable
+     */
+    public function label__delete()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = trim(Request::input('projectid'));
+        if(!in_array('admin',$user['identity'])){
+            $inRes = Project::inThe($projectid, $user['username']);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        }
+
+        //
+        $labelid = intval(Request::input('labelid'));
+        $labelDetail = Base::DBC2A(DB::table('project_label')->where('id', $labelid)->where('projectid', $projectid)->first());
+        if (empty($labelDetail)) {
+            return Base::retError('列表不存在或已被删除!');
+        }
+        //
+        return DB::transaction(function () use ($user, $projectid, $labelDetail) {
+            $taskLists = Base::DBC2A(DB::table('project_task')->where('labelid', $labelDetail['id'])->get());
+            $logArray = [];
+            foreach ($taskLists AS $task) {
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $projectid,
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '删除列表任务',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                    ])
+                ];
+            }
+            $logArray[] = [
+                'type' => '日志',
+                'projectid' => $projectid,
+                'taskid' => 0,
+                'username' => $user['username'],
+                'detail' => '删除任务列表【' . $labelDetail['title'] . '】',
+                'indate' => Base::time(),
+                'other' => Base::array2string([])
+            ];
+            DB::table('project_task')->where('labelid', $labelDetail['id'])->update([
+                'delete' => 1,
+                'deletedate' => Base::time()
+            ]);
+            DB::table('project_label')->where('id', $labelDetail['id'])->delete();
+            DB::table('project_log')->insert($logArray);
+            Project::updateNum($projectid);
+            //
+            return Base::retSuccess('删除成功!');
+        });
+    }
+
+    /**
+     * 项目任务-列表
+     *
+     * @apiParam {Number} [projectid]           项目ID
+     * @apiParam {Number} [labelid]             项目子分类ID
+     * @apiParam {String} [username]            负责人用户名(如果项目ID为空时此参数无效只获取自己的任务)
+     * @apiParam {Number} [level]               任务等级(1~4)
+     * @apiParam {String} [archived]            任务是否归档
+     * - 未归档 (默认)
+     * - 已归档
+     * - 全部
+     * @apiParam {String} [type]                任务类型
+     * - 全部(默认)
+     * - 未完成
+     * - 已超期
+     * - 已完成
+     * @apiParam {Number} [createuser]          是否仅获取自己创建的项目(1:是;赋值时projectid和username不强制)
+     * @apiParam {Number} [attention]           是否仅获取关注数据(1:是;赋值时projectid和username不强制)
+     * @apiParam {Number} [statistics]          是否获取统计数据(1:获取)
+     * @apiParam {String} [startdate]           任务开始时间,格式:YYYY-MM-DD
+     * @apiParam {String} [enddate]             任务结束时间,格式:YYYY-MM-DD
+     *
+     * @apiParam {Object} [sorts]               排序方式,格式:{key:'', order:''}
+     * - key: title|labelid|enddate|username|level|indate|type|inorder(默认)|userorder
+     * - order: asc|desc
+     * - 【archived=已归档】或【startdate和enddate赋值】时无效
+     *
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     * @apiParam {Number} [export]              是否导出并返回下载地址(1:是;仅支持projectid赋值时)
+     */
+    public function task__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = intval(Request::input('projectid'));
+        $export = intval(Request::input('export'));
+        if ($projectid > 0) {
+            if(!in_array('admin',$user['identity'])){
+                $inRes = Project::inThe($projectid, $user['username']);
+                if (Base::isError($inRes)) {
+                    return $inRes;
+                }
+            }
+
+        } else {
+            $export = 0;
+        }
+        //
+        $orderBy = '`inorder` DESC,`id` DESC';
+        $sorts = Base::json2array(Request::input('sorts'));
+        if (in_array($sorts['order'], ['asc', 'desc'])) {
+            switch ($sorts['key']) {
+                case 'title':
+                case 'labelid':
+                case 'enddate':
+                case 'username':
+                case 'level':
+                case 'indate':
+                case 'inorder':
+                case 'userorder':
+                    $orderBy = '`' . $sorts['key'] . '` ' . $sorts['order'] . ',`id` DESC';
+                    break;
+                case 'type':
+                    $orderBy = 'CASE WHEN `complete`= 0 AND `enddate` BETWEEN 1 AND ' . Base::time() . ' THEN 0 ELSE 1 END ' . $sorts['order'] . ', `complete` ' . $sorts['order'] . ',`id` DESC';
+                    break;
+            }
+        }
+        //
+        $builder = DB::table('project_task');
+        $selectArray = ['project_task.*'];
+        $whereRaw = null;
+        $whereFunc = null;
+        $whereArray = [];
+        $whereArray[] = ['project_task.delete', '=', 0];
+        if (intval(Request::input('createuser')) === 1) {
+            $whereArray[] = ['project_task.createuser', '=', $user['username']];
+            if ($projectid > 0) {
+                $whereArray[] = ['project_lists.id', '=', $projectid];
+            }
+            if (trim(Request::input('username'))) {
+                $whereArray[] = ['project_task.username', '=', trim(Request::input('username'))];
+            }
+        } else if (intval(Request::input('attention')) === 1) {
+            if ($projectid > 0) {
+                $whereArray[] = ['project_lists.id', '=', $projectid];
+            }
+            if (trim(Request::input('username'))) {
+                $whereArray[] = ['project_task.username', '=', trim(Request::input('username'))];
+            }
+        } else {
+            if ($projectid > 0) {
+                $whereArray[] = ['project_lists.id', '=', $projectid];
+                if (trim(Request::input('username'))) {
+                    $whereArray[] = ['project_task.username', '=', trim(Request::input('username'))];
+                }
+            } else {
+                $builder->where(function ($query) use ($user) {
+                    $query->where('project_task.username', $user['username']);
+                    $query->orWhereIn('project_task.id', function ($inQuery) use ($user) {
+                        $inQuery->from('project_users')
+                            ->select('taskid')
+                            ->where('username', $user['username'])
+                            ->where('type', '负责人');
+                    });
+                });
+            }
+        }
+        if (intval(Request::input('labelid')) > 0) {
+            $whereArray[] = ['project_task.labelid', '=', intval(Request::input('labelid'))];
+        }
+        if (intval(Request::input('level')) > 0) {
+            $whereArray[] = ['project_task.level', '=', intval(Request::input('level'))];
+        }
+        $archived = trim(Request::input('archived'));
+        if (empty($archived)) $archived = "未归档";
+        switch ($archived) {
+            case '已归档':
+                $whereArray[] = ['project_task.archived', '=', 1];
+                $orderBy = '`archiveddate` DESC';
+                break;
+            case '未归档':
+                $whereArray[] = ['project_task.archived', '=', 0];
+                break;
+        }
+        $type = trim(Request::input('type'));
+        switch ($type) {
+            case '未完成':
+                $whereArray[] = ['project_task.complete', '=', 0];
+                break;
+            case '已超期':
+                $whereArray[] = ['project_task.complete', '=', 0];
+                $whereArray[] = ['project_task.enddate', '>', 0];
+                $whereArray[] = ['project_task.enddate', '<=', Base::time()];
+                break;
+            case '已完成':
+                $whereArray[] = ['project_task.complete', '=', 1];
+                break;
+        }
+        $startdate = trim(Request::input('startdate'));
+        $enddate = trim(Request::input('enddate'));
+        if (Base::isDate($startdate) || Base::isDate($enddate)) {
+            $startdate = strtotime($startdate . ' 00:00:00');
+            $enddate = strtotime($enddate . ' 23:59:59');
+            $whereRaw.= $whereRaw ? ' AND ' : '';
+            $whereRaw.= "((`startdate` >= " . $startdate . " OR `startdate` = 0) AND (`enddate` <= " . $enddate . " OR `enddate` = 0))";
+            $orderBy = '`startdate` DESC';
+        }
+        //
+        if ($projectid > 0) {
+            $builder->join('project_lists', 'project_lists.id', '=', 'project_task.projectid');
+        }
+        if (intval(Request::input('attention')) === 1) {
+            $builder->join('project_users', 'project_users.taskid', '=', 'project_task.id');
+            $builder->where([
+                ['project_users.type', '=', '关注'],
+                ['project_users.username', '=', $user['username']],
+            ]);
+            $selectArray[] = 'project_users.indate AS attentiondate';
+        }
+        if ($whereRaw) {
+            $builder->whereRaw($whereRaw);
+        }
+
+        $builder->select($selectArray)->where($whereArray)->orderByRaw($orderBy);
+        if ($export) {
+            //导出excel
+            $checkRole = Project::role('project_role_export', $projectid);
+            if (Base::isError($checkRole)) {
+                return $checkRole;
+            }
+            $lists = Base::DBC2A($builder->get());
+            if (empty($lists)) {
+                return Base::retError('未找到任何相关的任务!');
+            }
+            $labels = DB::table('project_label')->select(['id', 'title'])->where('projectid', $projectid)->pluck('title', 'id');
+            $fileName = str_replace(['/', '\\', ':', '*', '"', '<', '>', '|', '?'], '_', $checkRole['data']['title'] ?: $projectid) . '_' . Base::time() . '.xls';
+            $filePath = "temp/task/export/" . date("Ym", Base::time());
+            $headings = [];
+            $headings[] = '任务ID';
+            $headings[] = '任务标题';
+            $headings[] = '任务阶段';
+            $headings[] = '计划时间(开始)';
+            $headings[] = '计划时间(结束)';
+            $headings[] = '负责人';
+            $headings[] = '负责人(昵称)';
+            $headings[] = '创建人';
+            $headings[] = '创建人(昵称)';
+            $headings[] = '优先级';
+            $headings[] = '状态';
+            $headings[] = '是否超期';
+            $headings[] = '创建时间';
+            $headings[] = '最近更新时间';
+            $data = [];
+            foreach ($lists AS $info) {
+                $overdue = Project::taskIsOverdue($info);
+                $data[] = [
+                    $info['id'],
+                    $info['title'],
+                    $labels[$info['labelid']] ?: '-',
+                    $info['startdate'] ? date("Y-m-d H:i:s", $info['startdate']) : '-',
+                    $info['enddate'] ? date("Y-m-d H:i:s", $info['enddate']) : '-',
+                    $info['username'],
+                    DBCache::table('users')->where('username', $info['username'])->value('nickname') ?: $info['username'],
+                    $info['createuser'],
+                    DBCache::table('users')->where('username', $info['createuser'])->value('nickname') ?: $info['createuser'],
+                    'P' . $info['level'],
+                    ($overdue ? '已超期' : ($info['complete'] ? '已完成' : '未完成')),
+                    $overdue ? '是' : '-',
+                    date("Y-m-d H:i:s", $info['indate'])
+                ];
+                $subtask = Base::DBC2A(DB::table('project_sub_task')->where(['taskid'=>$info['id'], 'delete' => 0])->orderByDesc('userorder')->get());
+                if ($subtask) {
+                    foreach ($subtask AS $subInfo) {
+                        $data[] = [
+                            '',
+                            $subInfo['detail'],
+                            '',
+                            '',
+                            '',
+                            $subInfo['uname'] ?: '',
+                            $subInfo['uname'] ? (DBCache::table('users')->where('username', $subInfo['uname'])->value('nickname') ?: $subInfo['uname']) : $subInfo['uname'],
+                            '',
+                            '',
+                            '',
+                            $subInfo['status'] == 'complete' ? '已完成' : '未完成',
+                            '',
+                            date("Y-m-d H:i:s", $subInfo['indate'])
+                        ];
+                    }
+                }
+            }
+            $res = BillExport::create()->setHeadings($headings)->setData($data)->store($filePath . "/" . $fileName);
+            if ($res != 1) {
+                return Base::retError(['导出失败,%!', $fileName]);
+            }
+            //
+            $xlsPath = storage_path("app/" . $filePath . "/" . $fileName);
+            $zipFile = "app/" . $filePath . "/" . Base::rightDelete($fileName, '.xls'). ".zip";
+            $zipPath = storage_path($zipFile);
+            if (file_exists($zipPath)) {
+                Base::deleteDirAndFile($zipPath, true);
+            }
+            try {
+                Madzipper::make($zipPath)->add($xlsPath)->close();
+            } catch (\Exception $e) { }
+            //
+            if (file_exists($zipPath)) {
+                $base64 = base64_encode(Base::array2string([
+                    'projectid' => $projectid,
+                    'file' => $zipFile,
+                ]));
+                Session::put('task::export:username', $user['username']);
+                return Base::retSuccess("success", [
+                    'size' => Base::twoFloat(filesize($zipPath) / 1024, true),
+                    'url' => Base::fillUrl('api/project/task/export?data=' . urlencode($base64)),
+                ]);
+            } else {
+                return Base::retError('打包失败,请稍后再试...');
+            }
+        }
+        $lists = $builder->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if (intval(Request::input('statistics')) == 1) {
+            $lists['statistics_unfinished'] = $type === '未完成' ? $lists['total'] : DB::table('project_task')->where('projectid', $projectid)->where('delete', 0)->where('archived', 0)->where('complete', 0)->count();
+            $lists['statistics_overdue'] = $type === '已超期' ? $lists['total'] : DB::table('project_task')->where('projectid', $projectid)->where('delete', 0)->where('archived', 0)->where('complete', 0)->whereBetween('enddate', [1, Base::time()])->count();
+            $lists['statistics_complete'] = $type === '已完成' ? $lists['total'] : DB::table('project_task')->where('projectid', $projectid)->where('delete', 0)->where('archived', 0)->where('complete', 1)->count();
+        }
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的任务!', $lists);
+        }
+        foreach ($lists['lists'] AS $key => $info) {
+            $info['persons'] = Project::taskPersons($info);
+            $info['overdue'] = Project::taskIsOverdue($info);
+            $info['subtask'] = Base::DBC2A(DB::table('project_sub_task')->where(['taskid'=>$info['id'], 'delete' => 0])->orderByDesc('userorder')->get());
+            $info['follower'] = Base::string2array($info['follower']);
+            $info['plantime'] = ($info['startdate'] > 0 ? date("Y-m-d",$info['startdate']) : "未设置") . "-" . ($info['enddate'] > 0 ? date("Y-m-d H:i:s",$info['enddate']) : "未设置");
+            $update = DB::table('project_log')->where('taskid', $info['id'])->limit(1)->orderBy('indate','DESC')->first();
+            $info['update'] = $update->indate;
+            $lists['lists'][$key] = array_merge($info, Users::username2basic($info['username']));
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 项目任务-导出结果
+     *
+     * @apiParam {String} data              base64
+     */
+    public function task__export()
+    {
+        $username = Session::get('task::export:username');
+        if (empty($username)) {
+            return Base::ajaxError("请求已过期,请重新导出!", [], 0, 502);
+        }
+        $array = Base::string2array(base64_decode(urldecode(Request::input('data'))));
+        $projectid = intval($array['projectid']);
+        $file = $array['file'];
+        if (empty($projectid)) {
+            return Base::ajaxError("参数错误!", [], 0, 502);
+        }
+        if (empty($file) || !file_exists(storage_path($file))) {
+            return Base::ajaxError("文件不存在!", [], 0, 502);
+        }
+        $checkRole = Project::role('project_role_export', $projectid, 0, $username);
+        if (Base::isError($checkRole)) {
+            return Base::ajaxError($checkRole['msg'], [], 0, 502);
+        }
+        return response()->download(storage_path($file), ($checkRole['data']['title'] ?: Base::time()) . '.zip');
+    }
+
+    /**
+     * 项目任务-详情(与任务有关系的用户(关注的、在项目里的、负责人、创建者)都可以查到)
+     *
+     * @apiParam {Number} taskid              任务ID
+     */
+    public function task__detail()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $taskid = intval(Request::input('taskid'));
+        $tmpLists = Project::taskSomeUsers($taskid);
+        if (!in_array($user['username'], $tmpLists)) {
+            return Base::retError('未能找到此任务或无法管理此任务!');
+        }
+        //
+        $task = Base::DBC2A(DB::table('project_task')->where('id', $taskid)->first());
+        $task['subtask'] = Base::DBC2A(DB::table('project_sub_task')->where(['taskid'=>$taskid, 'delete' => 0])->orderByDesc('userorder')->get());
+        $task['persons'] = Project::taskPersons($task);
+        $task['overdue'] = Project::taskIsOverdue($task);
+        $task['follower'] = Base::string2array($task['follower']);
+        $task = array_merge($task, Users::username2basic($task['username']));
+        $task['projectTitle'] = $task['projectid'] > 0 ? DB::table('project_lists')->where('id', $task['projectid'])->value('title') : '';
+        return Base::retSuccess('success', $task);
+    }
+
+    /**
+     * 项目任务-描述(任务有关系的用户(关注的、在项目里的、负责人、创建者)都可以查到)
+     *
+     * @apiParam {Number} taskid              任务ID
+     */
+    public function task__desc()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $taskid = intval(Request::input('taskid'));
+        $tmpLists = Project::taskSomeUsers($taskid);
+        if (!in_array($user['username'], $tmpLists)) {
+            return Base::retError('未能找到此任务或无法管理此任务!');
+        }
+        //
+        $desc = DB::table('project_content')->where('taskid', $taskid)->value('content');
+        if (empty($desc)) {
+            $desc = DB::table('project_task')->where('id', $taskid)->value('desc');
+        }
+        return Base::retSuccess('success', [
+            'taskid' => $taskid,
+            'desc' => $desc
+        ]);
+    }
+
+    /**
+     * 项目任务-获取数量
+     *
+     * @apiParam {Number} [level]               任务等级(1~4,留空获取所有)
+     */
+    public function task__levelnum()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $whereArray = [];
+        $whereArray[] = ['project_task.delete', '=', 0];
+        $whereArray[] = ['project_task.username', '=', $user['username']];
+        $whereArray[] = ['project_task.archived', '=', 0];
+        $array = [
+            'level_1' => 0,
+            'level_2' => 0,
+            'level_3' => 0,
+            'level_4' => 0,
+        ];
+        $level = intval(Request::input('level'));
+        if ($level > 0) {
+            $array = [];
+            $array['level_' . $level] = 0;
+        }
+        foreach ($array AS $key => $val) {
+            $level = intval(Base::leftDelete($key, 'level_'));
+            $array[$key] = DB::table('project_task')->where($whereArray)->where('level', $level)->count();
+        }
+        return Base::retSuccess('success', $array);
+    }
+
+    /**
+     * 项目任务-添加任务
+     *
+     * @apiParam {String} title                 任务标题
+     * @apiParam {Number} [projectid]           项目ID
+     * @apiParam {Number} [labelid]             项目子分类ID
+     * @apiParam {Number} [level]               任务紧急级别(1~4,默认:2)
+     * @apiParam {String} [username]            任务负责人用户名(如果项目ID为空时此参数无效,负责人为自己)
+     * @apiParam {Number} [insertbottom]        是否添加至列表结尾(1:是,默认:0,仅适用于项目分类列表)
+     *
+     * @throws \Throwable
+     */
+    public function task__add()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = intval(Request::input('projectid'));
+        $labelid = intval(Request::input('labelid'));
+        $insertbottom = intval(Request::input('insertbottom'));
+        if ($projectid > 0) {
+            $projectDetail = Base::DBC2A(DB::table('project_lists')->where('id', $projectid)->where('delete', 0)->first());
+            if (empty($projectDetail)) {
+                return Base::retError('项目不存在或已被删除!');
+            }
+            //
+            $labelDetail = Base::DBC2A(DB::table('project_label')->where('id', $labelid)->where('projectid', $projectid)->first());
+            if (empty($labelDetail)) {
+                return Base::retError('项目子分类不存在或已被删除!');
+            }
+            //
+            if(!in_array('admin',$user['identity'])){
+                $inRes = Project::inThe($projectid, $user['username']);
+                if (Base::isError($inRes)) {
+                    return $inRes;
+                }
+            }
+
+            $checkRole = Project::role('add_role', $projectid, 0);
+            if (Base::isError($checkRole)) {
+                return $checkRole;
+            }
+            //
+            $username = trim(Request::input('username'));
+            if (empty($username)) {
+                $username = $user['username'];
+            }
+            if ($username != $user['username']) {
+                $inRes = Project::inThe($projectid, $username);
+                if (Base::isError($inRes)) {
+                    return Base::retError('负责人不在项目成员内!');
+                }
+            }
+        } else {
+            $username = $user['username'];
+        }
+        //
+        $title = trim(Request::input('title'));
+        if (empty($title)) {
+            return Base::retError('任务标题不能为空!');
+        } elseif (mb_strlen($title) > 255) {
+            return Base::retError('任务标题最多只能设置255个字!');
+        }
+        //
+        $level = max(1, min(4, intval(Request::input('level'))));
+        if (empty($projectid)) {
+            $inorder = 0;
+        } else {
+            $inorder = intval(DB::table('project_task')->where('projectid', $projectid)->orderBy('inorder', $insertbottom ? 'asc' : 'desc')->value('inorder')) + ($insertbottom ? -1 : 1);
+        }
+        $userorder = intval(DB::table('project_task')->where('username', $user['username'])->where('level', $level)->orderByDesc('userorder')->value('userorder')) + 1;
+        //
+        $inArray = [
+            'projectid' => $projectid,
+            'labelid' => $labelid,
+            'createuser' => $user['username'],
+            'username' => $username,
+            'title' => $title,
+            'level' => $level,
+            'inorder' => $inorder,
+            'userorder' => $userorder,
+            'indate' => Base::time(),
+            'startdate' => Base::time(),
+            'follower' => Base::array2string([]),
+        ];
+        return DB::transaction(function () use ($inArray) {
+            $taskid = DB::table('project_task')->insertGetId($inArray);
+            if (empty($taskid)) {
+                return Base::retError('系统繁忙,请稍后再试!');
+            }
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $inArray['projectid'],
+                'taskid' => $taskid,
+                'username' => $inArray['createuser'],
+                'detail' => '添加任务',
+                'indate' => Base::time(),
+                'other' => Base::array2string([
+                    'type' => 'task',
+                    'id' => $taskid,
+                    'title' => $inArray['title'],
+                ])
+            ]);
+            Project::updateNum($inArray['projectid']);
+            //
+            $task = Base::DBC2A(DB::table('project_task')->where('id', $taskid)->first());
+            $task['persons'] = Project::taskPersons($task);
+            $task['overdue'] = Project::taskIsOverdue($task);
+            $task['subtask'] = Base::DBC2A(DB::table('project_sub_task')->where(['taskid'=>$taskid, 'delete' => 0])->orderByDesc('userorder')->get());
+            $task['follower'] = Base::string2array($task['follower']);
+            $task = array_merge($task, Users::username2basic($task['username']));
+            return Base::retSuccess('添加成功!', $task);
+        });
+    }
+
+    /**
+     * {post} 项目任务-修改
+     *
+     * @apiParam {Number} taskid            任务ID
+     * @apiParam {String} act               修改字段|操作类型
+     * - title: 标题
+     * - desc: 描述
+     * - level: 优先级
+     * - username: 负责人
+     * - plannedtime: 设置计划时间
+     * - unplannedtime: 取消计划时间
+     * - complete: 标记完成
+     * - unfinished: 标记未完成
+     * - archived: 归档
+     * - unarchived: 取消归档
+     * - delete: 删除任务
+     * - comment: 评论
+     * - attention: 添加关注
+     * - subtask: 修改子任务
+     * @apiParam {String} [content]         内容数据
+     * @apiParam {String} [mode]            【act=attention】时可选参数,clean表示不在提交的列表中则删除
+     *
+     * @throws \Throwable
+     */
+    public function task__edit()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $act = trim(Base::getPostValue('act'));
+        $taskid = intval(Base::getPostValue('taskid'));
+        $type = trim(Base::getPostValue('type'));
+        $task = Base::DBC2A(DB::table('project_task')
+            ->where([
+                ['delete', '=', 0],
+                ['id', '=', $taskid],
+            ])
+            ->first());
+        if (empty($task)) {
+            return Base::retError('任务不存在!');
+        }
+        if ($task['projectid'] > 0) {
+            if (!Project::isPersons($task, $user['username'])) {
+                $inRes = Project::inThe($task['projectid'], $user['username']);
+                if (Base::isError($inRes)) {
+                    return $inRes;
+                }
+            }
+            if (!in_array($act, ['comment', 'attention'])) {
+                $checkRole = Project::role('edit_role', $task['projectid'], $task['id']);
+                if (Base::isError($checkRole)) {
+                    return $checkRole;
+                }
+                switch ($act) {
+                    case 'complete':
+                    case 'unfinished':
+                        $checkRole = Project::role('complete_role', $task['projectid'], $task['id']);
+                        if (Base::isError($checkRole)) {
+                            return $checkRole;
+                        }
+                        break;
+                    case 'archived':
+                    case 'unarchived':
+                        $checkRole = Project::role('archived_role', $task['projectid'], $task['id']);
+                        if (Base::isError($checkRole)) {
+                            return $checkRole;
+                        }
+                        break;
+                    case 'delete':
+                        $checkRole = Project::role('del_role', $task['projectid'], $task['id']);
+                        if (Base::isError($checkRole)) {
+                            return $checkRole;
+                        }
+                        break;
+                }
+            }
+        } else {
+            if (!Project::isPersons($task, $user['username'])) {
+                return Base::retError('此操作只允许任务负责人!');
+            }
+        }
+        //
+        $content = Base::newTrim(Base::getPostValue('content'));
+        $task['subtask'] = Base::DBC2A(DB::table('project_sub_task')->where(['taskid'=>$taskid, 'delete' => 0])->orderByDesc('userorder')->get());
+        $message = "";
+        $upArray = [];
+        $logArray = [];
+        switch ($act) {
+            /**
+             * 修改标题
+             */
+            case 'title': {
+                if ($content == $task['title']) {
+                    return Base::retError('标题未做改变!');
+                }
+                $upArray['title'] = $content;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '修改任务标题',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $content,
+                        'old_title' => $task['title'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 修改描述
+             */
+            case 'desc': {
+                preg_match_all("/<img\s*src=\"data:image\/(png|jpg|jpeg);base64,(.*?)\"/s", $content, $matchs);
+                foreach ($matchs[2] as $key => $text) {
+                    $p = "uploads/projects/" . ($task['projectid'] ?: Users::token2userid()) . "/";
+                    Base::makeDir(public_path($p));
+                    $p.= md5($text) . "." . $matchs[1][$key];
+                    $r = file_put_contents(public_path($p), base64_decode($text));
+                    if ($r) {
+                        $content = str_replace($matchs[0][$key], '<img src="' . Base::fillUrl($p) . '"', $content);
+                    }
+                }
+                Base::DBUPIN('project_content', [
+                    'taskid' => $task['id'],
+                ], [
+                    'content' => $content,
+                ], [
+                    'projectid' => $task['projectid'],
+                    'content' => $content,
+                    'indate' => Base::time()
+                ]);
+                $upArray['desc'] = $content ? Base::time() : '';
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '修改任务描述',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                        'old_desc' => $task['desc'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 调整任务等级
+             */
+            case 'level': {
+                $content = intval($content);
+                if ($content == $task['level']) {
+                    return Base::retError('优先级未做改变!');
+                }
+                if ($content > 4 || $content < 1) {
+                    return Base::retError('优先级参数错误!');
+                }
+                $upArray['level'] = $content;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '调整任务等级为【P' . $content . '】',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                        'old_level' => $task['level'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 修改任务负责人
+             */
+            case 'username': {
+                if ($content == $task['username']) {
+                    return Base::retError('负责人未做改变!');
+                }
+                if ($task['projectid'] > 0) {
+                    $inRes = Project::inThe($task['projectid'], $content);
+                    if (Base::isError($inRes)) {
+                        return Base::retError(['%不在成员列表内!', $content]);
+                    }
+                }
+                $upArray['username'] = $content;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '修改负责人',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                        'old_username' => $task['username'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 修改计划时间
+             */
+            case 'plannedtime': {
+                list($startdate, $enddate) = explode(",", $content);
+                $startdate = strtotime($startdate);
+                $enddate = strtotime($enddate);
+                if (!$startdate || !$enddate) {
+                    return Base::retError('计划时间参数错误!');
+                }
+                if ($startdate == $task['startdate'] && $enddate == $task['enddate']) {
+                    return Base::retError('与原计划时间一致!');
+                }
+                if ($startdate == $enddate) {
+                    return Base::retError('开始时间与结束时间一致!');
+                }
+                $upArray['startdate'] = $startdate;
+                $upArray['enddate'] = $enddate;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '设置计划时间',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                        'old_startdate' => $task['startdate'],
+                        'old_enddate' => $task['enddate'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 取消计划时间
+             */
+            case 'unplannedtime': {
+                $startdate = 0;
+                $enddate = 0;
+                if ($startdate == $task['startdate'] && $enddate == $task['enddate']) {
+                    return Base::retError('与原计划时间一致!');
+                }
+                $upArray['startdate'] = $startdate;
+                $upArray['enddate'] = $enddate;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '取消计划时间',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                        'old_startdate' => $task['startdate'],
+                        'old_enddate' => $task['enddate'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 标记完成
+             */
+            case 'complete': {
+                if ($task['complete'] == 1) {
+                    return Base::retError('任务已标记完成,请勿重复操作!');
+                }
+                $upArray['complete'] = 1;
+                $upArray['completedate'] = Base::time();
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '标记已完成',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 标记未完成
+             */
+            case 'unfinished': {
+                if ($task['complete'] == 0) {
+                    return Base::retError('任务未完成,无法标记未完成!');
+                }
+                $upArray['complete'] = 0;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '标记未完成',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 归档
+             */
+            case 'archived': {
+                if ($task['archived'] == 1) {
+                    return Base::retError('任务已经归档,请勿重复操作!');
+                }
+                $upArray['archived'] = 1;
+                $upArray['archiveddate'] = Base::time();
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '任务归档',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 取消归档
+             */
+            case 'unarchived': {
+                if ($task['archived'] == 0) {
+                    return Base::retError('任务未归档,无法取消归档操作!');
+                }
+                $upArray['archived'] = 0;
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '取消归档',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                    ])
+                ];
+                break;
+            }
+
+            /**
+             * 删除任务
+             */
+            case 'delete': {
+                if ($task['delete'] == 1) {
+                    return Base::retError('任务已删除,请勿重复操作!');
+                }
+                $upArray['delete'] = 1;
+                $upArray['deletedate'] = Base::time();
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => '删除任务',
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                    ])
+                ];
+                $message = "删除成功!";
+                break;
+            }
+
+            /**
+             * 评论任务
+             */
+            case 'comment': {
+                if (mb_strlen($content) < 2) {
+                    return Base::retError('评论内容至少2个字!');
+                }
+                $logArray[] = [
+                    'type' => '评论',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => $content,
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                    ])
+                ];
+                $message = "评论成功!";
+                break;
+            }
+
+            /**
+             * 添加关注
+             */
+            case 'attention': {
+                $mode = trim(Base::getPostValue('mode'));
+                $userArray  = explode(",", $content);
+                DB::transaction(function () use ($mode, $user, $task, $userArray) {
+                    foreach ($userArray AS $uname) {
+                        $uid = Users::username2id($uname);
+                        if (empty($uid)) {
+                            continue;
+                        }
+                        $row = Base::DBC2A(DB::table('project_users')->where([
+                            'type' => '关注',
+                            'taskid' => $task['id'],
+                            'username' => $uname,
+                        ])->lockForUpdate()->first());
+                        if (empty($row)) {
+                            DB::table('project_users')->insert([
+                                'type' => '关注',
+                                'projectid' => $task['projectid'],
+                                'taskid' => $task['id'],
+                                'isowner' => $task['username'] == $uname ? 1 : 0,
+                                'username' => $uname,
+                                'indate' => Base::time()
+                            ]);
+                            DB::table('project_log')->insert([
+                                'type' => '日志',
+                                'projectid' => $task['projectid'],
+                                'taskid' => $task['id'],
+                                'username' => $uname,
+                                'detail' => $uname == $user['username'] ? '关注任务' : '加入关注',
+                                'indate' => Base::time(),
+                                'other' => Base::array2string([
+                                    'type' => 'task',
+                                    'id' => $task['id'],
+                                    'title' => $task['title'],
+                                    'operator' => $user['username'],
+                                    'action' => 'attention',
+                                ])
+                            ]);
+                        }
+                    }
+                    if ($mode == 'clean') {
+                        $tempLists = Base::DBC2A(DB::table('project_users')
+                            ->select(['id', 'username'])
+                            ->where([
+                                'type' => '关注',
+                                'taskid' => $task['id'],
+                            ])
+                            ->whereNotIn('username', $userArray)
+                            ->lockForUpdate()
+                            ->get());
+                        foreach ($tempLists AS $tempItem) {
+                            if (DB::table('project_users')->where('id', $tempItem['id'])->delete()) {
+                                $uname = $tempItem['username'];
+                                DB::table('project_log')->insert([
+                                    'type' => '日志',
+                                    'projectid' => $task['projectid'],
+                                    'taskid' => $task['id'],
+                                    'username' => $uname,
+                                    'detail' => $uname == $user['username'] ? '取消关注' : '移出关注',
+                                    'indate' => Base::time(),
+                                    'other' => Base::array2string([
+                                        'type' => 'task',
+                                        'id' => $task['id'],
+                                        'title' => $task['title'],
+                                        'operator' => $user['username'],
+                                        'action' => 'unattention',
+                                    ])
+                                ]);
+                            }
+                        }
+                    }
+                });
+                $tempRow = Base::DBC2A(DB::table('project_users')->select(['username'])->where([ 'type' => '关注', 'taskid' => $task['id'] ])->get()->pluck('username'));
+                $upArray['follower'] = Base::array2string($tempRow);
+                $message = "保存成功!";
+                break;
+            }
+
+            /**
+             * 取消关注
+             */
+            case 'unattention': {
+                $userArray  = explode(",", $content);
+                DB::transaction(function () use ($user, $task, $userArray) {
+                    foreach ($userArray AS $uname) {
+                        if (DB::table('project_users')->where([
+                            'type' => '关注',
+                            'taskid' => $task['id'],
+                            'username' => $uname,
+                        ])->delete()) {
+                            DB::table('project_log')->insert([
+                                'type' => '日志',
+                                'projectid' => $task['projectid'],
+                                'taskid' => $task['id'],
+                                'username' => $uname,
+                                'detail' => $uname == $user['username'] ? '取消关注' : '移出关注',
+                                'indate' => Base::time(),
+                                'other' => Base::array2string([
+                                    'type' => 'task',
+                                    'id' => $task['id'],
+                                    'title' => $task['title'],
+                                    'operator' => $user['username'],
+                                    'action' => 'unattention',
+                                ])
+                            ]);
+                        }
+                    }
+                });
+                $tempRow = Base::DBC2A(DB::table('project_users')->select(['username'])->where([ 'type' => '关注', 'taskid' => $task['id'] ])->get()->pluck('username'));
+                $upArray['follower'] = Base::array2string($tempRow);
+                $message = "保存成功!";
+                break;
+            }
+
+            /**
+             * 修改子任务
+             */
+            case 'subtask': {
+                if (!is_array($content)) {
+                    $content = [];
+                }
+                $subNames = [];
+                foreach ($content AS $tmp) {
+                    if ($tmp['uname'] && !in_array($tmp['uname'], $subNames)) {
+                        $subNames[] = $tmp['uname'];
+                    }
+                }
+
+                if ($subNames) {
+                    DB::transaction(function() use ($task, $subNames) {
+                        foreach ($subNames AS $uname) {
+                            $row = Base::DBC2A(DB::table('project_users')->where([
+                                'type' => '负责人',
+                                'taskid' => $task['id'],
+                                'username' => $uname,
+                            ])->lockForUpdate()->first());
+                            if (empty($row)) {
+                                DB::table('project_users')->insert([
+                                    'type' => '负责人',
+                                    'projectid' => $task['projectid'],
+                                    'taskid' => $task['id'],
+                                    'isowner' => $task['username'] == $uname ? 1 : 0,
+                                    'username' => $uname,
+                                    'indate' => Base::time()
+                                ]);
+                            }
+                        }
+                        DB::table('project_users')->where([
+                            'type' => '负责人',
+                            'taskid' => $task['id'],
+                        ])->whereNotIn('username', $subNames)->delete();
+                    });
+                } else {
+                    DB::table('project_users')->where([
+                        'type' => '负责人',
+                        'taskid' => $task['id'],
+                    ])->delete();
+                }
+
+                //zmw修改
+                switch ($type){
+                    case 'all':
+                        //批量添加子任务
+                        $subtask_data = [];
+                        foreach ($content as $k => $v){
+                            $item = [
+                                'taskid' => $task['id'],
+                                'uname' => '',
+                                'indate' => Base::time(),
+                                'status' => 'unfinished',
+                                'detail' => $v['detail']
+                            ];
+                            array_push($subtask_data,$item);
+                        }
+                        $content = Base::array2string($subtask_data);
+                        DB::transaction(function() use ($subtask_data) {
+                            DB::table('project_sub_task')->insert($subtask_data);
+                        });
+                        $detail = '批量添加子任务';
+                        $subtype = 'add';
+                        $old_subtask = '';
+                        break;
+                    case 'detail':
+                        if(array_key_exists('id',$content[0])){
+                            //编辑
+                            $row = Base::DBC2A(DB::table('project_sub_task')->where([
+                                'taskid' => $task['id'],
+                                'id' => $content[0]['id'],
+                                'delete' => 0
+                            ])->lockForUpdate()->first());
+                            if ($row['detail'] == $content[0]['detail']) {
+                                return Base::retError('子任务未做改变!');
+                            }
+                            DB::table('project_sub_task')->where('id', $content[0]['id'])->where(['taskid'=>$task['id'], 'delete' => 0])->update(['detail' => $content[0]['detail']]);
+                            $detail = '修改子任务';
+                            $subtype = 'modify';
+                            $old_subtask = Base::array2string($row);
+                        }else{
+                            //新增
+                            $item = [
+                                'taskid' => $task['id'],
+                                'uname' => '',
+                                'indate' => Base::time(),
+                                'status' => 'unfinished',
+                                'detail' => $content[0]['detail']
+                            ];
+                            DB::table('project_sub_task')->insert($item);
+                            $detail = '增加子任务';
+                            $subtype = 'add';
+                            $old_subtask = '';
+                        }
+                        break;
+                    case 'status':
+                        if(array_key_exists('id',$content[0])){
+                            $row = Base::DBC2A(DB::table('project_sub_task')->where([
+                                'taskid' => $task['id'],
+                                'id' => $content[0]['id'],
+                                'delete' => 0
+                            ])->lockForUpdate()->first());
+                            //编辑
+                            if($content[0]['status'] == 'complete'){
+                                $time = time();
+                            }else{
+                                $time = 0;
+                            }
+                            DB::table('project_sub_task')->where('id', $content[0]['id'])->where(['taskid'=>$task['id'], 'delete' => 0])->update(['status' => $content[0]['status'], 'completedate' => $time]);
+                            $detail = '修改子任务';
+                            $subtype = 'modify';
+                            $old_subtask = Base::array2string($row);
+                        }else{
+                            //新增
+                            $item = [
+                                'taskid' => $task['id'],
+                                'uname' => '',
+                                'indate' => Base::time(),
+                                'status' => $content[0]['status'],
+                                'detail' => ''
+                            ];
+                            DB::table('project_sub_task')->insert($item);
+                            $detail = '增加子任务';
+                            $subtype = 'add';
+                            $old_subtask = '';
+                        }
+                        break;
+                    case 'uname':
+                        if(array_key_exists('id',$content[0])){
+                            $row = Base::DBC2A(DB::table('project_sub_task')->where([
+                                'taskid' => $task['id'],
+                                'id' => $content[0]['id'],
+                                'delete' => 0
+                            ])->lockForUpdate()->first());
+                            //编辑
+                            DB::table('project_sub_task')->where('id', $content[0]['id'])->where(['taskid'=>$task['id'], 'delete' => 0])->update(['uname' => $content[0]['uname']]);
+                            $detail = '修改子任务负责人';
+                            $subtype = 'modify';
+                            $old_subtask = Base::array2string($row);
+                        }else{
+                            //新增
+                            $item = [
+                                'taskid' => $task['id'],
+                                'uname' => $content[0]['uname'],
+                                'indate' => Base::time(),
+                                'status' => 'unfinished',
+                                'detail' => ''
+                            ];
+                            DB::table('project_sub_task')->insert($item);
+                            $detail = '增加子任务';
+                            $subtype = 'add';
+                            $old_subtask = '';
+                        }
+                        break;
+                    case 'delete':
+                        $row = Base::DBC2A(DB::table('project_sub_task')->where([
+                            'taskid' => $task['id'],
+                            'id' => $content[0]['id'],
+                            'delete' => 0
+                        ])->lockForUpdate()->first());
+                        DB::table('project_sub_task')->where('id', $content[0]['id'])->where(['taskid'=>$task['id'], 'delete' => 0])->update(['delete' => 1, 'deletedate' => time()]);
+                        $detail = '删除子任务';
+                        $subtype = 'del';
+                        $old_subtask = Base::array2string($row);
+                        break;
+                    default:
+                        $content = '';
+                        $detail = '修改子任务';
+                        $subtype = 'modify';
+                        $old_subtask = '';
+                        break;
+                }
+
+                $task['subtask'] = Base::DBC2A(DB::table('project_sub_task')->where(['taskid'=>$task['id'], 'delete' => 0])->orderByDesc('userorder')->get());
+
+                $logArray[] = [
+                    'type' => '日志',
+                    'projectid' => $task['projectid'],
+                    'taskid' => $task['id'],
+                    'username' => $user['username'],
+                    'detail' => $detail,
+                    'indate' => Base::time(),
+                    'other' => Base::array2string([
+                        'type' => 'task',
+                        'subtype' => $subtype,
+                        'id' => $task['id'],
+                        'title' => $task['title'],
+                        'subtask' => $content,
+                        'old_subtask' => $old_subtask,
+                    ])
+                ];
+                break;
+            }
+
+            default: {
+                return Base::retError('参数错误!');
+            }
+        }
+        //
+        if ($upArray) {
+            DB::table('project_task')->where('id', $taskid)->update($upArray);
+        }
+        if ($logArray) {
+            DB::table('project_log')->insert($logArray);
+        }
+        //
+        if (in_array($act, ['complete', 'unfinished', 'delete'])) {
+            Project::updateNum($task['projectid']);
+        }
+        //
+        $task = array_merge($task, $upArray);
+        $task['persons'] = Project::taskPersons($task);
+        $task['overdue'] = Project::taskIsOverdue($task);
+        //$task['subtask'] = Base::string2array($task['subtask']);
+        $task['follower'] = Base::string2array($task['follower']);
+        $task['projectTitle'] = $task['projectid'] > 0 ? DB::table('project_lists')->where('id', $task['projectid'])->value('title') : '';
+        $task['plantime'] = ($task['startdate'] > 0 ? date("Y-m-d",$task['startdate']) : "未设置") . "-" . ($task['enddate'] > 0 ? date("Y-m-d H:i:s",$task['enddate']) : "未设置");
+        $task = array_merge($task, Users::username2basic($task['username']));
+        return Base::retSuccess($message ?: '修改成功!', $task);
+    }
+
+    /**
+     * 项目任务-待推送日志
+     *
+     * @apiParam {Number} taskid                任务ID
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     * @throws \Throwable
+     */
+    public function task__pushlog()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        return DB::transaction(function () {
+            $taskid = intval(Request::input('taskid'));
+            $task = Base::DBC2A(DB::table('project_task')
+                ->select(['pushlid', 'follower', 'username'])
+                ->where([
+                    ['delete', '=', 0],
+                    ['id', '=', $taskid],
+                ])
+                ->lockForUpdate()
+                ->first());
+            if (empty($task)) {
+                return Base::retError('任务不存在!');
+            }
+            $task['follower'] = Base::string2array($task['follower']);
+            $task['follower'][] = $task['username'];
+            //
+            $pushlid = $task['pushlid'];
+            $lists = DB::table('project_log')
+                ->select(['id', 'username', 'indate', 'detail', 'other'])
+                ->where([
+                    ['id', '>', $pushlid],
+                    ['taskid', '=', $taskid],
+                    ['indate', '>', Base::time() - 60]
+                ])
+                ->orderBy('id')->paginate(Base::getPaginate(100, 20));
+            $lists = Base::getPageList($lists, false);
+            if (count($lists['lists']) == 0) {
+                return Base::retError('no lists');
+            }
+            $array = [];
+            foreach ($lists['lists'] AS $key => $item) {
+                $item = array_merge($item, Users::username2basic($item['username']));
+                $item['other'] = Base::string2array($item['other'], ['type' => '']);
+                if (!in_array($item['other']['action'], ['attention', 'unattention'])) {
+                    $array[] = $item;
+                }
+                $pushlid = $item['id'];
+                if($item['detail'] == '修改负责人'){
+                    $ding_followers = $task['follower'];
+                    $ding_followers[] = $item['old_username'];
+                    $users = DB::table('users')->whereIn("username",$ding_followers)->pluck("userid")->toArray();
+                    $json = [
+                        'userid_list' => implode(',',$users),
+                        'msg' => [
+                            'msgtype' => 'oa',
+                            'oa' => [
+                                'message_url' => 'http://project.jinjianghc.com/ding?corpId=$CORPID$',
+                                'head' => [
+                                    'bgcolor' => 'FFBBBBBB',
+                                    'text' => '头部标题'
+                                ],
+                                'body' => [
+                                    'title' => '任务负责人变更通知',
+                                    'content' => '任务:'.$task['title'] . ',更改负责人为:' . $item['nickname'] .'。请知悉!',
+                                    'author' => '来自系统消息'
+                                ]
+                            ]
+                        ],
+                    ];
+                    AccessToken::getToken();
+                    Notification::send($json);
+                }
+                if($item['detail'] == '修改子任务负责人'){
+                    $ding_followers = $task['follower'];
+                    if(!empty($item['other']['old_subtask']['uname'])){
+                        $ding_followers[] = $item['other']['old_subtask']['uname'];
+                    }
+                    $sub_own = array_merge($item, Users::username2basic($item['other']['subtask'][0]['uname']));
+                    $users = DB::table('users')->whereIn("username",$ding_followers)->pluck("userid")->toArray();
+                    $json = [
+                        'userid_list' => implode(',',$users),
+                        'msg' => [
+                            'msgtype' => 'oa',
+                            'oa' => [
+                                'message_url' => 'http://project.jinjianghc.com/ding?corpId=$CORPID$',
+                                'head' => [
+                                    'bgcolor' => 'FFBBBBBB',
+                                    'text' => '头部标题'
+                                ],
+                                'body' => [
+                                    'title' => '任务负责人变更通知',
+                                    'content' => '任务:'.$item['other']['subtask'][0]['detail'] . ',更改负责人为:' . $sub_own['nickname'] .'。请知悉!',
+                                    'author' => '来自系统消息'
+                                ]
+                            ]
+                        ],
+                    ];
+                    //\Log::channel("stderr")->info(print_r($item,true));
+                    AccessToken::getToken();
+                    Notification::send($json);
+                }
+            }
+            $lists['lists'] = $array;
+            if ($pushlid != $task['pushlid']) {
+                DB::table('project_task')->where('id', $taskid)->update([
+                    'pushlid' => $pushlid
+                ]);
+            }
+
+
+            return Base::retSuccess('success', array_merge($lists, $task));
+        });
+    }
+
+    /**
+     * 项目文件-列表
+     *
+     * @apiParam {Number} [projectid]           项目ID
+     * @apiParam {Number} [taskid]              任务ID(如果项目ID为空时此参必须赋值且任务必须是自己负责人或在任务所在的项目里)
+     * @apiParam {String} [name]                文件名称
+     * @apiParam {String} [username]            上传者用户名
+     * @apiParam {Object} [sorts]               排序方式,格式:{key:'', order:''}
+     * - key: name|size|username|indate
+     * - order: asc|desc
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     */
+    public function files__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $taskid = intval(Request::input('taskid'));
+        if ($taskid > 0) {
+            $projectid = intval(DB::table('project_task')->select(['projectid'])->where([ 'id' => $taskid])->value('projectid'));
+        } else {
+            $projectid = intval(Request::input('projectid'));
+        }
+        if ($projectid > 0) {
+            if(!in_array('admin',$user['identity'])){
+                $inRes = Project::inThe($projectid, $user['username']);
+                if (Base::isError($inRes)) {
+                    return $inRes;
+                }
+            }
+
+        }
+        //
+        $orderBy = '`id` DESC';
+        $sorts = Base::json2array(Request::input('sorts'));
+        if (in_array($sorts['order'], ['asc', 'desc'])) {
+            switch ($sorts['key']) {
+                case 'name':
+                case 'size':
+                case 'download':
+                case 'username':
+                case 'indate':
+                    $orderBy = '`' . $sorts['key'] . '` ' . $sorts['order'] . ',`id` DESC';
+                    break;
+            }
+        }
+        //
+        $whereArray = [];
+        if ($projectid > 0) {
+            $whereArray[] = ['projectid', '=', $projectid];
+            if ($taskid > 0) {
+                $whereArray[] = ['taskid', '=', $taskid];
+            }
+        } else {
+            if ($taskid <= 0) {
+                return Base::retError('参数错误!');
+            }
+            $tmpLists = Project::taskSomeUsers($taskid);
+            if (!in_array($user['username'], $tmpLists)) {
+                return Base::retError('未能找到此任务或无法管理此任务!');
+            }
+            $whereArray[] = ['taskid', '=', $taskid];
+        }
+        $whereArray[] = ['delete', '=', 0];
+        if (intval(Request::input('taskid')) > 0) {
+            $whereArray[] = ['taskid', '=', intval(Request::input('taskid'))];
+        }
+        if (trim(Request::input('name'))) {
+            $whereArray[] = ['name', 'like', '%' . trim(Request::input('name')) . '%'];
+        }
+        if (trim(Request::input('username'))) {
+            $whereArray[] = ['username', '=', trim(Request::input('username'))];
+        }
+        //
+        $lists = DB::table('project_files')
+            ->where($whereArray)
+            ->orderByRaw($orderBy)->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的文件', $lists);
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $lists['lists'][$key]['path'] = Base::fillUrl($item['path']);
+            $lists['lists'][$key]['thumb'] = Base::fillUrl($item['thumb']);
+            $lists['lists'][$key]['yetdown'] = intval(Session::get('filesDownload:' . $item['id']));
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 项目文件-上传
+     *
+     * @apiParam {Number} [projectid]           get-项目ID
+     * @apiParam {Number} [taskid]              get-任务ID(如果项目ID为空时此参必须赋值且任务必须是自己负责人)
+     * @apiParam {String} [filename]            post-文件名称
+     * @apiParam {String} [image64]             post-base64图片(二选一)
+     * @apiParam {File} [files]                 post-文件对象(二选一)
+     */
+    public function files__upload()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = intval(Request::input('projectid'));
+        $taskid = intval(Request::input('taskid'));
+        if ($projectid > 0) {
+            if(!in_array('admin',$user['identity'])){
+                $inRes = Project::inThe($projectid, $user['username']);
+                if (Base::isError($inRes)) {
+                    return $inRes;
+                }
+            }
+        } else {
+            if ($taskid <= 0) {
+                return Base::retError('参数错误!');
+            }
+            $tmpLists = Project::taskSomeUsers($taskid);
+            if (!in_array($user['username'], $tmpLists)) {
+                return Base::retError('未能找到此任务或无法管理此任务!');
+            }
+            $projectid = DB::table('project_task')->where('id', $taskid)->value('projectid');
+        }
+        //
+        $path = "uploads/projects/" . ($projectid ?: Users::token2userid()) . "/";
+        $image64 = trim(Base::getPostValue('image64'));
+        $fileName = trim(Base::getPostValue('filename'));
+        if ($image64) {
+            $data = Base::image64save([
+                "image64" => $image64,
+                "path" => $path,
+                "fileName" => $fileName,
+            ]);
+        } else {
+            $data = Base::upload([
+                "file" => Request::file('files'),
+                "type" => 'file',
+                "path" => $path,
+                "fileName" => $fileName,
+            ]);
+        }
+        //
+        if (Base::isError($data)) {
+            return Base::retError($data['msg']);
+        } else {
+            $fileData = $data['data'];
+            $fileData['thumb'] = $fileData['thumb'] ?: 'images/files/file.png';
+            switch ($fileData['ext']) {
+                case "docx":
+                    $fileData['thumb'] = 'images/files/doc.png';
+                    break;
+                case "xlsx":
+                    $fileData['thumb'] = 'images/files/xls.png';
+                    break;
+                case "pptx":
+                    $fileData['thumb'] = 'images/files/ppt.png';
+                    break;
+                case "ai":
+                case "avi":
+                case "bmp":
+                case "cdr":
+                case "doc":
+                case "eps":
+                case "gif":
+                case "mov":
+                case "mp3":
+                case "mp4":
+                case "pdf":
+                case "ppt":
+                case "pr":
+                case "psd":
+                case "rar":
+                case "svg":
+                case "tif":
+                case "txt":
+                case "xls":
+                case "zip":
+                    $fileData['thumb'] = 'images/files/' . $fileData['ext'] . '.png';
+                    break;
+            }
+            $array = [
+                'projectid' => $projectid,
+                'taskid' => $taskid,
+                'name' => $fileData['name'],
+                'size' => $fileData['size'] * 1024,
+                'ext' => $fileData['ext'],
+                'path' => $fileData['path'],
+                'thumb' => $fileData['thumb'],
+                'username' => $user['username'],
+                'indate' => Base::time(),
+            ];
+            $id = DB::table('project_files')->insertGetId($array);
+            $array['id'] = $id;
+            $array['path'] = Base::fillUrl($array['path']);
+            $array['thumb'] = Base::fillUrl($array['thumb']);
+            $array['download'] = 0;
+            $array['yetdown'] = 0;
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $projectid,
+                'taskid' => $taskid,
+                'username' => $user['username'],
+                'detail' => '上传文件',
+                'indate' => Base::time(),
+                'other' => Base::array2string([
+                    'type' => 'file',
+                    'id' => $id,
+                    'name' => $fileData['name'],
+                ])
+            ]);
+            if ($taskid > 0) {
+                DB::table('project_task')->where('id', $taskid)->increment('filenum');
+            }
+            return Base::retSuccess('success', $array);
+        }
+    }
+
+    /**
+     * 项目文件-下载
+     *
+     * @apiParam {Number} fileid                文件ID
+     */
+    public function files__download()
+    {
+        $fileDetail = Base::DBC2A(DB::table('project_files')->where('id', intval(Request::input('fileid')))->where('delete', 0)->first());
+        if (empty($fileDetail)) {
+            abort(404, '文件不存在或已被删除!');
+        }
+        $filePath = public_path($fileDetail['path']);
+        if (!file_exists($filePath)) {
+            abort(404, '文件不存在或已被删除。');
+        }
+        if (intval(Session::get('filesDownload:' . $fileDetail['id'])) !== 1) {
+            Session::put('filesDownload:' . $fileDetail['id'], 1);
+            DB::table('project_files')->where('id', $fileDetail['id'])->increment('download');
+        }
+        return response()->download($filePath, $fileDetail['name']);
+    }
+
+    /**
+     * 项目文件-重命名
+     *
+     * @apiParam {Number} fileid                文件ID
+     * @apiParam {String} name                  新文件名称
+     */
+    public function files__rename()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $fileDetail = Base::DBC2A(DB::table('project_files')->where('id', intval(Request::input('fileid')))->where('delete', 0)->first());
+        if (empty($fileDetail)) {
+            return Base::retError('文件不存在或已被删除!');
+        }
+        if ($fileDetail['username'] != $user['username']) {
+            $inRes = Project::inThe($fileDetail['projectid'], $user['username'], true);
+            if (Base::isError($inRes)) {
+                return Base::retError('此操作仅支持管理员或上传者!');
+            }
+        }
+        //
+        $name = Base::rightDelete(trim(Request::input('name')), '.' . $fileDetail['ext']);
+        if (empty($name)) {
+            return Base::retError('文件名称不能为空!');
+        } elseif (mb_strlen($name) > 32) {
+            return Base::retError('文件名称最多只能设置32个字!');
+        }
+        //
+        $name .= '.' . $fileDetail['ext'];
+        if (DB::table('project_files')->where('id', $fileDetail['id'])->update([ 'name' => $name ])) {
+            DB::table('project_log')->insert([
+                'type' => '日志',
+                'projectid' => $fileDetail['projectid'],
+                'taskid' => $fileDetail['taskid'],
+                'username' => $user['username'],
+                'detail' => '文件【' . $fileDetail['name'] . '】重命名',
+                'indate' => Base::time(),
+                'other' => Base::array2string([
+                    'type' => 'file',
+                    'id' => $fileDetail['id'],
+                    'name' => $name,
+                ])
+            ]);
+        }
+        //
+        return Base::retSuccess('修改成功!', [
+            'name' => $name,
+        ]);
+    }
+
+    /**
+     * 项目文件-删除
+     *
+     * @apiParam {Number} fileid                文件ID
+     */
+    public function files__delete()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $fileDetail = Base::DBC2A(DB::table('project_files')->where('id', intval(Request::input('fileid')))->where('delete', 0)->first());
+        if (empty($fileDetail)) {
+            return Base::retError('文件不存在或已被删除!');
+        }
+        if ($fileDetail['username'] != $user['username']) {
+            $inRes = Project::inThe($fileDetail['projectid'], $user['username'], true);
+            if (Base::isError($inRes)) {
+                return Base::retError('此操作仅支持管理员或上传者!');
+            }
+        }
+        //
+        DB::table('project_files')->where('id', $fileDetail['id'])->update([
+            'delete' => 1,
+            'deletedate' => Base::time()
+        ]);
+        DB::table('project_log')->insert([
+            'type' => '日志',
+            'projectid' => $fileDetail['projectid'],
+            'taskid' => $fileDetail['taskid'],
+            'username' => $user['username'],
+            'detail' => '删除文件',
+            'indate' => Base::time(),
+            'other' => Base::array2string([
+                'type' => 'file',
+                'id' => $fileDetail['id'],
+                'name' => $fileDetail['name'],
+            ])
+        ]);
+        if ($fileDetail['taskid'] > 0) {
+            DB::table('project_task')->where('id', $fileDetail['taskid'])->decrement('filenum');
+        }
+        //
+        return Base::retSuccess('删除成功!');
+    }
+
+    /**
+     * 项目动态-列表
+     *
+     * @apiParam {Number} [projectid]           项目ID
+     * @apiParam {Number} [taskid]              任务ID(如果项目ID为空时此参必须赋值且任务必须是自己负责人)
+     * @apiParam {String} [type]                类型
+     * - 全部: 日志+评论(默认)
+     * - 日志
+     * - 评论
+     * @apiParam {String} [username]            用户名
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     */
+    public function log__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $projectid = intval(Request::input('projectid'));
+        if ($projectid > 0) {
+            if(!in_array('admin',$user['identity'])){
+                $inRes = Project::inThe($projectid, $user['username']);
+                if (Base::isError($inRes)) {
+                    return $inRes;
+                }
+            }
+        }
+        //
+        $taskid = intval(Request::input('taskid'));
+        $whereArray = [];
+        $whereFunc = null;
+        if ($projectid > 0) {
+            $whereArray[] = ['projectid', '=', $projectid];
+            if ($taskid > 0) {
+                $whereArray[] = ['taskid', '=', $taskid];
+            }
+        } else {
+            if ($taskid < 0) {
+                return Base::retError('参数错误!');
+            }
+            $tmpLists = Project::taskSomeUsers($taskid);
+            if (!in_array($user['username'], $tmpLists)) {
+                return Base::retError('未能找到此任务或无法管理此任务!');
+            }
+            $whereArray[] = ['taskid', '=', $taskid];
+        }
+        if (trim(Request::input('username'))) {
+            $whereArray[] = ['username', '=', trim(Request::input('username'))];
+        }
+        switch (trim(Request::input('type'))) {
+            case '日志': {
+                $whereArray[] = ['type', '=', '日志'];
+                break;
+            }
+            case '评论': {
+                $whereArray[] = ['type', '=', '评论'];
+                break;
+            }
+            default: {
+                $whereFunc = function ($query) {
+                    $query->whereIn('type', ['日志', '评论']);
+                };
+                break;
+            }
+        }
+        //
+        $lists = DB::table('project_log')
+            ->where($whereArray)
+            ->where($whereFunc)
+            ->orderByDesc('indate')->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的记录', $lists);
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $item = array_merge($item, Users::username2basic($item['username']));
+            if (empty($item['userimg'])) {
+                $item['userimg'] = Users::userimg($item['userimg']);
+            }
+            $item['timeData'] = [
+                'ymd' => date(date("Y", $item['indate']) == date("Y", Base::time()) ? "m-d" : "Y-m-d", $item['indate']),
+                'hi' => date("h:i", $item['indate']) ,
+                'week' => "周" . Base::getTimeWeek($item['indate']),
+                'segment' => Base::getTimeDayeSegment($item['indate']),
+            ];
+            $item['other'] = Base::string2array($item['other'], ['type' => '']);
+            $lists['lists'][$key] = $item;
+        }
+        return Base::retSuccess('success', $lists);
+    }
+}

+ 416 - 0
app/Http/Controllers/Api/ReportController.php

@@ -0,0 +1,416 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Module\Base;
+use App\Module\Users;
+use DB;
+use Request;
+use App\Task;
+
+/**
+ * @apiDefine report
+ *
+ * 汇报
+ */
+class ReportController extends Controller
+{
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+    /**
+     * 获取内容
+     *
+     * @apiParam {Number} id           数据ID
+     */
+    public function content()
+    {
+        $row = Base::DBC2A(DB::table('report_content')->select(['rid', 'content'])->where('rid', intval(Request::input('id')))->first());
+        if (empty($row)) {
+            return Base::retError('内容不存在或已被删除!');
+        }
+        return Base::retSuccess('success', $row);
+    }
+
+    /**
+     * {post} 获取模板、保存、发送、删除
+     *
+     * @apiParam {String} type           类型
+     * - 日报
+     * - 周报
+     * @apiParam {Number} [id]          数据ID
+     * @apiParam {String} [act]         请求方式
+     * - submit: 保存
+     * - send: 仅发送
+     * - delete: 删除汇报
+     * - else: 获取
+     * @apiParam {String} [send]        是否发送(1:是),仅act=submit且未发送过的有效
+     * @apiParam {Object} [D]           Request Payload 提交
+     * - title: 标题
+     * - ccuser: 抄送人
+     * - content: 内容
+     */
+    public function template()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $id = intval(Base::getPostValue('id'));
+        $act = trim(Base::getPostValue('act'));
+        $type = trim(Base::getPostValue('type'));
+        if (!in_array($type, ['日报', '周报'])) {
+            return Base::retError('参数错误!');
+        }
+        $dateTitle = "";
+        //
+        $whereArray = [];
+        $whereArray[] = ['username', '=', $user['username']];
+        if ($id > 0) {
+            $whereArray[] = ['id', '=', $id];
+        } else {
+            switch ($type) {
+                case "日报":
+                    $whereArray[] = ['type', '=', '日报'];
+                    $whereArray[] = ['date', '=', date("Ymd")];
+                    $dateTitle = date("Y-m-d");
+                    break;
+                case "周报":
+                    $whereArray[] = ['type', '=', '周报'];
+                    $whereArray[] = ['date', '=', date("W")];
+                    $dateTitle = date("Y年m月") . "第" . Base::getMonthWeek() . "周";
+                    break;
+            }
+        }
+        //
+        $reportDetail = Base::DBC2A(DB::table('report_lists')->where($whereArray)->first());
+        if ($id > 0 && empty($reportDetail)) {
+            return Base::retError('没有相关的数据!');
+        }
+        if ($act == 'send') {
+            if (empty($reportDetail)) {
+                return Base::retError('没有相关的数据或已被删除!');
+            }
+            $ccuser = Base::string2array($reportDetail['ccuser']);
+            DB::table('report_ccuser')->where(['rid' => $reportDetail['id']])->update(['cc' => 0]);
+            foreach ($ccuser AS $ck => $cuser) {
+                if (!$cuser) {
+                    unset($ccuser[$ck]);
+                    continue;
+                }
+                DB::table('report_ccuser')->updateOrInsert([
+                    'rid' => $reportDetail['id'],
+                    'username' => $cuser,
+                    'indate' => Base::time()
+                ], [
+                    'cc' => 1
+                ]);
+            }
+            DB::table('report_lists')->where('id', $reportDetail['id'])->update([
+                'status' => '已发送',
+                'ccuser' => Base::array2string($ccuser)
+            ]);
+            $reportDetail['ccuser'] = implode(',', $ccuser);
+            $reportDetail['ccuserArray'] = explode(',', $reportDetail['ccuser']);
+            return Base::retSuccess('发送成功!', array_merge($reportDetail, [
+                'ccuserAgain' => $reportDetail['status'] == '已发送'
+            ]));
+        } elseif ($act == 'delete') {
+            if (empty($reportDetail)) {
+                return Base::retError('没有相关的数据或已被删除!');
+            }
+            if ($reportDetail['status'] == '已发送') {
+                return Base::retError('汇报已发送,无法删除!');
+            }
+            DB::table('report_lists')->where('id', $reportDetail['id'])->delete();
+            DB::table('report_ccuser')->where('rid', $reportDetail['id'])->delete();
+            DB::table('report_content')->where('rid', $reportDetail['id'])->delete();
+            return Base::retSuccess('删除成功!');
+        } elseif ($act == 'submit') {
+            if (mb_strlen(Base::getPostValue('title')) < 2 || mb_strlen(Base::getPostValue('title')) > 100) {
+                return Base::retError('标题限制2-100个字!');
+            }
+            if (empty($reportDetail)) {
+                DB::table('report_lists')->insert([
+                    'username' => $user['username'],
+                    'title' => Base::getPostValue('title'),
+                    'type' => $type,
+                    'status' => '未发送',
+                    'date' => $type=='日报'?date("Ymd"):date("W"),
+                    'indate' => Base::time(),
+                ]);
+                $reportDetail = Base::DBC2A(DB::table('report_lists')->where($whereArray)->first());
+            }
+            if (empty($reportDetail)) {
+                return Base::retError('系统繁忙,请稍后再试!');
+            }
+            //
+            $ccuserArr = explode(",", Base::getPostValue('ccuser'));
+            $send = $reportDetail['status'] == '已发送' ? 1 : intval(Base::getPostValue('send'));
+            $ccuserAgain = $reportDetail['status'] == '已发送';
+            if ($send) {
+                DB::table('report_ccuser')->where(['rid' => $reportDetail['id']])->update(['cc' => 0]);
+                foreach ($ccuserArr AS $ck => $cuser) {
+                    if (!$cuser) {
+                        unset($ccuserArr[$ck]);
+                        continue;
+                    }
+                    DB::table('report_ccuser')->updateOrInsert([
+                        'rid' => $reportDetail['id'],
+                        'username' => $cuser,
+                        'indate' => Base::time()
+                    ], [
+                        'cc' => 1
+                    ]);
+                }
+                $reportDetail['status'] = '已发送';
+            }
+            //
+            DB::table('report_lists')->where('id', $reportDetail['id'])->update([
+                'title' => Base::getPostValue('title'),
+                'status' => $send ? '已发送' : '未发送',
+                'ccuser' => Base::array2string($ccuserArr)
+            ]);
+            DB::table('report_content')->updateOrInsert(['rid' => $reportDetail['id']], ['content' => Base::getPostValue('content')]);
+            //
+            $reportDetail = array_merge($reportDetail, [
+                'ccuserAgain' => $ccuserAgain,
+                'ccuser' => $ccuserArr,
+                'title' => Base::getPostValue('title'),
+                'content' => Base::getPostValue('content'),
+            ]);
+        }
+        if (empty($reportDetail)) {
+            $startTime = $type == '日报' ? strtotime(date('Y-m-d 00:00:00')) : strtotime(date('Y-m-d 00:00:00', strtotime('this week')));
+            $finishTime = $type == '日报' ? strtotime(date('Y-m-d 23:59:59')) : strtotime(date('Y-m-d 23:59:59', strtotime('last day next week')));
+
+            //zmw 修改
+            $list = Task::where(function($query) use ($user){
+                return $query->where('username',$user['username'])->orwhere('createuser',$user['username']);
+            })->where('delete',0)->with(['subtask'=>function($query) {$query->where('delete',0);}])->get()->toArray();
+
+            $completeContent = '';//已完成的任务
+            $unfinishedContent = '';//未完成的任务
+
+            foreach ($list as $k => $v){
+                if($v['complete'] == 1 && $v['completedate'] >= $startTime && $v['completedate'] <= $finishTime){
+                    //父任务标记已完成,不管子任务是否有完成,统一放到已完成内
+                    $pre = $type == '周报' ? ('<span>[周' . ['日', '一', '二', '三', '四', '五', '六'][date('w')] . ']</span>&nbsp;') : '';
+                    $completeContent .= '<li>' . $pre . $v['title'] . '</li>';
+                    if(count($v['subtask']) > 0){
+                        $completeContent .= '<ol>';
+                        foreach ($v['subtask'] as $key => $value){
+                            $completeContent .= '<li>' . $value['detail'] . '</li>';
+                        }
+                        $completeContent .= '</ol>';
+                    }
+                }
+
+                if($v['complete'] == 0 && $v['enddate'] <= $finishTime){
+                    //父任务未标记已完成,可能实际已完成,但忘记置父任务状态,也可能后续还会增加子任务,故统一放未完成,对父任务未完成,但下面已经完成的子任务做删除线
+                    $pre = $v['enddate'] > 0 && $v['enddate'] < time() ? '<span style="color:#ff0000;">[超期]</span>&nbsp;' : '';
+                    $unfinishedContent .= '<li>' . $pre . $v['title'] . '</li>';
+                    if(count($v['subtask']) > 0){
+                        $unfinishedContent .= '<ol>';
+                        foreach ($v['subtask'] as $key => $value){
+                            $unfinishedContent .= '<li>';
+                            if($value['status'] == 'complete'){
+                                $unfinishedContent .= "<span style='text-decoration: line-through;'>" .$value['detail'] . "</span>";
+                            }else{
+                                $unfinishedContent .= $value['detail'];
+                            }
+                            $unfinishedContent .= '</li>';
+                        }
+                        $unfinishedContent .= '</ol>';
+                    }
+                }
+            }
+
+            if (empty($completeContent)) {
+                $completeContent = '<li>&nbsp;</li>';
+            }
+
+            if (empty($unfinishedContent)) {
+                $unfinishedContent = '<li>&nbsp;</li>';
+            }
+
+            //
+            $reportDetail['title'] = ($user['nickname'] ?: $user['username']) . '的' . $type . '[' . $dateTitle . ']';
+            $reportDetail['ccuser'] = '';
+            $reportDetail['content'] = '<h2>已完成工作</h2><ol>' . $completeContent . '</ol><h2>未完成的工作</h2><ol>' . $unfinishedContent . '</ol>';
+            $reportDetail['status'] = '未保存';
+        } else {
+            $reportDetail['ccuser'] = implode(',', Base::string2array($reportDetail['ccuser']));
+            if (!isset($reportDetail['content'])) {
+                $reportDetail['content'] = DB::table('report_content')->select(['content'])->where('rid', $reportDetail['id'])->value('content');
+            }
+        }
+        $reportDetail['ccuserAgain'] = isset($reportDetail['ccuserAgain']) ? $reportDetail['ccuserAgain'] : false;
+        $reportDetail['ccuserArray'] = explode(',', $reportDetail['ccuser']);
+        return Base::retSuccess($act == 'submit' ? '保存成功!' : 'success', $reportDetail);
+    }
+
+    /**
+     * 我的汇报
+     *
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     */
+    public function my()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $whereArray = [];
+        $whereArray[] = ['username', '=', $user['username']];
+        if (trim(Request::input('username'))) {
+            $whereArray[] = ['username', '=', trim(Request::input('username'))];
+        }
+        if (in_array(trim(Request::input('type')), ['日报', '周报'])) {
+            $whereArray[] = ['type', '=', trim(Request::input('type'))];
+        }
+        $indate = Request::input('indate');
+        if (is_array($indate)) {
+            if ($indate[0] > 0) $whereArray[] = ['indate', '>=', Base::dayTimeF($indate[0])];
+            if ($indate[1] > 0) $whereArray[] = ['indate', '<=', Base::dayTimeE($indate[1])];
+        }
+        //
+        $orderBy = '`indate` DESC,`id` DESC';
+        $sorts = Base::json2array(Request::input('sorts'));
+        if (in_array($sorts['order'], ['asc', 'desc'])) {
+            switch ($sorts['key']) {
+                case 'date':
+                case 'indate':
+                    $orderBy = '`' . $sorts['key'] . '` ' . $sorts['order'] . ',`id` DESC';
+                    break;
+            }
+        }
+        //
+        $lists = DB::table('report_lists')
+            ->where($whereArray)
+            ->orderByRaw($orderBy)
+            ->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的汇报', $lists);
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $lists['lists'][$key]['ccuser'] = Base::string2array($item['ccuser']);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 我的汇报
+     *
+     * @apiParam {String} [username]            汇报者用户名
+     * @apiParam {Array} [indate]               汇报时间
+     * @apiParam {String} [type]                类型
+     * - 日报
+     * - 周报
+     * @apiParam {Object} [sorts]               排序方式,格式:{key:'', order:''}
+     * - key: title|username|indate
+     * - order: asc|desc
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:20,最大:100
+     */
+    public function receive()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $whereArray = [];
+        $whereArray[] = ['report_ccuser.username', '=', $user['username']];
+        $whereArray[] = ['report_ccuser.cc', '=', 1];
+        if (trim(Request::input('username'))) {
+            $whereArray[] = ['report_lists.username', '=', trim(Request::input('username'))];
+        }
+        if (in_array(trim(Request::input('type')), ['日报', '周报'])) {
+            $whereArray[] = ['report_lists.type', '=', trim(Request::input('type'))];
+        }
+        $indate = Request::input('indate');
+        if (is_array($indate)) {
+            if ($indate[0] > 0) $whereArray[] = ['report_lists.indate', '>=', Base::dayTimeF($indate[0])];
+            if ($indate[1] > 0) $whereArray[] = ['report_lists.indate', '<=', Base::dayTimeE($indate[1])];
+        }
+        //
+        $builder = DB::table('report_lists')
+            ->join('report_ccuser', 'report_lists.id', '=', 'report_ccuser.rid')
+            ->select(['report_lists.*', 'report_ccuser.indate as senddate'])
+            ->where($whereArray);
+        $sorts = Base::json2array(Request::input('sorts'));
+        if (in_array($sorts['order'], ['asc', 'desc'])) {
+            switch ($sorts['key']) {
+                case 'title':
+                case 'username':
+                    $builder->orderBy($sorts['key'], $sorts['order']);
+                    break;
+                case 'indate':
+                    $builder->orderBy('report_ccuser.indate', $sorts['order']);
+                    break;
+            }
+        } else {
+            $builder->orderByDesc('report_ccuser.indate');
+            $builder->orderByDesc('report_ccuser.id');
+        }
+        //
+        $builder->orderByDesc('date');
+        $lists = $builder->paginate(Base::getPaginate(100, 20));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的汇报', $lists);
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $lists['lists'][$key]['ccuser'] = Base::string2array($item['ccuser']);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 获取我上次抄送的人
+     * @return array|mixed
+     */
+    public function prevcc()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $rid = DB::table('report_ccuser')
+            ->join('report_lists', 'report_lists.id', '=', 'report_ccuser.rid')
+            ->where('report_lists.username', $user['username'])
+            ->orderByDesc('report_ccuser.id')
+            ->value('rid');
+        if (empty($rid)) {
+            return Base::retError('没有相关数据!');
+        }
+        $lists = Base::DBC2A(DB::table('report_ccuser')->select(['username'])->where('rid', $rid)->pluck('username'));
+        if (empty($lists)) {
+            return Base::retError('没有相关数据!');
+        }
+        return Base::retSuccess('success', [
+            'lists' => $lists
+        ]);
+    }
+}

+ 290 - 0
app/Http/Controllers/Api/SystemController.php

@@ -0,0 +1,290 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Module\Base;
+use App\Module\Users;
+use Request;
+
+/**
+ * @apiDefine system
+ *
+ * 系统
+ */
+class SystemController extends Controller
+{
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+    /**
+     * 获取设置、保存设置
+     *
+     * @apiParam {String} type
+     * - get: 获取(默认)
+     * - save: 保存设置(参数:logo、github、reg、callav、autoArchived、archivedDay)
+     */
+    public function setting()
+    {
+        $type = trim(Request::input('type'));
+        if ($type == 'save') {
+            if (env("SYSTEM_SETTING") == 'disabled') {
+                return Base::retError('当前环境禁止修改!');
+            }
+            $user = Users::authE();
+            if (Base::isError($user)) {
+                return $user;
+            } else {
+                $user = $user['data'];
+            }
+            if (Base::isError(Users::identity('admin'))) {
+                return Base::retError('权限不足!', [], -1);
+            }
+            $all = Request::input();
+            foreach ($all AS $key => $value) {
+                if (!in_array($key, ['logo', 'github', 'reg', 'callav', 'autoArchived', 'archivedDay'])) {
+                    unset($all[$key]);
+                }
+            }
+            $all['logo'] = is_array($all['logo']) ? $all['logo'][0]['path'] : $all['logo'];
+            $all['archivedDay'] = intval($all['archivedDay']);
+            if ($all['autoArchived'] == 'open') {
+                if ($all['archivedDay'] <= 0) {
+                    return Base::retError(['自动归档时间不可小于%天!', 1]);
+                } elseif ($all['archivedDay'] > 100) {
+                    return Base::retError(['自动归档时间不可大于%天!', 100]);
+                }
+            }
+            $setting = Base::setting('system', Base::newTrim($all));
+        } else {
+            $setting = Base::setting('system');
+        }
+        $setting['footerText'] = env('WEBSITE_FOOTER', '');
+        $setting['logo'] = Base::fillUrl($setting['logo']);
+        $setting['enterprise'] = env('ENTERPRISE_SHOW') ? 'show': '';
+        return Base::retSuccess('success', $setting ? $setting : json_decode('{}'));
+    }
+
+    /**
+     * 获取终端详细信息
+     */
+    public function get__info()
+    {
+        if (Request::input("key") !== env('APP_KEY')) {
+            return [];
+        }
+        return Base::retSuccess('success', [
+            'ip' => Base::getIp(),
+            'ip-info' => Base::getIpInfo(Base::getIp()),
+            'ip-iscn' => Base::isCnIp(Base::getIp()),
+            'header' => Request::header(),
+            'token' => Base::getToken(),
+            'url' => url('') . Base::getUrl(),
+        ]);
+    }
+
+    /**
+     * 获取IP地址
+     */
+    public function get__ip() {
+        return Base::getIp();
+    }
+
+    /**
+     * 是否中国IP地址
+     */
+    public function get__cnip() {
+        return Base::isCnIp(Request::input('ip'));
+    }
+
+    /**
+     * 获取IP地址详细信息
+     */
+    public function get__ipinfo() {
+        return Base::getIpInfo(Request::input("ip"));
+    }
+
+    /**
+     * 获取websocket地址
+     */
+    public function get__wsurl() {
+        $wsurl = env('LARAVELS_PROXY_URL');
+        if (!$wsurl) {
+            $wsurl = url('');
+            $wsurl = str_replace('https://', 'wss://', $wsurl);
+            $wsurl = str_replace('http://', 'ws://', $wsurl);
+            $wsurl.= '/ws';
+        }
+        return Base::retSuccess('success', [
+            'wsurl' => $wsurl,
+        ]);
+    }
+
+    /**
+     * 上传图片
+     */
+    public function imgupload()
+    {
+        if (Users::token2userid() === 0) {
+            return Base::retError('身份失效,等重新登录!');
+        }
+        $scale = [intval(Request::input('width')), intval(Request::input('height'))];
+        if (!$scale[0] && !$scale[1]) {
+            $scale = [2160, 4160, -1];
+        }
+        $path = "uploads/picture/" . Users::token2userid() . "/" . date("Ym") . "/";
+        $image64 = trim(Base::getPostValue('image64'));
+        $fileName = trim(Base::getPostValue('filename'));
+        if ($image64) {
+            $data = Base::image64save([
+                "image64" => $image64,
+                "path" => $path,
+                "fileName" => $fileName,
+                "scale" => $scale
+            ]);
+        } else {
+            $data = Base::upload([
+                "file" => Request::file('image'),
+                "type" => 'image',
+                "path" => $path,
+                "fileName" => $fileName,
+                "scale" => $scale
+            ]);
+        }
+        if (Base::isError($data)) {
+            return Base::retError($data['msg']);
+        } else {
+            return Base::retSuccess('success', $data['data']);
+        }
+    }
+
+    /**
+     * 浏览图片空间
+     */
+    public function imgview()
+    {
+        if (Users::token2userid() === 0) {
+            return Base::retError('身份失效,等重新登录!');
+        }
+        $publicPath = "uploads/picture/" . Users::token2userid() . "/";
+        $dirPath = public_path($publicPath);
+        $dirs = $files = [];
+        //
+        $path = Request::input('path');
+        if ($path && is_string($path)) {
+            $path = str_replace(array('||', '|'), '/', $path);
+            $path = trim($path, '/');
+            $path = str_replace('..', '', $path);
+            $path = Base::leftDelete($path, $publicPath);
+            if ($path) {
+                $path = $path . '/';
+                $dirPath .= $path;
+                //
+                $dirs[] = [
+                    'type' => 'dir',
+                    'title' => '...',
+                    'path' => substr(substr($path, 0, -1), 0, strripos(substr($path, 0, -1), '/')),
+                    'url' => '',
+                    'thumb' => Base::fillUrl('images/other/dir.png'),
+                    'inode' => 0,
+                ];
+            }
+        } else {
+            $path = '';
+        }
+        $list = glob($dirPath . '*', GLOB_BRACE);
+        foreach ($list as $v) {
+            $filename = basename($v);
+            $pathTemp = $publicPath . $path . $filename;
+            if (is_dir($v)) {
+                $dirs[] = [
+                    'type' => 'dir',
+                    'title' => $filename,
+                    'path' => $pathTemp,
+                    'url' => Base::fillUrl($pathTemp),
+                    'thumb' => Base::fillUrl('images/other/dir.png'),
+                    'inode' => fileatime($v),
+                ];
+            } elseif (substr($filename, -10) != "_thumb.jpg") {
+                $array = [
+                    'type' => 'file',
+                    'title' => $filename,
+                    'path' => $pathTemp,
+                    'url' => Base::fillUrl($pathTemp),
+                    'thumb' => $pathTemp,
+                    'inode' => fileatime($v),
+                ];
+                //
+                $extension = pathinfo($dirPath . $filename, PATHINFO_EXTENSION);
+                if (in_array($extension, array('gif', 'jpg', 'jpeg', 'png', 'bmp'))) {
+                    if (file_exists($dirPath . $filename . '_thumb.jpg')) {
+                        $array['thumb'] .= '_thumb.jpg';
+                    }
+                    $array['thumb'] = Base::fillUrl($array['thumb']);
+                    $files[] = $array;
+                }
+            }
+        }
+        if ($dirs) {
+            $inOrder = [];
+            foreach ($dirs as $key => $item) {
+                $inOrder[$key] = $item['title'];
+            }
+            array_multisort($inOrder, SORT_DESC, $dirs);
+        }
+        if ($files) {
+            $inOrder = [];
+            foreach ($files as $key => $item) {
+                $inOrder[$key] = $item['inode'];
+            }
+            array_multisort($inOrder, SORT_DESC, $files);
+        }
+        //
+        return Base::retSuccess('success', ['dirs' => $dirs, 'files' => $files]);
+    }
+
+    /**
+     * 上传文件
+     */
+    public function fileupload()
+    {
+        if (Users::token2userid() === 0) {
+            return Base::retError('身份失效,等重新登录!');
+        }
+        $path = "uploads/files/" . Users::token2userid() . "/" . date("Ym") . "/";
+        $image64 = trim(Base::getPostValue('image64'));
+        $fileName = trim(Base::getPostValue('filename'));
+        if ($image64) {
+            $data = Base::image64save([
+                "image64" => $image64,
+                "path" => $path,
+                "fileName" => $fileName,
+            ]);
+        } else {
+            $data = Base::upload([
+                "file" => Request::file('files'),
+                "type" => 'file',
+                "path" => $path,
+                "fileName" => $fileName,
+            ]);
+        }
+        //
+        return $data;
+    }
+
+    /**
+     * 清理opcache数据
+     * @return int
+     */
+    public function opcache()
+    {
+        opcache_reset();
+        return Base::time();
+    }
+}

+ 587 - 0
app/Http/Controllers/Api/UsersController.php

@@ -0,0 +1,587 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\Model\DBCache;
+use App\Module\Base;
+use App\Module\Users;
+use DB;
+use Request;
+use Session;
+use SimpleDingTalk\User;
+
+/**
+ * @apiDefine users
+ *
+ * 会员
+ */
+class UsersController extends Controller
+{
+    public function __invoke($method, $action = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        return (method_exists($this, $app)) ? $this->$app() : Base::ajaxError("404 not found (" . str_replace("__", "/", $app) . ").");
+    }
+
+    /**
+     * 登陆、注册
+     *
+     * @apiParam {String} type           类型
+     * - login:登录(默认)
+     * - reg:注册
+     * @apiParam {String} username       用户名
+     * @apiParam {String} userpass       密码
+     */
+    public function login()
+    {
+        $type = trim(Request::input('type'));
+        $username = trim(Request::input('username'));
+        $userpass = trim(Request::input('userpass'));
+        if ($type == 'reg') {
+            $setting = Base::setting('system');
+            if ($setting['reg'] == 'close') {
+                return Base::retError('未开放注册。');
+            }
+            $user = Users::reg($username, $userpass);
+            if (Base::isError($user)) {
+                return $user;
+            } else {
+                $user = $user['data'];
+            }
+        } else {
+            $user = Base::DBC2A(DB::table('users')->where('username', $username)->first());
+            if (empty($user)) {
+                return Base::retError('账号或密码错误。');
+            }
+            if ($user['userpass'] != Base::md52($userpass, $user['encrypt'])) {
+                return Base::retError('账号或密码错误!');
+            }
+            if (in_array($user['id'], [1, 2])) {
+                $user['setting'] = Base::string2array($user['setting']);
+                if (intval($user['setting']['version']) < 1) {
+                    $user['setting']['version'] = intval($user['setting']['version']) + 1;
+                    $user['identity'] = ',admin,';
+                    DB::table('users')->where('username', $username)->update([
+                        'setting' => Base::array2string($user['setting']),
+                        'identity' => $user['identity'],
+                    ]);
+                }
+            }
+        }
+        //
+        $array = [
+            'token' => Users::token($user),
+            'loginnum' => $user['loginnum'] + 1,
+            'lastip' => Base::getIp(),
+            'lastdate' => Base::time(),
+            'lineip' => Base::getIp(),
+            'linedate' => Base::time(),
+        ];
+        Base::array_over($user, $array);
+        DB::table('users')->where('id', $user['id'])->update($array);
+        //
+        return Base::retSuccess($type == 'reg' ? "注册成功!" : "登陆成功!", Users::retInfo($user));
+    }
+
+    /**
+     * 获取我的信息
+     *
+     * @apiParam {String} [callback]           jsonp返回字段
+     */
+    public function info()
+    {
+        $callback = Request::input('callback');
+        //
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            if (strlen($callback) > 3) {
+                return $callback . '(' . json_encode($user) . ')';
+            }
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        if (strlen($callback) > 3) {
+            return $callback . '(' . json_encode(Base::retSuccess('success', Users::retInfo($user))) . ')';
+        }
+        return Base::retSuccess('success', Users::retInfo($user));
+    }
+
+    /**
+     * 获取指定会员基本信息
+     *
+     * @apiParam {String|jsonArray} username          会员用户名(多个格式:jsonArray,一次最多30个)
+     */
+    public function basic()
+    {
+        $username = trim(Request::input('username'));
+        $array = Base::json2array($username);
+        if (empty($array)) {
+            $array[] = $username;
+        }
+        if (count($array) > 50) {
+            return Base::retError(['一次最多只能获取%条数据!', 50]);
+        }
+        $retArray = [];
+        foreach ($array AS $name) {
+            $basic = Users::username2basic($name);
+            if ($basic) {
+                $retArray[] = $basic;
+            }
+        }
+        return Base::retSuccess('success', $retArray);
+    }
+
+    /**
+     * 搜索会员列表
+     *
+     * @apiParam {Object} where            搜索条件
+     * - where.usernameequal
+     * - where.nousername
+     * - where.username
+     * - where.noidentity
+     * - where.identity
+     * - where.noprojectid
+     * - where.projectid
+     * - where.nobookid
+     * @apiParam {Number} [take]           获取数量,10-100
+     */
+    public function searchinfo()
+    {
+        $keys = Request::input('where');
+        $whereArr = [];
+        $whereRaw = null;
+        if ($keys['usernameequal'])     $whereArr[] = ['username', '=', $keys['usernameequal']];
+        if ($keys['identity'])          $whereArr[] = ['identity', 'like', '%,' . $keys['identity'] . ',%'];
+        if ($keys['noidentity'])        $whereArr[] = ['identity', 'not like', '%,' . $keys['noidentity'] . ',%'];
+        if ($keys['username']) {
+            $whereRaw.= $whereRaw ? ' AND ' : '';
+            $whereRaw.= "(`username` LIKE '%" . $keys['username'] . "%' OR `nickname` LIKE '%" . $keys['username'] . "%')";
+        }
+        if (intval($keys['projectid']) > 0) {
+            $whereRaw.= $whereRaw ? ' AND ' : '';
+            $whereRaw.= "`username` IN (SELECT username FROM `" . env('DB_PREFIX') . "project_users` WHERE `type`='成员' AND `projectid`=" . intval($keys['projectid']) .")";
+        }
+        if ($keys['nousername']) {
+            $nousername = [];
+            foreach (explode(",", $keys['nousername']) AS $name) {
+                $name = trim($name);
+                if ($name && !in_array($name, $nousername)) {
+                    $nousername[] = $name;
+                }
+            }
+            if ($nousername) {
+                $whereRaw.= $whereRaw ? ' AND ' : '';
+                $whereRaw.= "(`username` NOT IN ('" . implode("','", $nousername) . "'))";
+            }
+        }
+        if (intval($keys['noprojectid']) > 0) {
+            $whereRaw.= $whereRaw ? ' AND ' : '';
+            $whereRaw.= "`username` NOT IN (SELECT username FROM `" . env('DB_PREFIX') . "project_users` WHERE `type`='成员' AND `projectid`=" . intval($keys['noprojectid']) .")";
+        }
+        if (intval($keys['nobookid']) > 0) {
+            $whereRaw.= $whereRaw ? ' AND ' : '';
+            $whereRaw.= "`username` NOT IN (SELECT username FROM `" . env('DB_PREFIX') . "docs_users` WHERE `bookid`=" . intval($keys['nobookid']) .")";
+        }
+        //
+        $lists = DBCache::table('users')->select(['id', 'username', 'nickname', 'userimg', 'profession'])
+            ->where($whereArr)
+            ->whereRaw($whereRaw)
+            ->orderBy('id')
+            ->cacheMinutes(now()->addSeconds(10))
+            ->take(Base::getPaginate(100, 10, 'take'))
+            ->get();
+        foreach ($lists AS $key => $item) {
+            $lists[$key]['userimg'] = Users::userimg($item['userimg']);
+            $lists[$key]['identitys'] = explode(",", trim($item['identity'], ","));
+            $lists[$key]['setting'] = Base::string2array($item['setting']);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 修改资料
+     *
+     * @apiParam {Object} [userimg]             会员头像
+     * @apiParam {String} [nickname]            昵称
+     * @apiParam {String} [profession]          职位/职称
+     * @apiParam {String} [bgid]                背景编号
+     */
+    public function editdata()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $array = [];
+        //头像
+        $userimg = Request::input('userimg');
+        if ($userimg) {
+            $userimg = is_array($userimg) ? $userimg[0]['path'] : $userimg;
+            $array['userimg'] = Base::unFillUrl($userimg);
+        }
+        //昵称
+        $nickname = trim(Request::input('nickname'));
+        if ($nickname) {
+            if (mb_strlen($nickname) < 2) {
+                return Base::retError('昵称不可以少于2个字!');
+            } elseif (mb_strlen($nickname) > 8) {
+                return Base::retError('昵称最多只能设置8个字!');
+            } else {
+                $array['nickname'] = $nickname;
+            }
+        }
+        //职位/职称
+        $profession = trim(Request::input('profession'));
+        if ($profession) {
+            if (mb_strlen($profession) < 2) {
+                return Base::retError('职位/职称不可以少于2个字!');
+            } elseif (mb_strlen($profession) > 20) {
+                return Base::retError('职位/职称最多只能设置20个字!');
+            } else {
+                $array['profession'] = $profession;
+            }
+        }
+        //背景
+        $bgid = intval(Request::input('bgid'));
+        if ($bgid > 0) {
+            $array['bgid'] = $bgid;
+        }
+        //
+        if ($array) {
+            DB::table('users')->where('id', $user['id'])->update($array);
+            Users::AZUpdate($user['id']);
+        } else {
+            return Base::retError('请设置要修改的内容!');
+        }
+        return Base::retSuccess('修改成功!');
+    }
+
+    /**
+     * 修改密码
+     *
+     * @apiParam {String} oldpass           旧密码
+     * @apiParam {String} newpass           新密码
+     */
+    public function editpass()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $oldpass = trim(Request::input('oldpass'));
+        $newpass = trim(Request::input('newpass'));
+        if (strlen($newpass) < 6) {
+            return Base::retError('密码设置不能小于6位数!');
+        } elseif (strlen($newpass) > 32) {
+            return Base::retError('密码最多只能设置32位数!');
+        }
+        if ($oldpass == $newpass) {
+            return Base::retError('新旧密码一致!');
+        }
+        //
+        if (env("PASSWORD_ADMIN") == 'disabled') {
+            if ($user['id'] == 1) {
+                return Base::retError('当前环境禁止修改密码!');
+            }
+        }
+        if (env("PASSWORD_OWNER") == 'disabled') {
+            return Base::retError('当前环境禁止修改密码!');
+        }
+        //
+        if ($user['setpass']) {
+            $verify = DB::table('users')->where(['id'=>$user['id'], 'userpass'=>Base::md52($oldpass, Users::token2encrypt())])->count();
+            if (empty($verify)) {
+                return Base::retError('请填写正确的旧密码!');
+            }
+        }
+        $encrypt = Base::generatePassword(6);
+        DB::table('users')->where('id', $user['id'])->update([
+            'encrypt' => $encrypt,
+            'userpass' => Base::md52($newpass, $encrypt),
+            'changepass' => 0
+        ]);
+        return Base::retSuccess('修改成功');
+    }
+
+    /**
+     * 团队列表
+     *
+     * @apiParam {Object} [sorts]               排序方式,格式:{key:'', order:''}
+     * - key: username|az|id(默认)
+     * - order: asc|desc
+     * @apiParam {String} [username]            指定获取某个成员(返回对象)
+     * @apiParam {Number} [page]                当前页,默认:1
+     * @apiParam {Number} [pagesize]            每页显示数量,默认:10,最大:100
+     */
+    public function team__lists()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        $username = trim(Request::input('username'));
+        $whereArray = [];
+        if ($username) {
+            $whereArray[] = ['username', '=', $username];
+        }
+        //
+        $orderBy = '`id` DESC';
+        $sorts = Base::json2array(Request::input('sorts'));
+        if (in_array($sorts['order'], ['asc', 'desc'])) {
+            switch ($sorts['key']) {
+                case 'username':
+                    $orderBy = '`' . $sorts['key'] . '` ' . $sorts['order'] . ',`id` DESC';
+                    break;
+                case 'az':
+                    $orderBy = '`' . $sorts['key'] . '` ' . $sorts['order'] . ',`username` ' . $sorts['order'] . ',`id` DESC';
+                    break;
+            }
+        }
+        //
+        $lists = DB::table('users')->where($whereArray)->select(['id', 'identity', 'username', 'nickname', 'az', 'userimg', 'profession', 'regdate'])->orderByRaw($orderBy)->paginate(Base::getPaginate(100, 10));
+        $lists = Base::getPageList($lists);
+        if ($lists['total'] == 0) {
+            return Base::retError('未找到任何相关的团队成员');
+        }
+        foreach ($lists['lists'] AS $key => $item) {
+            $lists['lists'][$key]['identity'] = is_array($item['identity']) ? $item['identity'] : explode(",", trim($item['identity'], ","));
+            $lists['lists'][$key]['userimg'] = Users::userimg($item['userimg']);
+        }
+        if ($username) {
+            return Base::retSuccess('success', $lists['lists'][0]);
+        }
+        return Base::retSuccess('success', $lists);
+    }
+
+    /**
+     * 添加团队成员
+     *
+     * @apiParam {Number} [id]                  用户ID(留空为添加用户)
+     * @apiParam {String} username              用户名(修改时无效,多个用英文逗号分隔)
+     * @apiParam {String} userpass              密码
+     * @apiParam {Object} [userimg]             会员头像
+     * @apiParam {String} [nickname]            昵称
+     * @apiParam {String} [profession]          职位/职称
+     * @apiParam {Number} changepass            登陆是否需要修改密码
+     */
+    public function team__add()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        if (Base::isError(Users::identity('admin'))) {
+            return Base::retError('权限不足!', [], -1);
+        }
+        //头像
+        $userimg = Request::input('userimg');
+        if ($userimg) {
+            $userimg = is_array($userimg) ? $userimg[0]['path'] : $userimg;
+        }
+        //昵称
+        $nickname = trim(Request::input('nickname'));
+        if ($nickname) {
+            if (mb_strlen($nickname) < 2) {
+                return Base::retError('昵称不可以少于2个字!');
+            } elseif (mb_strlen($nickname) > 8) {
+                return Base::retError('昵称最多只能设置8个字!');
+            }
+        }
+        //职位/职称
+        $profession = trim(Request::input('profession'));
+        if ($profession) {
+            if (mb_strlen($profession) < 2) {
+                return Base::retError('职位/职称不可以少于2个字!');
+            } elseif (mb_strlen($profession) > 20) {
+                return Base::retError('职位/职称最多只能设置20个字!');
+            }
+        }
+        //
+        $id = intval(Request::input('id'));
+        $userpass = trim(Request::input('userpass'));
+        $otherArray = [
+            'userimg' => $userimg ?: '',
+            'nickname' => $nickname ?: '',
+            'profession' => $profession ?: '',
+            'changepass' => intval(Request::input('changepass')),
+        ];
+        if ($id > 0) {
+            //开始修改
+            if ($userpass) {
+                if (strlen($userpass) < 6) {
+                    return Base::retError('密码设置不能小于6位数!');
+                } elseif (strlen($userpass) > 32) {
+                    return Base::retError('密码最多只能设置32位数!');
+                }
+                $encrypt = Base::generatePassword(6);
+                $otherArray['encrypt'] = $encrypt;
+                $otherArray['userpass'] = Base::md52($userpass, $encrypt);
+            }
+            DB::table('users')->where('id', $id)->update($otherArray);
+            Users::AZUpdate($id);
+            return Base::retSuccess('修改成功!');
+        } else {
+            //开始注册
+            if (strlen($userpass) < 6) {
+                return Base::retError('密码设置不能小于6位数!');
+            } elseif (strlen($userpass) > 32) {
+                return Base::retError('密码最多只能设置32位数!');
+            }
+            $username = trim(Request::input('username'));
+            $array = array_values(array_filter(array_unique(explode(",", $username))));
+            if (empty($array)) {
+                return Base::retError('请填写有效的用户名!');
+            }
+            if (count($array) > 500) {
+                return Base::retError(['一次最多只能添加%个账号!', 500]);
+            }
+            foreach ($array AS $item) {
+                $username = trim($item);
+                if ($username) {
+                    $user = Users::reg($username, $userpass, $otherArray);
+                    if (Base::isError($user)) {
+                        return $user;
+                    }
+                }
+            }
+            return Base::retSuccess('添加成功!');
+        }
+    }
+
+    /**
+     * 删除团队成员
+     *
+     * @apiParam {String} username           用户名
+     */
+    public function team__delete()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        if (Base::isError(Users::identity('admin'))) {
+            return Base::retError('权限不足!', [], -1);
+        }
+        $username = trim(Request::input('username'));
+        if ($user['username'] == $username) {
+            return Base::retError('不能删除自己!');
+        }
+        //
+        if (DB::table('users')->where('username', $username)->delete()) {
+            return Base::retSuccess('删除成功!');
+        } else {
+            return Base::retError('删除失败!');
+        }
+    }
+
+    /**
+     * 设置、删除管理员
+     *
+     * @apiParam {String} act           操作
+     * - set: 设置管理员
+     * - del: 删除管理员
+     * @apiParam {String} username      用户名
+     */
+    public function team__admin()
+    {
+        $user = Users::authE();
+        if (Base::isError($user)) {
+            return $user;
+        } else {
+            $user = $user['data'];
+        }
+        //
+        if (Base::isError(Users::identity('admin'))) {
+            return Base::retError('权限不足!', [], -1);
+        }
+        //
+        $username = trim(Request::input('username'));
+        if ($user['username'] == $username) {
+            return Base::retError('不能操作自己!');
+        }
+        $userInfo = Base::DBC2A(DB::table('users')->where('username', $username)->first());
+        if (empty($userInfo)) {
+            return Base::retError('成员不存在!');
+        }
+        $identity = is_array($userInfo['identity']) ? $userInfo['identity'] : explode(",", trim($userInfo['identity'], ","));
+        $isUp = false;
+        if (trim(Request::input('act')) == 'del') {
+            if (Users::identityRaw('admin', $identity)) {
+                $identity = array_diff($identity, ['admin']);
+                $isUp = true;
+            }
+        } else {
+            if (!Users::identityRaw('admin', $identity)) {
+                $identity[] = 'admin';
+                $isUp = true;
+            }
+        }
+        if ($isUp) {
+            DB::table('users')->where('username', $username)->update([
+                'identity' => $identity ? (',' . implode(",", $identity) . ',') : ''
+            ]);
+        }
+        return Base::retSuccess('操作成功!', [
+            'up' => $isUp ? 1 : 0,
+            'identity' => $identity
+        ]);
+    }
+
+    /**
+     * 设置、删除友盟token
+     *
+     * @apiParam {String} act           操作
+     * - set: 设置token
+     * - del: 删除token
+     * @apiParam {String} token         友盟token
+     * @apiParam {String} platform      ios|android
+     */
+    public function umeng__token()
+    {
+        $act = trim(Request::input('act'));
+        $token = trim(Request::input('token'));
+        if (empty($token)) {
+            return Base::retError('token empty');
+        }
+        $platform = strtolower(trim(Request::input('platform')));
+        DB::table('umeng')->where('token', $token)->delete();
+        //
+        if ($act == 'set') {
+            $user = Users::authE();
+            if (Base::isError($user)) {
+                return $user;
+            } else {
+                $user = $user['data'];
+            }
+            DB::table('umeng')->insert([
+                'token' => $token,
+                'username' => $user['username'],
+                'platform' => $platform,
+                'update' => Base::time(),
+            ]);
+        }
+        //
+        return Base::retSuccess('success');
+    }
+}

+ 10 - 0
app/Http/Controllers/Api/apidoc.json

@@ -0,0 +1,10 @@
+{
+  "name": "API",
+  "title": "APP接口",
+  "version": "2.0.0",
+  "description": "APP接口文档",
+  "url": "https://你的域名/",
+  "template": {
+    "withGenerator": false
+  }
+}

+ 89 - 0
app/Http/Controllers/Api/apidoc.php

@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * 给apidoc项目增加顺序编号
+ */
+
+error_reporting(E_ALL & ~E_NOTICE);
+
+$path = dirname(__FILE__). '/';
+$lists = scandir($path);
+//
+foreach ($lists AS $item) {
+    $fillPath = $path . $item;
+    if (substr($fillPath, -14) == 'Controller.php') {
+        $content = file_get_contents($fillPath);
+        preg_match_all("/\* @api \{(.+?)\} (.*?)\n/i", $content, $matchs);
+        $i = 1;
+        foreach ($matchs[2] AS $key=>$text) {
+            if (in_array(strtolower($matchs[1][$key]), array('get', 'post'))) {
+                $expl = explode(" ", __sRemove($text));
+                $end = $expl[1];
+                if ($expl[2]) {
+                    $end = '';
+                    foreach ($expl AS $k=>$v) { if ($k >= 2) { $end.= " ".$v; } }
+                }
+                $newtext = "* @api {".$matchs[1][$key]."} ".$expl[0]."          ".__zeroFill($i, 2).". ".trim($end);
+                $content = str_replace("* @api {".$matchs[1][$key]."} ".$text, $newtext, $content);
+                $i++;
+                //
+                echo $newtext;
+                echo "\r\n";
+            }
+        }
+        if ($i > 1) {
+            file_put_contents($fillPath, $content);
+        }
+    }
+}
+echo "Success \n";
+
+/** ************************************************************** */
+/** ************************************************************** */
+/** ************************************************************** */
+
+/**
+ * 替换所有空格
+ * @param $str
+ * @return mixed
+ */
+function __sRemove($str) {
+    $str = str_replace("  ", " ", $str);
+    if (__strExists($str, "  ")) {
+        return __sRemove($str);
+    }
+    return $str;
+}
+
+/**
+ * 是否包含字符
+ * @param $string
+ * @param $find
+ * @return bool
+ */
+function __strExists($string, $find)
+{
+    return !(strpos($string, $find) === FALSE);
+}
+
+/**
+ * @param string $str 补零
+ * @param int $length
+ * @param int $after
+ * @return bool|string
+ */
+function __zeroFill($str, $length = 0, $after = 1) {
+    if (strlen($str) >= $length) {
+        return $str;
+    }
+    $_str = '';
+    for ($i = 0; $i < $length; $i++) {
+        $_str .= '0';
+    }
+    if ($after) {
+        $_ret = substr($_str . $str, $length * -1);
+    } else {
+        $_ret = substr($str . $_str, 0, $length);
+    }
+    return $_ret;
+}

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

@@ -0,0 +1,13 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
+use Illuminate\Foundation\Bus\DispatchesJobs;
+use Illuminate\Foundation\Validation\ValidatesRequests;
+use Illuminate\Routing\Controller as BaseController;
+
+class Controller extends BaseController
+{
+    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
+}

+ 68 - 0
app/Http/Controllers/IndexController.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Module\Base;
+use Redirect;
+use DB;
+
+/**
+ * 页面
+ * Class IndexController
+ * @package App\Http\Controllers
+ */
+class IndexController extends Controller
+{
+
+    public function __invoke($method, $action = '', $child = '')
+    {
+        $app = $method ? $method : 'main';
+        if ($action) {
+            $app .= "__" . $action;
+        }
+        if (!method_exists($this, $app)) {
+            $app = 'main';
+        }
+        return $this->$app($child);
+    }
+
+    /**
+     * 首页
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+     */
+    public function main()
+    {
+        return view('main', ['version' => Base::getVersion()]);
+    }
+
+
+    /**
+     * 接口文档
+     * @return \Illuminate\Http\RedirectResponse
+     */
+    public function api()
+    {
+        return Redirect::to(Base::fillUrl('docs'), 301);
+    }
+
+    public function test(){
+        $list = DB::table("project_task")->where('delete',0)->get()->toArray();
+        foreach ($list as $k => $v){
+            $subtasks = Base::string2array($v->subtask);
+            if(count($subtasks) > 0){
+                $subtasks_data = [];
+                foreach ($subtasks as $key => $value){
+                    $item = [
+                        'taskid' => $v->id,
+                        'uname' => $value['uname'],
+                        'indate' => $value['time'],
+                        'status' => $value['status'],
+                        'detail' => $value['detail']
+                    ];
+                    array_push($subtasks_data,$item);
+                }
+                DB::table('project_sub_task')->insert($subtasks_data);
+            }
+        }
+    }
+}

+ 70 - 0
app/Http/Kernel.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Http;
+
+use Illuminate\Foundation\Http\Kernel as HttpKernel;
+
+class Kernel extends HttpKernel
+{
+    /**
+     * The application's global HTTP middleware stack.
+     *
+     * These middleware are run during every request to your application.
+     *
+     * @var array
+     */
+    protected $middleware = [
+        \App\Http\Middleware\TrustProxies::class,
+        \Fruitcake\Cors\HandleCors::class,
+        \App\Http\Middleware\CheckForMaintenanceMode::class,
+        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
+        \App\Http\Middleware\TrimStrings::class,
+        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
+    ];
+
+    /**
+     * The application's route middleware groups.
+     *
+     * @var array
+     */
+    protected $middlewareGroups = [
+        'web' => [
+            \App\Http\Middleware\EncryptCookies::class,
+            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
+            \Illuminate\Session\Middleware\StartSession::class,
+            // \Illuminate\Session\Middleware\AuthenticateSession::class,
+            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
+            \App\Http\Middleware\VerifyCsrfToken::class,
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        ],
+
+        'api' => [
+            'throttle:60,1',
+            \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        ],
+    ];
+
+    /**
+     * The application's route middleware.
+     *
+     * These middleware may be assigned to groups or used individually.
+     *
+     * @var array
+     */
+    protected $routeMiddleware = [
+        'auth' => \App\Http\Middleware\Authenticate::class,
+        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
+        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
+        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
+        'can' => \Illuminate\Auth\Middleware\Authorize::class,
+        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
+        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
+        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
+        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
+        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
+    ];
+
+    protected $commands = [
+        'App\Console\Commands\Action',
+    ];
+}

+ 32 - 0
app/Http/Middleware/ApiMiddleware.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Request;
+
+class ApiMiddleware
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return mixed
+     */
+    public function handle($request, Closure $next)
+    {
+        global $_A;
+        $_A = [];
+
+        @error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
+
+        if (Request::input('__Access-Control-Allow-Origin') || Request::header('__Access-Control-Allow-Origin')) {
+            header('Access-Control-Allow-Origin:*');
+            header('Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS');
+            header('Access-Control-Allow-Headers:Content-Type, platform, platform-channel, token, release, Access-Control-Allow-Origin');
+        }
+
+        return $next($request);
+    }
+}

+ 21 - 0
app/Http/Middleware/Authenticate.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Auth\Middleware\Authenticate as Middleware;
+
+class Authenticate extends Middleware
+{
+    /**
+     * Get the path the user should be redirected to when they are not authenticated.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return string|null
+     */
+    protected function redirectTo($request)
+    {
+        if (! $request->expectsJson()) {
+            return route('login');
+        }
+    }
+}

+ 17 - 0
app/Http/Middleware/CheckForMaintenanceMode.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
+
+class CheckForMaintenanceMode extends Middleware
+{
+    /**
+     * The URIs that should be reachable while maintenance mode is enabled.
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

+ 35 - 0
app/Http/Middleware/EnableCrossRequestMiddleware.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Closure;
+use Illuminate\Http\Request;
+
+class EnableCrossRequestMiddleware
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
+     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
+     */
+    public function handle(Request $request, Closure $next)
+    {
+        $response = $next($request);
+        $origin = $request->server('HTTP_ORIGIN') ? $request->server('HTTP_ORIGIN') : '';
+        $allow_origin = [
+            'http://**.com',//允许访问
+            'http://**.com',//允许访问
+        ];
+        if (in_array($origin, $allow_origin)) {
+            $response->header('Access-Control-Allow-Origin', $origin);
+            $response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, X-CSRF-TOKEN, Accept, Authorization, X-XSRF-TOKEN');
+            $response->header('Access-Control-Expose-Headers', 'Authorization, authenticated');
+            $response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
+            $response->header('Access-Control-Allow-Credentials', 'true');
+        }
+        return $response;
+
+    }
+}

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

@@ -0,0 +1,17 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
+
+class EncryptCookies extends Middleware
+{
+    /**
+     * The names of the cookies that should not be encrypted.
+     *
+     * @var array
+     */
+    protected $except = [
+        //
+    ];
+}

+ 27 - 0
app/Http/Middleware/RedirectIfAuthenticated.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use App\Providers\RouteServiceProvider;
+use Closure;
+use Illuminate\Support\Facades\Auth;
+
+class RedirectIfAuthenticated
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @param  string|null  $guard
+     * @return mixed
+     */
+    public function handle($request, Closure $next, $guard = null)
+    {
+        if (Auth::guard($guard)->check()) {
+            return redirect(RouteServiceProvider::HOME);
+        }
+
+        return $next($request);
+    }
+}

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

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
+
+class TrimStrings extends Middleware
+{
+    /**
+     * The names of the attributes that should not be trimmed.
+     *
+     * @var array
+     */
+    protected $except = [
+        'password',
+        'password_confirmation',
+    ];
+}

+ 23 - 0
app/Http/Middleware/TrustProxies.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Fideloper\Proxy\TrustProxies as Middleware;
+use Illuminate\Http\Request;
+
+class TrustProxies extends Middleware
+{
+    /**
+     * The trusted proxies for this application.
+     *
+     * @var array|string
+     */
+    protected $proxies;
+
+    /**
+     * The headers that should be used to detect proxies.
+     *
+     * @var int
+     */
+    protected $headers = Request::HEADER_X_FORWARDED_ALL;
+}

+ 39 - 0
app/Http/Middleware/VerifyCsrfToken.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Http\Middleware;
+
+use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
+
+class VerifyCsrfToken extends Middleware
+{
+    /**
+     * The URIs that should be excluded from CSRF verification.
+     *
+     * @var array
+     */
+    protected $except = [
+        //上传图片
+        'api/system/imgupload/',
+
+        //上传文件
+        'api/system/fileupload/',
+
+        //上传项目文件
+        'api/project/files/upload/',
+
+        //上传聊天文件
+        'api/chat/files/upload/',
+
+        //修改项目任务
+        'api/project/task/edit/',
+
+        //汇报提交
+        'api/report/template/',
+
+        //保存文档
+        'api/docs/section/save/',
+
+        //钉钉系列
+        'api/ding/notice/push'
+    ];
+}

+ 29 - 0
app/Jobs/Timer/SystemCronJob.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Jobs\Timer;
+
+use App\Tasks\AutoArchivedTask;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+use Hhxsv5\LaravelS\Swoole\Timer\CronJob;
+
+class SystemCronJob extends CronJob
+{
+    protected $i = 0;
+
+    public function interval()
+    {
+        return 60000;    // 每60秒运行一次
+    }
+
+    public function isImmediate()
+    {
+        return true;    // 是否立即执行第一次,false则等待间隔时间后执行第一次
+    }
+
+    public function run()
+    {
+        $this->i++;
+        $autoArchivedTask = new AutoArchivedTask();
+        Task::deliver($autoArchivedTask);
+    }
+}

+ 526 - 0
app/Model/DBCache.php

@@ -0,0 +1,526 @@
+<?php
+
+namespace App\Model;
+
+use Cache;
+use Closure;
+use DateTime;
+use Illuminate\Pagination\Paginator;
+
+/**
+ * 数据库模型 缓存读取
+ *
+ * Class DBCache
+ * @package App\Model
+ */
+class DBCache
+{
+    protected $table = null;
+
+    protected $attributes = [];
+
+    protected $builder = null;
+
+    private $__cache = true;               //启用缓存(默认启用)
+    private $__cacheKeyname = null;        //缓存名称(默认自动生成)
+    private $__cacheMinutes = 1;           //缓存时间(分钟, 默认1分钟)
+    private $__removeCache = false;        //删除缓存
+    private $__join = [];
+    private $__take = [];
+    private $__where = [];
+    private $__whereRaw = [];
+    private $__whereIn = [];
+    private $__select = [];
+    private $__selectRaw = [];
+    private $__orderBy = [];
+    private $__orderByRaw = [];
+    private $__inRandomOrder = false;
+
+    public function __construct($tabel = null, array $attributes = [])
+    {
+        $this->initParameter();
+        if ($tabel) {
+            $this->table = $tabel;
+        }
+        if ($attributes) {
+            $this->attributes = $attributes;
+        }
+    }
+
+    public function setTable($table)
+    {
+        $this->table = $table;
+        return $this;
+    }
+
+    public function setAttributes($attributes)
+    {
+        $this->attributes = $attributes;
+        return $this;
+    }
+
+    /**
+     * 是否缓存
+     *
+     * @param bool $isCache
+     * @return $this
+     */
+    public function cache($isCache = true)
+    {
+        $this->__cache = $isCache ? true : false;
+        return $this;
+    }
+
+    public function noCache()
+    {
+        $this->__cache = false;
+        return $this;
+    }
+
+    /**
+     * 缓存名称
+     *
+     * @param $name
+     * @return $this
+     */
+    public function cacheKeyname($name)
+    {
+        $this->__cacheKeyname = $name ?: null;
+        return $this;
+    }
+
+    /**
+     * 缓存时间(分钟)
+     *
+     * @param $Minutes
+     * @return $this
+     */
+    public function cacheMinutes($Minutes)
+    {
+        if ($Minutes === 'year') {
+            $Minutes = 365 * 24 * 60;
+        }elseif ($Minutes === 'month') {
+            $Minutes = 30 * 24 * 60;
+        }elseif ($Minutes === 'day') {
+            $Minutes = 24 * 60;
+        }elseif ($Minutes === 'hour') {
+            $Minutes = 60;
+        }
+        if ($Minutes instanceof DateTime) {
+            $this->__cacheMinutes = $Minutes;
+        }else{
+            $this->__cacheMinutes = max($Minutes, 1);
+        }
+        return $this;
+    }
+
+    /**
+     * 删除缓存
+     */
+    public function removeCache()
+    {
+        $this->__removeCache = true;
+        return $this;
+    }
+    public function forgetCache($cacheKey)
+    {
+        $this->__removeCache = false;
+        return Cache::forget($cacheKey);
+    }
+
+    /* ******************************************************************************** */
+    /* ******************************************************************************** */
+
+    public function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false)
+    {
+        $this->__join[] = [
+            $table,
+            $first,
+            $operator,
+            $second,
+            $type,
+            $where
+        ];
+        return $this;
+    }
+
+    public function take($var)
+    {
+        $this->__take[] = $var;
+        return $this;
+    }
+
+    public function where($column, $operator = null, $value = null, $boolean = 'and')
+    {
+        $this->__where[] = [
+            $column,
+            $operator,
+            $value,
+            $boolean
+        ];
+        return $this;
+    }
+
+    public function whereRaw($sql, $bindings = [], $boolean = 'and')
+    {
+        if ($sql === null) {
+            return $this;
+        }
+        $this->__whereRaw[] = [
+            $sql,
+            $bindings,
+            $boolean
+        ];
+        return $this;
+    }
+
+    public function whereIn($column, $values, $boolean = 'and', $not = false)
+    {
+        $this->__whereIn[] = [
+            $column,
+            $values,
+            $boolean,
+            $not
+        ];
+        return $this;
+    }
+    public function whereNotIn($column, $values, $boolean = 'and')
+    {
+        return $this->whereIn($column, $values, $boolean, true);
+    }
+
+    public function select($var = ['*'])
+    {
+        $this->__select[] = is_array($var) ? $var : func_get_args();
+        return $this;
+    }
+
+    public function selectRaw($expression, array $bindings = [])
+    {
+        $this->__selectRaw[] = [
+            $expression,
+            $bindings
+        ];
+        return $this;
+    }
+
+    public function orderBy($column, $direction = 'asc')
+    {
+        $this->__orderBy[] = [
+            $column,
+            $direction
+        ];
+        return $this;
+    }
+    public function orderByDesc($column)
+    {
+        return $this->orderBy($column, 'desc');
+    }
+
+    public function orderByRaw($sql, $bindings = [])
+    {
+        $this->__orderByRaw[] = [
+            $sql,
+            $bindings
+        ];
+        return $this;
+    }
+
+    public function inRandomOrder($isRand = true)
+    {
+        $this->__inRandomOrder = $isRand?true:false;
+        return $this;
+    }
+
+    /* ******************************************************************************** */
+    /* ******************************************************************************** */
+    /* ******************************************************************************** */
+
+    /**
+     * 初始化参数
+     */
+    private function initParameter() {
+        $this->__cache = true;
+        $this->__cacheKeyname = null;
+        $this->__cacheMinutes = 1;
+        $this->__removeCache = false;
+        //
+        $this->__join = [];
+        $this->__take = [];
+        $this->__where = [];
+        $this->__whereRaw = [];
+        $this->__whereIn = [];
+        $this->__select = [];
+        $this->__selectRaw = [];
+        $this->__orderBy = [];
+        $this->__orderByRaw = [];
+        $this->__inRandomOrder = false;
+    }
+
+    /**
+     * 获取缓存标识
+     * @param string $type      查询方式
+     * @param string $attach    附加标识
+     * @return string
+     */
+    private function identify($type, $attach = '') {
+        if ($this->__cacheKeyname) {
+            return $this->__cacheKeyname;
+        }
+        //
+        $identify = $this->addEncode($this->attributes);
+        $identify.= $this->addEncode($this->__join);
+        $identify.= $this->addEncode($this->__take);
+        $identify.= $this->addEncode($this->__where);
+        $identify.= $this->addEncode($this->__whereRaw);
+        $identify.= $this->addEncode($this->__whereIn);
+        $identify.= $this->addEncode($this->__select);
+        $identify.= $this->addEncode($this->__selectRaw);
+        $identify.= $this->addEncode($this->__orderBy);
+        $identify.= $this->addEncode($this->__orderByRaw);
+        $identify.= $this->addEncode($this->__inRandomOrder);
+        $identify.= $this->addEncode($attach);
+        //
+        return 'DBCache:' . $this->table . ':' . $type . '::' . md5($identify);
+    }
+
+    private function addEncode($value)
+    {
+        $encodeName = '';
+        if (is_array($value)) {
+            sort($value);
+            foreach ($value AS $key => $val) {
+                $encodeName .= ':' . $key . '=' . $this->addEncode($val) . ';';
+            }
+        } elseif ($value instanceof Closure) {
+            $join = new DBClause();
+            call_user_func($value, $join);
+            $encodeName .= ':' . $join->toString() . ';';
+        } elseif (is_string($value) || is_numeric($value)) {
+            $encodeName .= ':' . $value . ';';
+        } else {
+            $encodeName .= ':' . var_export($value, true) . ';';
+        }
+        return $encodeName;
+    }
+
+    /**
+     * 创建对象
+     * @return $this|DOModel|null
+     */
+    private function builder() {
+        if ($this->builder === null) {
+            $this->builder = new DOModel($this->table, $this->attributes);
+        }
+        $builder = $this->builder;
+        //
+        foreach ($this->__join AS $item) {
+            $builder = $builder->join($item[0], $item[1], $item[2], $item[3], $item[4], $item[5]);
+        }
+        foreach ($this->__take AS $item) {
+            $builder = $builder->take($item);
+        }
+        foreach ($this->__where AS $item) {
+            $builder = $builder->where($item[0], $item[1], $item[2], $item[3]);
+        }
+        foreach ($this->__whereRaw AS $item) {
+            $builder = $builder->whereRaw($item[0], $item[1], $item[2]);
+        }
+        foreach ($this->__whereIn AS $item) {
+            $builder = $builder->whereIn($item[0], $item[1], $item[2], $item[3]);
+        }
+        foreach ($this->__select AS $item) {
+            $builder = $builder->select($item);
+        }
+        foreach ($this->__selectRaw AS $item) {
+            $builder = $builder->selectRaw($item[0], $item[1]);
+        }
+        foreach ($this->__orderBy AS $item) {
+            $builder = $builder->orderBy($item[0], $item[1]);
+        }
+        foreach ($this->__orderByRaw AS $item) {
+            $builder = $builder->orderByRaw($item[0], $item[1]);
+        }
+        if ($this->__inRandomOrder) {
+            $builder = $builder->inRandomOrder();
+        }
+        //
+        $this->initParameter();
+        return $builder;
+    }
+
+    /* ******************************************************************************** */
+    /* ******************************************************************************** */
+    /* ******************************************************************************** */
+
+    /**
+     * 静态方法
+     *
+     * @param string $tabel
+     * @return DBCache
+     */
+    public static function table($tabel = '')
+    {
+        return new DBCache($tabel);
+    }
+
+    /**
+     * 获取一条数据
+     *
+     * @param array $columns
+     * @return mixed
+     */
+    public function first($columns = ['*'])
+    {
+        if ($this->__cache) {
+            $cacheKey = $this->identify('first', $columns);
+            if ($this->__removeCache) {
+                return $this->forgetCache($cacheKey);
+            }
+            $result = Cache::remember($cacheKey, $this->__cacheMinutes, function() use ($columns) {
+                return $this->builder()->first($columns);
+            });
+        }else{
+            $result = $this->builder()->first($columns);
+        }
+        return isset($result->original)?$result->original:null;
+    }
+
+    /**
+     * 获取所有数据
+     *
+     * @param array $columns
+     * @return array|bool
+     */
+    public function get($columns = ['*'])
+    {
+        if ($this->__cache) {
+            $cacheKey = $this->identify('get', $columns);
+            if ($this->__removeCache) {
+                return $this->forgetCache($cacheKey);
+            }
+            $result = Cache::remember($cacheKey, $this->__cacheMinutes, function() use ($columns) {
+                return $this->builder()->get($columns);
+            });
+        }else{
+            $result = $this->builder()->get($columns);
+        }
+        //
+        $array = [];
+        foreach ($result AS $key=>$item) {
+            $array[$key] = isset($item->original)?$item->original:null;
+        }
+        return $array;
+    }
+
+    /**
+     * 查询结果的计数
+     *
+     * @param string $columns
+     * @return int|bool
+     */
+    public function count($columns = '*')
+    {
+        if ($this->__cache) {
+            $cacheKey = $this->identify('count', $columns);
+            if ($this->__removeCache) {
+                return $this->forgetCache($cacheKey);
+            }
+            $result = Cache::remember($cacheKey, $this->__cacheMinutes, function() use ($columns) {
+                return $this->builder()->count($columns);
+            });
+        }else{
+            $result = $this->builder()->count($columns);
+        }
+        return intval($result);
+    }
+
+    /**
+     * 从查询的第一个结果中获得一个列的值
+     *
+     * @param $column
+     * @return mixed
+     */
+    public function value($column)
+    {
+        if ($this->__cache) {
+            $cacheKey = $this->identify('value', $column);
+            if ($this->__removeCache) {
+                return $this->forgetCache($cacheKey);
+            }
+            $result = Cache::remember($cacheKey, $this->__cacheMinutes, function() use ($column) {
+                $value = $this->builder()->value($column);
+                return $value ? $value : '';
+            });
+        }else{
+            $result = $this->builder()->value($column);
+        }
+        return $result;
+    }
+
+    /**
+     * 统计输出
+     *
+     * @param $column
+     * @return bool|mixed
+     */
+    public function sum($column)
+    {
+        if ($this->__cache) {
+            $cacheKey = $this->identify('sum', $column);
+            if ($this->__removeCache) {
+                return $this->forgetCache($cacheKey);
+            }
+            $result = Cache::remember($cacheKey, $this->__cacheMinutes, function() use ($column) {
+                $sum = $this->builder()->sum($column);
+                return $sum ? $sum : 0;
+            });
+        }else{
+            $result = $this->builder()->sum($column);
+        }
+        return $result;
+    }
+
+    /**
+     * 获取分页数据
+     * @param null $perPage
+     * @param array $columns
+     * @param string $pageName
+     * @param null $page
+     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|mixed
+     */
+    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
+    {
+        if ($this->__cache) {
+            $attach = $this->addEncode($perPage);
+            $attach.= $this->addEncode($columns);
+            $attach.= $this->addEncode($pageName);
+            $attach.= $this->addEncode(Paginator::resolveCurrentPage($pageName));
+            $cacheKey = $this->identify('paginate', $attach);
+            if ($this->__removeCache) {
+                return $this->forgetCache($cacheKey);
+            }
+            $result = Cache::remember($cacheKey, $this->__cacheMinutes, function() use ($perPage, $columns, $pageName, $page) {
+                return $this->builder()->paginate($perPage, $columns, $pageName, $page);
+            });
+        }else{
+            $result = $this->builder()->paginate($perPage, $columns, $pageName, $page);
+        }
+        $array = [];
+        foreach ($result AS $key=>$item) {
+            $array[$key] = isset($item->original)?$item->original:null;
+        }
+        return [
+            "currentPage" => $result->currentPage(),
+            "firstItem" => $result->firstItem(),
+            "hasMorePages" => $result->hasMorePages(),
+            "lastItem" => $result->lastItem(),
+            "lastPage" => $result->lastPage(),
+            "nextPageUrl" => $result->nextPageUrl(),
+            "previousPageUrl" => $result->previousPageUrl(),
+            "perPage" => $result->perPage(),
+            "total" => $result->total(),
+            "lists" => $array,
+        ];
+    }
+}

+ 55 - 0
app/Model/DBClause.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Model;
+
+
+use Closure;
+
+class DBClause
+{
+    private $identify;
+
+    public function __construct()
+    {
+        $this->identify = "";
+    }
+
+    public function on($first, $operator = null, $second = null, $boolean = 'and')
+    {
+        $identify = $this->addEncode($first);
+        $identify.= $this->addEncode($operator);
+        $identify.= $this->addEncode($second);
+        $identify.= $this->addEncode($boolean);
+        $this->identify.= $identify;
+    }
+
+    public function orOn($first, $operator = null, $second = null)
+    {
+        $this->on($first, $operator, $second, 'or');
+    }
+
+    public function toString()
+    {
+        return $this->identify;
+    }
+
+    private function addEncode($value)
+    {
+        $encodeName = '';
+        if (is_array($value)) {
+            ksort($value);
+            foreach ($value AS $key => $val) {
+                $encodeName .= ':' . $key . '=' . $this->addEncode($val) . ';';
+            }
+        } elseif ($value instanceof Closure) {
+            $join = new DBClause();
+            call_user_func($value, $join);
+            $encodeName .= ':' . $join->toString() . ';';
+        } elseif (is_string($value) || is_numeric($value)) {
+            $encodeName .= ':' . $value . ';';
+        } else {
+            $encodeName .= ':' . var_export($value, true) . ';';
+        }
+        return $encodeName;
+    }
+}

+ 32 - 0
app/Model/DOModel.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Model;
+
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * Class Model
+ * @package App\Model
+ */
+class DOModel extends Model
+{
+
+    public $original = [];
+
+    public $timestamps = false;
+
+    public function __construct($tabel = null, array $attributes = [])
+    {
+        parent::__construct($attributes);
+        //
+        if (is_string($tabel)) {
+            $this->setTable($tabel);
+        }
+    }
+
+    public function setTimestamps($timestamps)
+    {
+        $this->timestamps = $timestamps;
+    }
+
+}

+ 2556 - 0
app/Module/Base.php

@@ -0,0 +1,2556 @@
+<?php
+
+namespace App\Module;
+
+use App\Model\DBCache;
+use Cache;
+use DB;
+use Exception;
+use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Redirect;
+use Request;
+use Storage;
+
+class Base
+{
+
+    /**
+     * 获取版本号
+     * @return string
+     */
+    public static function getVersion()
+    {
+        return Cache::remember("Base::version", now()->addSeconds(10), function () {
+            $file = base_path('package.json');
+            if (file_exists($file)) {
+                $packageArray = json_decode(file_get_contents($file), true);
+                return isset($packageArray['version']) ? $packageArray['version'] : '1.0.0';
+            }
+            return '1.0.0';
+        });
+    }
+
+    /**
+     * 获取数组或对象值
+     * @param $obj
+     * @param string $key
+     * @param string $default
+     * @return string
+     */
+    public static function val($obj, $key = '', $default = '')
+    {
+        if (is_object($obj)) $obj = Base::object2array($obj);
+        if (is_int($key)) {
+            if (isset($obj[$key])){
+                $obj = $obj[$key];
+            }else{
+                $obj = "";
+            }
+        }elseif (!empty($key)){
+            $arr = explode(".", str_replace("|", ".", $key));
+            foreach ($arr as $val){
+                if (isset($obj[$val])){
+                    $obj = $obj[$val];
+                }else{
+                    $obj = ""; break;
+                }
+            }
+        }
+        if ($default && empty($obj)) $obj = $default;
+        return $obj;
+    }
+
+    /**
+     * 获取当前uri
+     * @return string
+     */
+    public static function getUrl()
+    {
+        return Request::getRequestUri();
+    }
+
+    /**
+     * 跳转
+     * @param null $url
+     * @return mixed
+     */
+    public static function goUrl($url = null)
+    {
+        if (empty($url)) {
+            $url = Base::getUrl();
+        }
+        return Redirect::to($url, 301);
+    }
+
+    /**
+     * 默认显示
+     * @param $str
+     * @param $val
+     * @param $default
+     * @return mixed
+     */
+    public static function nullShow($str, $val, $default = '')
+    {
+        return $str ? ($default ? $default : $str) : $val;
+    }
+
+    /**
+     * 补零
+     * @param $str
+     * @param int $length       长度
+     * @param bool $before      是否补在前面
+     * @return string
+     */
+    public static function zeroFill($str, $length = 0, $before = true)
+    {
+        if (strlen($str) >= $length) {
+            return $str;
+        }
+        $_str = '';
+        for ($i = 0; $i < $length; $i++) {
+            $_str .= '0';
+        }
+        if ($before) {
+            $_ret = substr($_str . $str, $length * -1);
+        } else {
+            $_ret = substr($str . $_str, 0, $length);
+        }
+        return $_ret;
+    }
+
+    /**
+     * 新建目录
+     * @param $path
+     * @return mixed
+     */
+    public static function makeDir($path)
+    {
+        try{
+            Storage::makeDirectory($path);
+        } catch (Exception $e) {}
+        if (!file_exists($path)){
+            self::makeDir(dirname($path));
+            @mkdir($path, 0777);
+            @chmod($path, 0777);
+        }
+        return $path;
+    }
+
+    /**
+     * 删除目录
+     * @param $path
+     */
+    public static function deleteDir($path)
+    {
+        Storage::deleteDirectory($path);
+    }
+
+    /**
+     * 删除目录及目录下所有的文件
+     * @param $dirName
+     * @param bool $undeleteDir 不删除目录(只删除文件)
+     */
+    public static function deleteDirAndFile($dirName, $undeleteDir = false)
+    {
+        if ($handle = opendir($dirName)) {
+            while (false !== ($item = readdir($handle))) {
+                if ($item != "." && $item != "..") {
+                    if (is_dir($dirName . "/" . $item)) {
+                        self::deleteDirAndFile($dirName . "/" . $item);
+                    } else {
+                        @unlink($dirName . "/" . $item);
+                    }
+                }
+            }
+            closedir($handle);
+            if ($undeleteDir === false) {
+                rmdir($dirName);
+            }
+        }
+    }
+
+    /**
+     * 去除html
+     * @param $text
+     * @param int $length
+     * @return mixed|string
+     */
+    public static function getHtml($text, $length = 255)
+    {
+        $text = Base::cutStr(strip_tags($text), $length, 0, "...");
+        return $text;
+    }
+
+    /**
+     *
+     * 截取字符串
+     * @param string $string 字符串
+     * @param int $length 截取长度
+     * @param int $start 何处开始
+     * @param string $dot 超出尾部添加
+     * @param string $charset 默认编码
+     * @return mixed|string
+     */
+    public static function cutStr($string, $length, $start = 0, $dot = '', $charset = 'utf-8')
+    {
+        if (strtolower($charset) == 'utf-8') {
+            if (Base::getStrlen($string) <= $length) return $string;
+            $strcut = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), array('&', '"', '<', '>'), $string);
+            $strcut = Base::utf8Substr($strcut, $length, $start);
+            $strcut = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);
+            return $strcut . $dot;
+        } else {
+            $length = $length * 2;
+            if (strlen($string) <= $length) return $string;
+            $string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), array('&', '"', '<', '>'), $string);
+            $strcut = '';
+            for ($i = 0; $i < $length; $i++) {
+                $strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i];
+            }
+            $strcut = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);
+        }
+        return $strcut . $dot;
+    }
+
+    /**
+     * PHP获取字符串中英文混合长度
+     * @param string $str 字符串
+     * @param string $charset 编码
+     * @return float            返回长度,1中文=1位,2英文=1位
+     */
+    public static function getStrlen($str, $charset = 'utf-8')
+    {
+        if (strtolower($charset) == 'utf-8') {
+            $str = iconv('utf-8', 'GBK//IGNORE', $str);
+        }
+        $num = strlen($str);
+        $cnNum = 0;
+        for ($i = 0; $i < $num; $i++) {
+            if (ord(substr($str, $i + 1, 1)) > 127) {
+                $cnNum++;
+                $i++;
+            }
+        }
+        $enNum = $num - ($cnNum * 2);
+        $number = ($enNum / 2) + $cnNum;
+        return ceil($number);
+    }
+
+    /**
+     * PHP截取UTF-8字符串,解决半字符问题。
+     * @param string $str 源字符串
+     * @param int $len 左边的子串的长度
+     * @param int $start 何处开始
+     * @return string           取出的字符串, 当$len小于等于0时, 会返回整个字符串
+     */
+    public static function utf8Substr($str, $len, $start = 0)
+    {
+        $len = $len * 2;
+        $new_str = [];
+        for ($i = 0; $i < $len; $i++) {
+            $temp_str = substr($str, 0, 1);
+            if (ord($temp_str) > 127) {
+                $i++;
+                if ($i < $len) {
+                    $new_str[] = substr($str, 0, 3);
+                    $str = substr($str, 3);
+                }
+            } else {
+                $new_str[] = substr($str, 0, 1);
+                $str = substr($str, 1);
+            }
+        }
+        return join(array_slice($new_str, $start));
+    }
+
+    /**
+     * 将字符串转换为数组
+     * @param string    $data 字符串
+     * @param array     $default 为空时返回的默认数组
+     * @return    array    返回数组格式,如果,data为空,则返回$default
+     */
+    public static function string2array($data, $default = [])
+    {
+        if (is_array($data)) {
+            return $data ? $data : $default;
+        }
+        $data = trim($data);
+        if ($data == '') return $default;
+        if (strpos(strtolower($data), 'array') === 0 && strtolower($data) !== 'array') {
+            @ini_set('display_errors', 'on');
+            @eval("\$array = $data;");
+            @ini_set('display_errors', 'off');
+        } else {
+            if (strpos($data, '{\\') === 0) {
+                $data = stripslashes($data);
+            }
+            $array = json_decode($data, true);
+        }
+        return isset($array) && is_array($array) && $data ? $array : $default;
+    }
+
+    /**
+     * 将数组转换为字符串
+     * @param    array $data 数组
+     * @param    int $isformdata 如果为0,则不使用new_stripslashes处理,可选参数,默认为1
+     * @return    string    返回字符串,如果,data为空,则返回空
+     */
+    public static function array2string($data, $isformdata = 1)
+    {
+        if ($data == '' || empty($data)) return '';
+        if ($isformdata) $data = Base::newStripslashes($data);
+        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+            return Base::newAddslashes(json_encode($data));
+        } else {
+            return Base::newAddslashes(json_encode($data, JSON_FORCE_OBJECT));
+        }
+    }
+
+    /**
+     * 将数组转换为字符串 (格式化)
+     * @param    array $data 数组
+     * @param    int $isformdata 如果为0,则不使用new_stripslashes处理,可选参数,默认为1
+     * @return    string    返回字符串,如果,data为空,则返回空
+     */
+    public static function array2string_discard($data, $isformdata = 1)
+    {
+        if ($data == '' || empty($data)) return '';
+        if ($isformdata) $data = Base::newStripslashes($data);
+        return var_export($data, TRUE);
+    }
+
+    /**
+     * json字符串转换成array
+     * @param $string
+     * @return array|mixed
+     */
+    public static function json2array($string)
+    {
+        if (is_array($string)) {
+            return $string;
+        }
+        try {
+            return json_decode($string, true);
+        } catch (Exception $e) {
+            return [];
+        }
+    }
+
+    /**
+     * array转换成功json字符串
+     * @param $array
+     * @return string
+     */
+    public static function array2json($array)
+    {
+        if (!is_array($array)) {
+            return $array;
+        }
+        try {
+            return json_encode($array);
+        } catch (Exception $e) {
+            return '';
+        }
+    }
+
+    /**
+     * 叠加数组或对象
+     * @param object|array $array
+     * @param array $over
+     * @return object|array
+     */
+    public static function array_over(&$array, $over = [])
+    {
+        if (is_array($over)) {
+            foreach ($over AS $key=>$val) {
+                if (is_array($array)) {
+                    $array[$key] = $val;
+                }
+                if (is_object($array)) {
+                    $array->$key = $val;
+                }
+            }
+        }
+        return $array;
+    }
+
+    /**
+     * 获取数组第一个值
+     * @param $array
+     * @return mixed
+     */
+    public static function arrayFirst($array)
+    {
+        $val = '';
+        if (is_array($array)) {
+            foreach ($array AS $item) {
+                $val = $item;
+                break;
+            }
+        }
+        return $val;
+    }
+
+    /**
+     * 获取数组最后一个值
+     * @param $array
+     * @return mixed
+     */
+    public static function arrayLast($array)
+    {
+        $val = '';
+        if (is_array($array)) {
+            foreach (array_reverse($array) AS $item) {
+                $val = $item;
+                break;
+            }
+        }
+        return $val;
+    }
+
+    /**
+     * 数组指定值作为数组键
+     * @param $array
+     * @param $valkey
+     * @return array
+     */
+    public static function arrayValkey($array, $valkey)
+    {
+        self::coll2array($array);
+        if (is_array($array)) {
+            $items = [];
+            foreach ($array AS $item) {
+                $items[$item[$valkey]] = $item;
+            }
+            $array = $items;
+        }
+        return $array;
+    }
+
+    /**
+     * 对象转数组
+     * @param $array
+     * @return array
+     */
+    public static function object2array(&$array)
+    {
+        if (is_object($array)) {
+            $array = (array)$array;
+        }
+        if (is_array($array)) {
+            foreach ($array as $key => $value) {
+                $array[$key] = Base::object2array($value);
+            }
+        }
+        return $array;
+    }
+
+    /**
+     * 数据库返回对象转数组
+     * @param $array
+     * @return array
+     */
+    public static function coll2array(&$array)
+    {
+        if (is_object($array) && $array) {
+            $obj = $array;
+            $array = [];
+            foreach ($obj AS $key=>$item) {
+                $array[$key] = $item;
+            }
+            Base::object2array($array);
+        }
+        return $array;
+    }
+
+    /**
+     * 数据库返回对象转数组
+     * @param $array
+     * @return array
+     */
+    public static function DBC2A($array)
+    {
+        return Base::coll2array($array);
+    }
+
+    /**
+     * 数据库自更新数组
+     * @param $array
+     * @return array|\Illuminate\Database\Query\Expression
+     */
+    public static function DBUP($array) {
+        if (is_array($array)) {
+            foreach ($array AS $key => $val) {
+                $array[$key] = DB::raw(Base::DBRAW($key . ($val < 0 ? '-' : '+') . abs($val)));
+            }
+        } else {
+            $array = DB::raw(Base::DBRAW($array));
+        }
+        return $array;
+    }
+
+    /**
+     * 数据库更新或插入
+     * @param $builder
+     * @param $where
+     * @param $update
+     * @param array $insert
+     * @return bool
+     */
+    public static function DBUPIN($builder, $where, $update, $insert = [])
+    {
+        if (is_string($builder)) {
+            $builder = DB::table($builder);
+        }
+        if (!$builder->where($where)->exists()) {
+            return $builder->insert(array_merge($where, $insert));
+        }
+        return (bool)$builder->take(1)->update($update);
+    }
+
+    /**
+     * 处理数据库原生符号
+     * @param string $value
+     * @return mixed
+     */
+    public static function DBRAW($value = '')
+    {
+        if (env('DB_CONNECTION') === 'pgsql') {
+            $value = str_replace("`", "\"", $value);
+        }
+        return $value;
+    }
+
+    /**
+     * array转xml
+     * @param $data
+     * @param string $root 根节点
+     * @return string
+     */
+    public static function array2xml($data, $root = '<xml>'){
+        $str = "";
+        if ($root) $str .= $root;
+        foreach ($data as $key => $val) {
+            if (is_array($val)) {
+                $child = self::array2xml($val, false);
+                $str .= "<$key>$child</$key>";
+            } else {
+                $str .= "<$key><![CDATA[$val]]></$key>";
+            }
+        }
+        if ($root) $str .= '</xml>';
+        return $str;
+    }
+
+    /**
+     * xml转json
+     * @param string $source 传的是文件,还是xml的string的判断
+     * @return string
+     */
+    public static function xml2json($source)
+    {
+        if (is_file($source)) {
+            $xml_array = @simplexml_load_file($source);
+        } else {
+            $xml_array = @simplexml_load_string($source, NULL, LIBXML_NOCDATA);
+        }
+        return json_encode($xml_array);
+    }
+
+    /**
+     * 返回经stripslashes处理过的字符串或数组
+     * @param array|string $string 需要处理的字符串或数组
+     * @return mixed
+     */
+    public static function newStripslashes($string)
+    {
+        if (is_numeric($string)) {
+            return $string;
+        }elseif (!is_array($string)) {
+            return stripslashes($string);
+        }
+        foreach ($string as $key => $val) $string[$key] = Base::newStripslashes($val);
+        return $string;
+    }
+
+    /**
+     * 返回经addslashes处理过的字符串或数组
+     * @param array|string $string 需要处理的字符串或数组
+     * @return mixed
+     */
+    public static function newAddslashes($string)
+    {
+        if (is_numeric($string)) {
+            return $string;
+        }elseif (!is_array($string)) {
+            return addslashes($string);
+        }
+        foreach ($string as $key => $val) $string[$key] = Base::newAddslashes($val);
+        return $string;
+    }
+
+    /**
+     * 返回经trim处理过的字符串或数组
+     * @param $string
+     * @return array|string
+     */
+    public static function newTrim($string)
+    {
+        if (!is_array($string)) return trim($string);
+        foreach ($string as $key => $val) $string[$key] = Base::newTrim($val);
+        return $string;
+    }
+
+    /**
+     * 返回经intval处理过的字符串或数组
+     * @param $string
+     * @return array|string
+     */
+    public static function newIntval($string)
+    {
+        if (!is_array($string)) return intval($string);
+        foreach ($string as $key => $val) $string[$key] = Base::newIntval($val);
+        return $string;
+    }
+
+    /**
+     * 重MD5加密
+     * @param $text
+     * @param string $pass
+     * @return string
+     */
+    public static function md52($text, $pass = '')
+    {
+        $_text = md5($text) . $pass;
+        return md5($_text);
+    }
+
+    /**
+     * 随机字符串
+     * @param int $length 随机字符长度
+     * @param string $type
+     * @return string 1数字、2大小写字母、21小写字母、22大写字母、默认全部;
+     */
+    public static function generatePassword($length = 8, $type = '')
+    {
+        // 密码字符集,可任意添加你需要的字符
+        switch ($type) {
+            case '1':
+                $chars = '0123456789';
+                break;
+            case '2':
+                $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+                break;
+            case '21':
+                $chars = 'abcdefghijklmnopqrstuvwxyz';
+                break;
+            case '22':
+                $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+                break;
+            default:
+                $chars = $type ? $type : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+                break;
+        }
+        $passwordstr = '';
+        $max = strlen($chars) - 1;
+        for ($i = 0; $i < $length; $i++) {
+            $passwordstr .= $chars[mt_rand(0, $max)];
+        }
+        return $passwordstr;
+    }
+
+    /**
+     * 同 generate_password 默认获取纯数字
+     * @param $length
+     * @param string $chars
+     * @return string
+     */
+    public static function strRandom($length, $chars = '0123456789')
+    {
+        return Base::generatePassword($length, $chars);
+    }
+
+    /**
+     * 判断两个地址域名是否相同
+     * @param string $var1
+     * @param string $var2
+     * @return bool
+     */
+    public static function hostContrast($var1, $var2)
+    {
+        $arr1 = parse_url($var1);
+        $arr2 = parse_url($var2);
+        //
+        $host1 = $var1;
+        if (isset($arr1['host'])) {
+            $host1 = $arr1['host'];
+        }
+        //
+        $host2 = $var2;
+        if (isset($arr2['host'])) {
+            $host2 = $arr2['host'];
+        }
+        return $host1== $host2;
+    }
+
+    /**
+     * 获取url域名
+     * @param string $var
+     * @return mixed
+     */
+    public static function getHost($var = '')
+    {
+        if (empty($var)) {
+            $var = url("/");
+        }
+        $arr = parse_url($var);
+        return $arr['host'];
+    }
+
+    /**
+     * 相对路径补全
+     * @param string|array $str
+     * @return string
+     */
+    public static function fillUrl($str = '')
+    {
+        if (is_array($str)) {
+            foreach ($str AS $key=>$item) {
+                $str[$key] = Base::fillUrl($item);
+            }
+            return $str;
+        }
+        if (empty($str)) {
+            return $str;
+        }
+        if (substr($str, 0, 2) == "//" ||
+            substr($str, 0, 7) == "http://" ||
+            substr($str, 0, 8) == "https://" ||
+            substr($str, 0, 6) == "ftp://" ||
+            substr($str, 0, 1) == "/" ||
+            substr(str_replace(' ', '', $str), 0, 11) == "data:image/"
+        ) {
+            return $str;
+        } else {
+            return url($str);
+        }
+    }
+
+    /**
+     * 反 fillUrl
+     * @param string $str
+     * @return array|string
+     */
+    public static function unFillUrl($str = '')
+    {
+        if (is_array($str)) {
+            foreach ($str AS $key=>$item) {
+                $str[$key] = Base::unFillUrl($item);
+            }
+            return $str;
+        }
+        return Base::leftDelete($str, url('') . '/');
+    }
+
+    /**
+     * 格式化内容图片地址
+     * @param $content
+     * @return mixed
+     */
+    public static function formatContentImg($content)
+    {
+        $pattern = '/<img(.*?)src=("|\')(.*?)\2/is';
+        if (preg_match($pattern, $content)) {
+            preg_match_all($pattern, $content, $matchs);
+            foreach ($matchs[3] AS $index => $value) {
+                if (!(substr($value, 0, 7) == "http://" ||
+                    substr($value, 0, 8) == "https://" ||
+                    substr($value, 0, 6) == "ftp://" ||
+                    substr(str_replace(' ', '', $value), 0, 11) == "data:image/"
+                )) {
+                    if (substr($value, 0, 2) == "//") {
+                        $value = "http:" . $value;
+                    }elseif (substr($value, 0, 1) == "/") {
+                        $value = substr($value, 1);
+                    }
+                    $newValue = "<img" . $matchs[1][$index] . "src=" . $matchs[2][$index] . self::fillUrl($value) . $matchs[2][$index];
+                    $content = str_replace($matchs[0][$index], $newValue, $content);
+                }
+            }
+        }
+        return $content;
+    }
+
+    /**
+     * 打散字符串,只留为数字的项
+     * @param $delimiter
+     * @param $string
+     * @return array
+     */
+    public static function explodeInt($delimiter, $string)
+    {
+        $array = is_array($string) ? $string : explode($delimiter, $string);
+        foreach ($array AS $k => $v) {
+            if (!is_numeric($v)) {
+                unset($array[$k]);
+            }
+        }
+        return array_values($array);
+    }
+
+    /**
+     * 检测日期格式
+     * @param string $str 需要检测的字符串
+     * @return bool
+     */
+    public static function isDate($str)
+    {
+        $strArr = explode('-', $str);
+        if (empty($strArr) || count($strArr) != 3) {
+            return false;
+        } else {
+            list($year, $month, $day) = $strArr;
+            if (checkdate($month, $day, $year)) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * 检测时间格式
+     * @param string $str 需要检测的字符串
+     * @return bool
+     */
+    public static function isTime($str)
+    {
+        $strArr = explode(':', $str);
+        if (empty($strArr) || count($strArr) != 2) {
+            return false;
+        } else {
+            list($hour, $minute) = $strArr;
+            if (intval($hour) > 23 || intval($minute) > 59) {
+                return false;
+            } else {
+                return true;
+            }
+        }
+    }
+
+    /**
+     * 检测手机号码格式
+     * @param string $str   需要检测的字符串
+     * @return bool
+     */
+    public static function isMobile($str)
+    {
+        if (preg_match("/^1([3456789])\d{9}$/", $str)) {
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    /**
+     * 检测邮箱格式
+     * @param string $str 需要检测的字符串
+     * @return int
+     */
+    public static function isMail($str)
+    {
+        $RegExp = '/^[a-z0-9][a-z\.0-9-_]+@[a-z0-9_-]+(?:\.[a-z]{0,3}\.[a-z]{0,2}|\.[a-z]{0,3}|\.[a-z]{0,2})$/i';
+        return preg_match($RegExp, $str);
+    }
+
+    /**
+     * 正则判断是否纯数字
+     * @param $str
+     * @return bool
+     */
+    public static function isNumber($str)
+    {
+        if (preg_match("/^\d*$/", $str)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 判断身份证是否正确
+     * @param $id
+     * @return bool
+     */
+    public static function isIdcard($id)
+    {
+        $id = strtoupper($id);
+        $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
+        $arr_split = array();
+        if(!preg_match($regx, $id)) {
+            return FALSE;
+        }
+        if(15==strlen($id)) {
+            //检查15位
+            $regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";
+            @preg_match($regx, $id, $arr_split);
+            //检查生日日期是否正确
+            $dtm_birth = "19".$arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
+            if(!strtotime($dtm_birth)) {
+                return FALSE;
+            } else {
+                return TRUE;
+            }
+        } else {
+            //检查18位
+            $regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
+            @preg_match($regx, $id, $arr_split);
+            $dtm_birth = $arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
+            //检查生日日期是否正确
+            if(!strtotime($dtm_birth)) {
+                return FALSE;
+            } else {
+                //检验18位身份证的校验码是否正确。
+                //校验位按照ISO 7064:1983.MOD 11-2的规定生成,X可以认为是数字10。
+                $arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
+                $arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
+                $sign = 0;
+                for ( $i = 0; $i < 17; $i++ ) {
+                    $b = (int) $id[$i];
+                    $w = $arr_int[$i];
+                    $sign += $b * $w;
+                }
+                $n = $sign % 11;
+                $val_num = $arr_ch[$n];
+                if ($val_num != substr($id,17, 1)) {
+                    return FALSE;
+                } else {
+                    return TRUE;
+                }
+            }
+        }
+    }
+
+    /**
+     * 阵列数组
+     * @param $keys
+     * @param $src
+     * @param bool $default
+     * @return array
+     */
+    public static function arrayElements($keys, $src, $default = FALSE)
+    {
+        $return = [];
+        if (!is_array($keys)) {
+            $keys = array($keys);
+        }
+        foreach ($keys as $key) {
+            if (isset($src[$key])) {
+                $return[$key] = $src[$key];
+            } else {
+                $return[$key] = $default;
+            }
+        }
+        return $return;
+    }
+
+    /**
+     * 判断字符串存在(包含)
+     * @param string $string
+     * @param string $find
+     * @return bool
+     */
+    public static function strExists($string, $find)
+    {
+        if (!is_string($string) || !is_string($find)) {
+            return false;
+        }
+        return !(strpos($string, $find) === FALSE);
+    }
+
+    /**
+     * 判断字符串开头包含
+     * @param string $string //原字符串
+     * @param string $find //判断字符串
+     * @param bool|false $lower //是否不区分大小写
+     * @return int
+     */
+    public static function leftExists($string, $find, $lower = false)
+    {
+        if (!is_string($string) || !is_string($find)) {
+            return false;
+        }
+        if ($lower) {
+            $string = strtolower($string);
+            $find = strtolower($find);
+        }
+        return (substr($string, 0, strlen($find)) == $find);
+    }
+
+    /**
+     * 判断字符串结尾包含
+     * @param string $string //原字符串
+     * @param string $find //判断字符串
+     * @param bool|false $lower //是否不区分大小写
+     * @return int
+     */
+    public static function rightExists($string, $find, $lower = false)
+    {
+        if (!is_string($string) || !is_string($find)) {
+            return false;
+        }
+        if ($lower) {
+            $string = strtolower($string);
+            $find = strtolower($find);
+        }
+        return (substr($string, strlen($find) * -1) == $find);
+    }
+
+    /**
+     * 删除开头指定字符串
+     * @param $string
+     * @param $find
+     * @param bool $lower
+     * @return string
+     */
+    public static function leftDelete($string, $find, $lower = false)
+    {
+        if (Base::leftExists($string, $find, $lower)) {
+            $string = substr($string, strlen($find));
+        }
+        return $string ? $string : '';
+    }
+
+    /**
+     * 删除结尾指定字符串
+     * @param $string
+     * @param $find
+     * @param bool $lower
+     * @return string
+     */
+    public static function rightDelete($string, $find, $lower = false)
+    {
+        if (Base::rightExists($string, $find, $lower)) {
+            $string = substr($string, 0, strlen($find) * -1);
+        }
+        return $string;
+    }
+
+    /**
+     * 截取指定字符串
+     * @param $str
+     * @param string $ta
+     * @param string $tb
+     * @return string
+     */
+    public static function getMiddle($str, $ta = '', $tb = ''){
+        if ($ta && strpos($str, $ta) !== false){
+            $str = substr($str, strpos($str, $ta) + strlen($ta));
+        }
+        if ($tb && strpos($str, $tb) !== false){
+            $str = substr($str, 0, strpos($str, $tb));
+        }
+        return $str;
+    }
+
+    /**
+     * 自定义替换次数
+     * @param $search
+     * @param $replace
+     * @param $subject
+     * @param int $limit
+     * @return string|string[]|null
+     */
+    public static function strReplaceLimit($search, $replace, $subject, $limit = -1)
+    {
+        if (is_array($search)) {
+            foreach ($search as $k => $v) {
+                $search[$k] = '`' . preg_quote($search[$k], '`') . '`';
+            }
+        } else {
+            $search = '`' . preg_quote($search, '`') . '`';
+        }
+        return preg_replace($search, $replace, $subject, $limit);
+    }
+
+    /**
+     * 获取或设置
+     * @param $setname          //配置名称
+     * @param bool $array       //保存内容
+     * @param bool $isCache     //读取缓存
+     * @return array
+     */
+    public static function setting($setname, $array = false, $isCache = false)
+    {
+        global $_A;
+        if (empty($setname)) {
+            return [];
+        }
+        if ($array === false && isset($_A["__static_setting_" . $setname])) {
+            return $_A["__static_setting_" . $setname];
+        }
+        $setting = [];
+        $setrow = DBCache::table('setting')->where('title', $setname)->cache($isCache)->first();
+        if (!empty($setrow)) {
+            $setting = Base::string2array($setrow['setting']);
+        } else {
+            DB::table('setting')->insert(['title' => $setname]);
+        }
+        if ($array !== false) {
+            $setting = $array;
+            DB::table('setting')->where('title', $setname)->update(['setting' => (is_array($array) ? Base::array2string($array) : $array)]);
+            DBCache::table('setting')->where('title', $setname)->removeCache()->first();
+        }
+        $_A["__static_setting_" . $setname] = $setting;
+        return $setting;
+    }
+
+    /**
+     * 获取设置值
+     * @param $setname
+     * @param $keyname
+     * @param $defaultVal
+     * @return mixed
+     */
+    public static function settingFind($setname, $keyname, $defaultVal = '')
+    {
+        $array = Base::setting($setname);
+        return isset($array[$keyname]) ? $array[$keyname] : $defaultVal;
+    }
+
+    /**
+     * 秒 (转) 年、天、时、分、秒
+     * @param $time
+     * @return array|bool
+     */
+    public static function sec2time($time)
+    {
+        if (is_numeric($time)) {
+            $value = array(
+                "years" => 0, "days" => 0, "hours" => 0,
+                "minutes" => 0, "seconds" => 0,
+            );
+            /*
+            if($time >= 31536000){
+                $value["years"] = floor($time/31536000);
+                $time = ($time%31536000);
+            }
+            */
+            if ($time >= 86400) {
+                $value["days"] = floor($time / 86400);
+                $time = ($time % 86400);
+            }
+            if ($time >= 3600) {
+                $value["hours"] = floor($time / 3600);
+                $time = ($time % 3600);
+            }
+            if ($time >= 60) {
+                $value["minutes"] = floor($time / 60);
+                $time = ($time % 60);
+            }
+            $value["seconds"] = floor($time);
+            return (array)$value;
+        } else {
+            return (bool)FALSE;
+        }
+    }
+
+    /**
+     * 年、天、时、分、秒 (转) 秒
+     * @param $value
+     * @return int
+     */
+    public static function time2sec($value)
+    {
+        $time = intval($value["seconds"]);
+        $time += intval($value["minutes"] * 60);
+        $time += intval($value["hours"] * 3600);
+        $time += intval($value["days"] * 86400);
+        $time += intval($value["years"] * 31536000);
+        return $time;
+    }
+
+    /**
+     * 阿拉伯数字转化为中文
+     * @param $num
+     * @return string
+     */
+    public static function chinaNum($num)
+    {
+        $china = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
+        $arr = str_split($num);
+        $txt = '';
+        for ($i = 0; $i < count($arr); $i++) {
+            $txt .= $china[$arr[$i]];
+        }
+        return $txt;
+    }
+
+    /**
+     * 阿拉伯数字转化为中文(用于星期,七改成日)
+     * @param $num
+     * @return string
+     */
+    public static function chinaNumZ($num)
+    {
+        return str_replace("七", "日", Base::chinaNum($num));
+    }
+
+    /**
+     * 获取(时间戳转)今天是星期几,只返回(几)
+     * @param string|number $unixTime
+     * @return string
+     */
+    public static function getTimeWeek($unixTime = '')
+    {
+        $unixTime = is_numeric($unixTime) ? $unixTime : Base::time();
+        $weekarray = ['日', '一', '二', '三', '四', '五', '六'];
+        return $weekarray[date('w', $unixTime)];
+    }
+
+    /**
+     * 获取(时间戳转)现在时间段:深夜、凌晨、早晨、上午.....
+     * @param string|number $unixTime
+     * @return string
+     */
+    public static function getTimeDayeSegment($unixTime = '')
+    {
+        $unixTime = is_numeric($unixTime) ? $unixTime : Base::time();
+        $H = date('H', $unixTime);
+        if ($H >= 19) {
+            return '晚上';
+        } elseif ($H >= 18) {
+            return '傍晚';
+        } elseif ($H >= 13) {
+            return '下午';
+        } elseif ($H >= 12) {
+            return '中午';
+        } elseif ($H >= 8) {
+            return '上午';
+        } elseif ($H >= 5) {
+            return '早晨';
+        } elseif ($H >= 1) {
+            return '凌晨';
+        } elseif ($H >= 0) {
+            return '深夜';
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     * 国际化(替换国际语言)
+     * @param $val
+     * @return mixed
+     */
+    public static function Lang($val)
+    {
+        $repArray = [];
+        if (is_array($val)) {
+            if (self::strExists($val[0], '%') && count($val) > 1) {
+                $repArray = array_slice($val, 1);
+            }
+            $val = $val[0];
+        }
+        $data = self::langData();
+        if (isset($data[$val]) && $data[$val] !== null) {
+            $val = $data[$val];
+        }
+        if ($repArray) {
+            foreach ($repArray AS $item) {
+                $val = self::strReplaceLimit('%', $item, $val, 1);
+            }
+        }
+        return $val;
+    }
+
+    /**
+     * 加载语言数据
+     * @param bool $refresh
+     * @return array|mixed
+     */
+    public static function langData($refresh = false)
+    {
+        global $_A;
+        if (!isset($_A["__static_langdata"]) || $refresh === true) {
+            $_A["__static_langdata"] = [];
+            $language = trim(Request::header('language'));
+            $langpath = resource_path('lang/' . $language . '/general.php');
+            if (file_exists($langpath)) {
+                $data = include $langpath;
+                if (is_array($data)) {
+                    $_A["__static_langdata"] = $data;
+                }
+            }
+        }
+        return $_A["__static_langdata"];
+    }
+
+    /**
+     * JSON返回
+     * @param $param
+     * @return string
+     */
+    public static function jsonEcho($param)
+    {
+        global $_GPC;
+        //
+        $json = json_encode($param);
+        $callback = $_GPC['callback'];
+        if ($callback) {
+            return $callback . '(' . $json . ')';
+        } else {
+            return $json;
+        }
+    }
+
+    /**
+     * 数组返回 正确
+     * @param $msg
+     * @param array $data
+     * @param int $ret
+     * @return array
+     */
+    public static function retSuccess($msg, $data = [], $ret = 1)
+    {
+        return array(
+            'ret' => $ret,
+            'msg' => self::Lang($msg),
+            'data' => $data
+        );
+    }
+
+    /**
+     * 数组返回 错误
+     * @param $msg
+     * @param array $data
+     * @param int $ret
+     * @return array
+     */
+    public static function retError($msg, $data = [], $ret = 0)
+    {
+        return array(
+            'ret' => $ret,
+            'msg' => self::Lang($msg),
+            'data' => $data
+        );
+    }
+
+    /**
+     * Ajax 错误返回
+     * @param $msg
+     * @param array $data
+     * @param int $ret
+     * @param int $abortCode
+     * @return array|void
+     */
+    public static function ajaxError($msg, $data = [], $ret = 0, $abortCode = 404)
+    {
+        if (Request::input('__Access-Control-Allow-Origin') || Request::header('Content-Type') === 'application/json') {
+            return Base::retError($msg, $data, $ret);
+        }else{
+            return abort($abortCode, $msg);
+        }
+    }
+
+    /**
+     * JSON返回 正确
+     * @param $msg
+     * @param array $data
+     * @param int $ret
+     * @return string
+     */
+    public static function jsonSuccess($msg, $data = [], $ret = 1)
+    {
+        return Base::jsonEcho(Base::retSuccess($msg, $data, $ret));
+    }
+
+    /**
+     * JSON返回 错误
+     * @param $msg
+     * @param array $data
+     * @param int $ret
+     * @return string
+     */
+    public static function jsonError($msg, $data = [], $ret = 0)
+    {
+        return Base::jsonEcho(Base::retError($msg, $data, $ret));
+    }
+
+    /**
+     * 是否错误
+     * @param $param
+     * @return bool
+     */
+    public static function isError($param)
+    {
+        return intval($param['ret']) <= 0;
+    }
+
+    /**
+     * 异常模板
+     * @param $msg
+     * @param bool $catch
+     * @return bool
+     */
+    public static function Exce($msg, $catch = false)
+    {
+        if ($catch === false) {
+            return "{{ExceMsg:".$msg.":ExceMsg}}";
+        }else{
+            if (Base::strExists($msg . "", "{{ExceMsg:") && Base::strExists($msg . "", ":ExceMsg}}")) {
+                $msg = Base::getMiddle($msg, "{{ExceMsg:", ":ExceMsg}}");
+                $catch = $msg?$msg:$catch;
+            }
+            return $catch;
+        }
+    }
+
+    /**
+     * 获取数组的第几个值
+     * @param $arr
+     * @param int $i
+     * @return array
+     */
+    public static function getArray($arr, $i = 1)
+    {
+        $array = [];
+        $j = 1;
+        foreach ($arr AS $item) {
+            $array[] = $item;
+            if ($i >= $j) {
+                break;
+            }
+            $j++;
+        }
+        return $array;
+    }
+
+    /**
+     * 小时转天/小时
+     * @param $hour
+     * @return string
+     */
+    public static function forumHourDay($hour)
+    {
+        $hour = intval($hour);
+        if ($hour > 24) {
+            $day = floor($hour / 24);
+            $hour-= $day * 24;
+            return $day.'天'.$hour.'小时';
+        }
+        return $hour.'小时';
+    }
+
+    /**
+     * 时间格式化
+     * @param $date
+     * @return false|string
+     */
+    public static function forumDate($date)
+    {
+        $dur = time() - $date;
+        if ($date > strtotime(date("Y-m-d"))) {
+            //今天
+            if ($dur < 60) {
+                return max($dur, 1) . '秒前';
+            } elseif ($dur < 3600) {
+                return floor($dur / 60) . '分钟前';
+            } elseif ($dur < 86400) {
+                return floor($dur / 3600) . '小时前';
+            } else {
+                return date("H:i", $date);
+            }
+        } elseif ($date > strtotime(date("Y-m-d", strtotime("-1 day")))) {
+            //昨天
+            return '昨天';
+        } elseif ($date > strtotime(date("Y-m-d", strtotime("-2 day")))) {
+            //前天
+            return '前天';
+        } elseif ($dur > 86400) {
+            //x天前
+            return floor($dur / 86400) . '天前';
+        }
+        return date("Y-m-d", $date);
+    }
+
+    /**
+     * 获取时间戳今天的第一秒时间戳
+     * @param $time
+     * @return false|int
+     */
+    public static function dayTimeF($time)
+    {
+        return strtotime(date("Y-m-d 00:00:00", self::isNumber($time) ? $time : strtotime($time)));
+    }
+
+    /**
+     * 获取时间戳今天的最后一秒时间戳
+     * @param $time
+     * @return false|int
+     */
+    public static function dayTimeE($time)
+    {
+        return strtotime(date("Y-m-d 23:59:59", self::isNumber($time) ? $time : strtotime($time)));
+    }
+
+    /**
+     * 用户名、邮箱、手机账号、银行卡号中间字符串以*隐藏
+     * @param $str
+     * @return mixed|string
+     */
+    public static function cardFormat($str)
+    {
+        if (strpos($str, '@')) {
+            $email_array = explode("@", $str);
+            $prevfix = (strlen($email_array[0]) < 4) ? "" : substr($str, 0, 3); //邮箱前缀
+            $count = 0;
+            $str = preg_replace('/([\d\w+_-]{0,100})@/', '***@', $str, -1, $count);
+            return $prevfix . $str;
+        }
+        if (Base::isMobile($str)) {
+            return substr($str, 0, 3) . "****" . substr($str, -4);
+        }
+        $pattern = '/([\d]{4})([\d]{4})([\d]{4})([\d]{4})([\d]{0,})?/i';
+        if (preg_match($pattern, $str)) {
+            return preg_replace($pattern, '$1 **** **** **** $5', $str);
+        }
+        $pattern = '/([\d]{4})([\d]{4})([\d]{4})([\d]{0,})?/i';
+        if (preg_match($pattern, $str)) {
+            return preg_replace($pattern, '$1 **** **** $4', $str);
+        }
+        $pattern = '/([\d]{4})([\d]{4})([\d]{0,})?/i';
+        if (preg_match($pattern, $str)) {
+            return preg_replace($pattern, '$1 **** $3', $str);
+        }
+        return substr($str, 0, 3) . "***" . substr($str, -1);
+    }
+
+    /**
+     * 数字每4位加一空格
+     * @param $str
+     * @param string $interval
+     * @return string
+     */
+    public static function fourFormat($str, $interval = " ")
+    {
+        if (!is_numeric($str)) return $str;
+        //
+        $text = '';
+        for ($i = 0; $i < strlen($str); $i++) {
+            $text .= $str[$i];
+            if ($i % 4 == 3) {
+                $text .= $interval;
+            }
+        }
+        return $text;
+    }
+
+    /**
+     * 保留两位小数点
+     * @param $str
+     * @param bool $float
+     * @return float
+     */
+    public static function twoFloat($str, $float = false)
+    {
+        $str = sprintf("%.2f", floatval($str));
+        if ($float === true) {
+            $str = floatval($str);
+        }
+        return $str;
+    }
+
+    /**
+     * 获取时间戳
+     * @param bool $refresh
+     * @return int
+     */
+    public static function time($refresh = false)
+    {
+        global $_A;
+        if (!isset($_A["__static_time"]) || $refresh === true) {
+            $_A["__static_time"] = time();
+        }
+        return $_A["__static_time"];
+    }
+
+    /**
+     * 获取毫秒时间戳
+     * @return float
+     */
+    public static function msecTime()
+    {
+        list($msec, $sec) = explode(' ', microtime());
+        $time = explode(".", $sec . ($msec * 1000));
+        return $time[0];
+    }
+
+    /**
+     * 时间差(不够1个小时算一个小时)
+     * @param int $s    开始时间戳
+     * @param int $e    结束时间戳
+     * @return string
+     */
+    public static function timeDiff($s, $e)
+    {
+        $d = $e - $s;
+        if ($d > 86400) {
+            $day = floor($d / 86400);
+            $hour = ceil(($d - ($day * 86400)) / 3600);
+            if ($hour > 0) {
+                return $day . '天' . $hour . '小时';
+            } else {
+                return $day . '天';
+            }
+        } elseif ($d > 3600) {
+            return ceil($d / 3600) . '小时';
+        } elseif ($d > 60) {
+            return ceil($d / 60) . '分钟';
+        } elseif ($d > 1) {
+            return '1分钟内';
+        } else {
+            return '0秒';
+        }
+    }
+
+    /**
+     * 获取IP地址
+     * @return string
+     */
+    public static function getIp()
+    {
+        global $_A;
+        if (!isset($_A["__static_ip"])) {
+            if (getenv('HTTP_CLIENT_IP') and strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
+                $onlineip = getenv('HTTP_CLIENT_IP');
+            } elseif (getenv('HTTP_X_FORWARDED_FOR') and strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
+                $onlineip = getenv('HTTP_X_FORWARDED_FOR');
+            } elseif (getenv('REMOTE_ADDR') and strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
+                $onlineip = getenv('REMOTE_ADDR');
+            } elseif (isset($_SERVER['REMOTE_ADDR']) and $_SERVER['REMOTE_ADDR'] and strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
+                $onlineip = $_SERVER['REMOTE_ADDR'];
+            } elseif (Request::header('X-Real-IP')) {
+                $onlineip = Request::header('X-Real-IP');
+            } else {
+                $onlineip = '0,0,0,0';
+            }
+            preg_match("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/", $onlineip, $match);
+            $_A["__static_ip"] = $match[0] ? $match[0] : 'unknown';
+        }
+        return $_A["__static_ip"];
+    }
+
+    /**
+     * 获取IP地址
+     * @param string $ip
+     * @return array|mixed
+     */
+    public static function getIpInfo($ip = '')
+    {
+        if (empty($ip)) {
+            $ip = self::getIp();
+        }
+        $cacheKey = "getIpInfo::" . md5($ip);
+        $result = Cache::rememberForever($cacheKey, function() use ($ip) {
+            return Ihttp::ihttp_request("http://ip.taobao.com/service/getIpInfo.php?accessKey=alibaba-inc&ip=" . $ip, [], [], 8);
+        });
+        if (Base::isError($result)) {
+            return $result;
+        }
+        $data = json_decode($result['data'], true);
+        if (!is_array($data) || intval($data['code']) != 0) {
+            Cache::forget($cacheKey);
+            return Base::retError("error ip: -1");
+        }
+        $data = $data['data'];
+        if (!is_array($data) || !isset($data['country'])) {
+            return Base::retError("error ip: -2");
+        }
+        $data['text'] = $data['country'];
+        $data['textSmall'] = $data['country'];
+        if ($data['region'] && $data['region'] != $data['country'] && $data['region'] != "XX") {
+            $data['text'].= " " . $data['region'];
+            $data['textSmall'] = $data['region'];
+        }
+        if ($data['city'] && $data['city'] != $data['region'] && $data['city'] != "XX") {
+            $data['text'].= " " . $data['city'];
+            $data['textSmall'].= " " . $data['city'];
+        }
+        if ($data['county'] && $data['county'] != $data['city'] && $data['county'] != "XX") {
+            $data['text'].= " " . $data['county'];
+            $data['textSmall'].= " " . $data['county'];
+        }
+        return Base::retSuccess("success", $data);
+    }
+
+    /**
+     * 是否是中国IP:-1错误、1是、0否
+     * @param string $ip
+     * @return int
+     */
+    public static function isCnIp($ip = '')
+    {
+        if (empty($ip)) {
+            $ip = self::getIp();
+        }
+        $cacheKey = "isCnIp::" . md5($ip);
+        //
+        $result = Cache::remember($cacheKey, now()->addMinutes(10), function () use ($ip) {
+            $file = dirname(__FILE__) . '/ip/all_cn.txt';
+            if (!file_exists($file)) {
+                return -1;
+            }
+            $in = false;
+            $myFile = fopen($file, "r");
+            $i = 0;
+            while (!feof($myFile)) {
+                $i++;
+                $cidr = trim(fgets($myFile));
+                if (Base::ipInRange($ip, $cidr)) {
+                    $in = true;
+                    break;
+                }
+            }
+            fclose($myFile);
+            return $in ? 1 : 0;
+        });
+        if ($result === -1) {
+            Cache::forget($cacheKey);
+        }
+        //
+        return intval($result);
+    }
+
+    /**
+     * 验证IP地址范围
+     * $range 支持多种写法
+     *  - Wildcard: 1.2.3.*
+     *  - CIRD:1.2.3/24 或者 1.2.3.4/255.255.255.0
+     *  - Start-End: 1.2.3.0-1.2.3.255
+     * @param $ip
+     * @param $range
+     * @return bool
+     */
+    public static function ipInRange($ip, $range)
+    {
+        if (substr_count($ip, '.') == 3 && $ip == $range) {
+            return true;
+        }
+        if (strpos($range, '/') !== false) {
+            list($range, $netmask) = explode('/', $range, 2);
+            if (strpos($netmask, '.') !== false) {
+                $netmask = str_replace('*', '0', $netmask);
+                $netmask_dec = ip2long($netmask);
+                return ((ip2long($ip) & $netmask_dec) == (ip2long($range) & $netmask_dec));
+            } else {
+                $x = explode('.', $range);
+                while (count($x) < 4) {
+                    $x[] = '0';
+                }
+                list($a, $b, $c, $d) = $x;
+                $range = sprintf("%u.%u.%u.%u", empty($a) ? '0' : $a, empty($b) ? '0' : $b, empty($c) ? '0' : $c, empty($d) ? '0' : $d);
+                $range_dec = ip2long($range);
+                $ip_dec = ip2long($ip);
+                $wildcard_dec = pow(2, (32 - $netmask)) - 1;
+                $netmask_dec = ~$wildcard_dec;
+                return (($ip_dec & $netmask_dec) == ($range_dec & $netmask_dec));
+            }
+        } else {
+            if (strpos($range, '*') !== false) {
+                $lower = str_replace('*', '0', $range);
+                $upper = str_replace('*', '255', $range);
+                $range = "$lower-$upper";
+            }
+            if (strpos($range, '-') !== false) {
+                list($lower, $upper) = explode('-', $range, 2);
+                $lower_dec = (float)sprintf("%u", ip2long($lower));
+                $upper_dec = (float)sprintf("%u", ip2long($upper));
+                $ip_dec = (float)sprintf("%u", ip2long($ip));
+                return (($ip_dec >= $lower_dec) && ($ip_dec <= $upper_dec));
+            }
+            return false;
+        }
+    }
+
+    /**
+     * php://input 字符串解析到变量并获取指定值
+     * @param $key
+     * @return array
+     */
+    public static function getContentsParse($key)
+    {
+        parse_str(Request::getContent(), $input);
+        if ($key) {
+            $input = isset($input[$key]) ? $input[$key] : array();
+        }
+        return is_array($input) ? $input : array($input);
+    }
+
+    /**
+     * php://input 字符串解析到变量并获取指定值
+     * @param $key
+     * @param null $default
+     * @return mixed|null
+     */
+    public static function getContentValue($key, $default = null)
+    {
+        global $_A;
+        if (!isset($_A["__static_input_content"])) {
+            parse_str(Request::getContent(), $input);
+            $_A["__static_input_content"] = $input;
+        }
+        return isset($_A["__static_input_content"][$key]) ? $_A["__static_input_content"][$key] : $default;
+    }
+
+    public static function getPostValue($key, $default = null)
+    {
+        return self::getContentValue($key, $default);
+    }
+
+    /**
+     * 多维 array_values
+     * @param $array
+     * @param string $keyName
+     * @param string $valName
+     * @return array
+     */
+    public static function array_values_recursive($array, $keyName = 'key', $valName = 'item') {
+        if (is_array($array) && count($array) > 0) {
+            $temp = [];
+            foreach ($array as $key => $value) {
+                $continue = false;
+                if (is_array($value) && count($value) > 0) {
+                    $continue = true;
+                    foreach ($value AS $item) {
+                        if (!is_array($item)) {
+                            $continue = false;
+                            break;
+                        }
+                    }
+                }
+                $temp[] = [
+                    $keyName => $key,
+                    $valName => $continue ? self::array_values_recursive($value, $keyName, $valName) : $value,
+                ];
+            }
+            return $temp;
+        }
+        return $array;
+    }
+
+    /**
+     * 获取tonken
+     * @return string
+     */
+    public static function getToken()
+    {
+        global $_A;
+        if (!isset($_A["__static_token"])) {
+            $_A["__static_token"] = Base::nullShow(Request::header('token'), Request::input('token'));
+        }
+        return $_A["__static_token"];
+    }
+
+    /**
+     * 设置tonken
+     * @param $token
+     */
+    public static function setToken($token)
+    {
+        global $_A;
+        $_A["__static_token"] = $token;
+    }
+
+    /**
+     * 是否微信
+     * @return bool
+     */
+    public static function isWechat()
+    {
+        return strpos(Request::server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
+    }
+
+    /**
+     * 获取浏览器类型
+     * @return string
+     */
+    public static function browser()
+    {
+        $user_agent = Request::server('HTTP_USER_AGENT');
+        if (strpos($user_agent, 'AlipayClient') !== false) {
+            return 'alipay';
+        }elseif (strpos($user_agent, 'MicroMessenger') !== false) {
+            return 'weixin';
+        }else{
+            return 'none';
+        }
+    }
+
+    /**
+     * 返回根据距离sql排序语句
+     * @param $lat
+     * @param $lng
+     * @param string $latName
+     * @param string $lngName
+     * @return string
+     */
+    public static function acos($lat , $lng, $latName = 'lat', $lngName = 'lng') {
+        $lat = floatval($lat);
+        $lng = floatval($lng);
+        return 'ACOS(
+		SIN(('.$lat.' * 3.1415) / 180) * SIN(('.$latName.' * 3.1415) / 180) + COS(('.$lat.' * 3.1415) / 180) * COS(('.$latName.' * 3.1415) / 180) * COS(
+			('.$lng.' * 3.1415) / 180 - ('.$lngName.' * 3.1415) / 180
+		)
+	) * 6380';
+    }
+
+    /**
+     * 获取分页详细信息
+     * @param LengthAwarePaginator $lists
+     * @param bool $getTotal
+     * @return array
+     */
+    public static function getPageInfo(LengthAwarePaginator $lists, $getTotal = true)
+    {
+        return [
+            "currentPage" => $lists->currentPage(),
+            "firstItem" => $lists->firstItem(),
+            "hasMorePages" => $lists->hasMorePages(),
+            "lastItem" => $lists->lastItem(),
+            "lastPage" => $lists->lastPage(),
+            "nextPageUrl" => $lists->nextPageUrl(),
+            "previousPageUrl" => $lists->previousPageUrl(),
+            "perPage" => $lists->perPage(),
+            "total" => $getTotal === true ? $lists->total() : -1,
+        ];
+    }
+
+    /**
+     * 获取分页数据
+     * @param $lists
+     * @param bool $getTotal
+     * @return array
+     */
+    public static function getPageList($lists, $getTotal = true)
+    {
+        $data = Base::getPageInfo($lists, $getTotal);
+        $data['lists'] = Base::coll2array($lists);
+        return $data;
+    }
+
+    /**
+     * 获取每页数量
+     * @param $max
+     * @param $default
+     * @param string $inputName
+     * @return mixed
+     */
+    public static function getPaginate($max, $default, $inputName = 'pagesize') {
+        return Min(Max(Base::nullShow(Request::input($inputName), $default), 1), $max);
+    }
+
+    /**
+     * image64图片保存
+     * @param array $param [ image64=带前缀的base64, path=>文件路径, fileName=>文件名称, scale=>[压缩原图宽,高, 压缩方式] ]
+     * @return array [name=>文件名, size=>文件大小(单位KB),file=>绝对地址, path=>相对地址, url=>全路径地址, ext=>文件后缀名]
+     */
+    public static function image64save($param)
+    {
+        $imgBase64 = $param['image64'];
+        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $imgBase64, $res)) {
+            $extension = $res[2];
+            if (!in_array($extension, ['png', 'jpg', 'jpeg', 'gif'])) {
+                return Base::retError('图片格式错误!');
+            }
+            $scaleName = "";
+            if ($param['fileName']) {
+                $fileName = $param['fileName'];
+            }else{
+                if ($param['scale'] && is_array($param['scale'])) {
+                    list($width, $height) = $param['scale'];
+                    if ($width > 0 || $height > 0) {
+                        $scaleName = "_{WIDTH}x{HEIGHT}";
+                        if (isset($param['scale'][2])) {
+                            $scaleName.= $param['scale'][2];
+                        }
+                    }
+                }
+                $fileName = 'paste_' . md5($imgBase64) . '.' . $extension;
+                $scaleName = md5_file($imgBase64) . $scaleName . '.' . $extension;
+            }
+            $fileDir = $param['path'];
+            $filePath = public_path($fileDir);
+            Base::makeDir($filePath);
+            if (file_put_contents($filePath . $fileName, base64_decode(str_replace($res[1], '', $imgBase64)))) {
+                $fileSize = filesize($filePath . $fileName);
+                $array = [
+                    "name" => $fileName,                                                //原文件名
+                    "size" => Base::twoFloat($fileSize / 1024, true),         //大小KB
+                    "file" => $filePath . $fileName,                                    //目录的完整路径                "D:\www....KzZ.jpg"
+                    "path" => $fileDir . $fileName,                                     //相对路径                     "uploads/pic....KzZ.jpg"
+                    "url" => Base::fillUrl($fileDir . $fileName),                   //完整的URL                    "https://.....hhsKzZ.jpg"
+                    "thumb" => '',                                                      //缩略图(预览图)               "https://.....hhsKzZ.jpg_thumb.jpg"
+                    "width" => -1,                                                      //图片宽度
+                    "height" => -1,                                                     //图片高度
+                    "ext" => $extension,                                                //文件后缀名
+                ];
+                if (in_array($extension, ['png', 'jpg', 'jpeg', 'gif'])) {
+                    //图片尺寸
+                    $paramet = getimagesize($array['file']);
+                    $array['width'] = $paramet[0];
+                    $array['height'] = $paramet[1];
+                    //原图压缩
+                    if ($param['scale'] && is_array($param['scale'])) {
+                        list($width, $height) = $param['scale'];
+                        if (($width > 0 && $array['width'] > $width) || ($height > 0 && $array['height'] > $height)) {
+                            $cut = ($width > 0 && $height > 0) ? 1 : -1;
+                            $cut = $param['scale'][2] ?? $cut;
+                            //图片压缩
+                            $tmpFile = $array['file'] . '_tmp.jpg';
+                            if (Base::imgThumb($array['file'], $tmpFile, $width, $height, $cut)) {
+                                $tmpSize = filesize($tmpFile);
+                                if ($tmpSize > $fileSize) {
+                                    @unlink($tmpFile);
+                                }else{
+                                    @unlink($array['file']);
+                                    rename($tmpFile, $array['file']);
+                                }
+                            }
+                            //图片尺寸
+                            $paramet = getimagesize($array['file']);
+                            $array['width'] = $paramet[0];
+                            $array['height'] = $paramet[1];
+                            //重命名
+                            if ($scaleName) {
+                                $scaleName = str_replace(['{WIDTH}', '{HEIGHT}'], [$array['width'], $array['height']], $scaleName);
+                                if (rename($array['file'], Base::rightDelete($array['file'], $fileName) . $scaleName)) {
+                                    $array['file'] = Base::rightDelete($array['file'], $fileName) . $scaleName;
+                                    $array['path'] = Base::rightDelete($array['path'], $fileName) . $scaleName;
+                                    $array['url'] = Base::rightDelete($array['url'], $fileName) . $scaleName;
+                                }
+                            }
+                        }
+                    }
+                    //生成缩略图
+                    $array['thumb'] = $array['path'];
+                    if (Base::imgThumb($array['file'], $array['file']."_thumb.jpg", 180, 0)) {
+                        $array['thumb'].= "_thumb.jpg";
+                    }
+                    $array['thumb'] = Base::fillUrl($array['thumb']);
+                }
+                return Base::retSuccess('success', $array);
+            }
+        }
+        return Base::retError('图片保存失败!');
+    }
+
+    /**
+     * 上传文件
+     * @param array $param [ type=[文件类型], file=>Request::file, path=>文件路径, fileName=>文件名称, scale=>[压缩原图宽,高, 压缩方式], size=>限制大小KB, autoThumb=>false不要自动生成缩略图 ]
+     * @return array [name=>原文件名, size=>文件大小(单位KB),file=>绝对地址, path=>相对地址, url=>全路径地址, ext=>文件后缀名]
+     */
+    public static function upload($param)
+    {
+        $file = $param['file'];
+        if (empty($file)) {
+            return Base::retError("您没有选择要上传的文件!");
+        }
+        if($file->isValid()){
+            Base::makeDir(public_path($param['path']));
+            //
+            switch ($param['type']) {
+                case 'png':
+                    $type = ['png'];
+                    break;
+                case 'png+jpg':
+                    $type = ['jpg', 'jpeg', 'png'];
+                    break;
+                case 'image':
+                    $type = ['jpg', 'jpeg', 'gif', 'png'];
+                    break;
+                case 'video':
+                    $type = ['rm', 'rmvb', 'wmv', 'avi', 'mpg', 'mpeg', 'mp4'];
+                    break;
+                case 'audio':
+                    $type = ['mp3', 'wma', 'wav', 'amr'];
+                    break;
+                case 'excel':
+                    $type = ['xls', 'xlsx'];
+                    break;
+                case 'app':
+                    $type = ['apk'];
+                    break;
+                case 'zip':
+                    $type = ['zip'];
+                    break;
+                case 'file':
+                    $type = ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz', 'ai', 'avi', 'bmp', 'cdr', 'eps', 'mov', 'mp3', 'mp4', 'pr', 'psd', 'svg', 'tif'];
+                    break;
+                default:
+                    return Base::retError('错误的类型参数');
+            }
+            $extension = strtolower($file->getClientOriginalExtension());
+            if ($type && is_array($type) && !in_array($extension, $type)) {
+                return Base::retError(['文件格式错误,限制类型:%!', implode(",", $type)]);
+            }
+            try {
+                $fileSize = $file->getSize();
+                if ($param['size'] > 0 && $fileSize > $param['size'] * 1024) {
+                    return Base::retError(['文件大小超限,最大限制:%KB!', $param['size']]);
+                }
+            } catch (Exception $e) {
+                $fileSize = 0;
+            }
+            $scaleName = "";
+            if ($param['fileName']) {
+                $fileName = $param['fileName'];
+            }else{
+                if ($param['scale'] && is_array($param['scale'])) {
+                    list($width, $height) = $param['scale'];
+                    if ($width > 0 || $height > 0) {
+                        $scaleName = "_{WIDTH}x{HEIGHT}";
+                        if (isset($param['scale'][2])) {
+                            $scaleName.= $param['scale'][2];
+                        }
+                    }
+                }
+                $fileName = md5_file($file) . '.' . $extension;
+                $scaleName = md5_file($file) . $scaleName . '.' . $extension;
+            }
+            //
+            $file->move(public_path($param['path']), $fileName);
+            //
+            $array = [
+                "name" => $file->getClientOriginalName(),               //原文件名
+                "size" => Base::twoFloat($fileSize / 1024, true),       //大小KB
+                "file" => public_path($param['path'].$fileName),        //目录的完整路径                "D:\www....KzZ.jpg"
+                "path" => $param['path'].$fileName,                     //相对路径                     "uploads/pic....KzZ.jpg"
+                "url" => Base::fillUrl($param['path'].$fileName),       //完整的URL                    "https://.....hhsKzZ.jpg"
+                "thumb" => '',                                          //缩略图(预览图)               "https://.....hhsKzZ.jpg_thumb.jpg"
+                "width" => -1,                                          //图片宽度
+                "height" => -1,                                         //图片高度
+                "ext" => $extension,                                    //文件后缀名
+            ];
+            if (!is_file($array['file'])) {
+                return Base::retError('上传失败!');
+            }
+            //iOS照片颠倒处理
+            if (in_array($extension, ['jpg', 'jpeg']) && function_exists('exif_read_data')) {
+                $data = imagecreatefromstring(file_get_contents($array['file']));
+                $exif = @exif_read_data($array['file']);
+                if (!empty($exif['Orientation'])) {
+                    switch ($exif['Orientation']) {
+                        case 8:
+                            $data = imagerotate($data, 90, 0);
+                            break;
+                        case 3:
+                            $data = imagerotate($data, 180, 0);
+                            break;
+                        case 6:
+                            $data = imagerotate($data, -90, 0);
+                            break;
+                        default:
+                            $data = null;
+                            break;
+                    }
+                    if ($data !== null) {
+                        imagejpeg($data, $array['file']);
+                    }
+                }
+            }
+            //
+            if (in_array($extension, ['jpg', 'jpeg', 'gif', 'png'])) {
+                //图片尺寸
+                $paramet = getimagesize($array['file']);
+                $array['width'] = $paramet[0];
+                $array['height'] = $paramet[1];
+                //原图压缩
+                if ($param['scale'] && is_array($param['scale'])) {
+                    list($width, $height) = $param['scale'];
+                    if (($width > 0 && $array['width'] > $width) || ($height > 0 && $array['height'] > $height)) {
+                        $cut = ($width > 0 && $height > 0) ? 1 : -1;
+                        $cut = $param['scale'][2] ?? $cut;
+                        //图片压缩
+                        $tmpFile = $array['file'] . '_tmp.jpg';
+                        if (Base::imgThumb($array['file'], $tmpFile, $width, $height, $cut)) {
+                            $tmpSize = filesize($tmpFile);
+                            if ($tmpSize > $fileSize) {
+                                @unlink($tmpFile);
+                            }else{
+                                @unlink($array['file']);
+                                rename($tmpFile, $array['file']);
+                            }
+                        }
+                        //图片尺寸
+                        $paramet = getimagesize($array['file']);
+                        $array['width'] = $paramet[0];
+                        $array['height'] = $paramet[1];
+                        //重命名
+                        if ($scaleName) {
+                            $scaleName = str_replace(['{WIDTH}', '{HEIGHT}'], [$array['width'], $array['height']], $scaleName);
+                            if (rename($array['file'], Base::rightDelete($array['file'], $fileName) . $scaleName)) {
+                                $array['file'] = Base::rightDelete($array['file'], $fileName) . $scaleName;
+                                $array['path'] = Base::rightDelete($array['path'], $fileName) . $scaleName;
+                                $array['url'] = Base::rightDelete($array['url'], $fileName) . $scaleName;
+                            }
+                        }
+                    }
+                }
+                //生成缩略图
+                $array['thumb'] = $array['path'];
+                if ($param['autoThumb'] === "false") $param['autoThumb'] = false;
+                if ($param['autoThumb'] !== false) {
+                    if (Base::imgThumb($array['file'], $array['file']."_thumb.jpg", 180, 0)) {
+                        $array['thumb'].= "_thumb.jpg";
+                    }
+                }
+                $array['thumb'] = Base::fillUrl($array['thumb']);
+            }
+            //
+            return Base::retSuccess('success', $array);
+        }else{
+            return Base::retError($file->getErrorMessage());
+        }
+    }
+
+    /**
+     * 生成缩略图
+     * @param string $src_img 源图绝对完整地址{带文件名及后缀名}
+     * @param string $dst_img 目标图绝对完整地址{带文件名及后缀名}
+     * @param int $width 缩略图宽{0:此时目标高度不能为0,目标宽度为源图宽*(目标高度/源图高)}
+     * @param int $height 缩略图高{0:此时目标宽度不能为0,目标高度为源图高*(目标宽度/源图宽)}
+     * @param int $cut 是否裁切{宽,高必须非0}:1是、0否、-1或'auto'保持等比
+     * @param int $proportion 缩放{0:不缩放, 0<this<1:缩放到相应比例(此时宽高限制和裁切均失效)}
+     * @return bool
+     */
+    public static function imgThumb($src_img, $dst_img, $width = 75, $height = 75, $cut = 0, $proportion = 0)
+    {
+        if (!is_file($src_img)) {
+            return false;
+        }
+        if (empty($dst_img)) {
+            $dst_img = $src_img;
+        }
+        $st = pathinfo($src_img, PATHINFO_EXTENSION);
+        if (!in_array(strtolower($st), array('jpg', 'jpeg', 'png', 'gif', 'bmp'))) {
+            return false;
+        }
+        $ot = pathinfo($dst_img, PATHINFO_EXTENSION);
+        $otfunc = 'image' . ($ot == 'jpg' ? 'jpeg' : $ot);
+        $srcinfo = getimagesize($src_img);
+        $src_w = $srcinfo[0];
+        $src_h = $srcinfo[1];
+        $type = strtolower(substr(image_type_to_extension($srcinfo[2]), 1));
+        if (empty($type)) {
+            return false;
+        }
+        $createfun = 'imagecreatefrom' . ($type == 'jpg' ? 'jpeg' : $type);
+
+        $dst_h = $height;
+        $dst_w = $width;
+        $x = $y = 0;
+
+        /**
+         * 缩略图不超过源图尺寸(前提是宽或高只有一个)
+         */
+        if (($width > $src_w && $height > $src_h) || ($height > $src_h && $width == 0) || ($width > $src_w && $height == 0)) {
+            $proportion = 1;
+        }
+        if ($width > $src_w) {
+            $dst_w = $width = $src_w;
+        }
+        if ($height > $src_h) {
+            $dst_h = $height = $src_h;
+        }
+
+        if (!$width && !$height && !$proportion) {
+            return false;
+        }
+        if (!$proportion) {
+            if ($cut == 'auto' || $cut == -1) {
+                if ($dst_w && $dst_h) {
+                    $wB = $dst_w / $src_w;
+                    $hB = $dst_h / $src_h;
+                    if ($wB > $hB) {
+                        $dst_w = 0;
+                    }else{
+                        $dst_h = 0;
+                    }
+                }
+                $cut = 0;
+            }
+            if ($cut == 0) {
+
+                if ($dst_w && $dst_h) {
+                    if ($dst_w / $src_w > $dst_h / $src_h) {
+                        $dst_w = $src_w * ($dst_h / $src_h);
+                        $x = 0 - ($dst_w - $width) / 2;
+                    } else {
+                        $dst_h = $src_h * ($dst_w / $src_w);
+                        $y = 0 - ($dst_h - $height) / 2;
+                    }
+                } else if ($dst_w xor $dst_h) {
+                    if ($dst_w && !$dst_h)  //有宽无高
+                    {
+                        $propor = $dst_w / $src_w;
+                        $height = $dst_h = $src_h * $propor;
+                    } else if (!$dst_w && $dst_h)  //有高无宽
+                    {
+                        $propor = $dst_h / $src_h;
+                        $width = $dst_w = $src_w * $propor;
+                    }
+                }
+            } else {
+                if (!$dst_h)  //裁剪时无高
+                {
+                    $height = $dst_h = $dst_w;
+                }
+                if (!$dst_w)  //裁剪时无宽
+                {
+                    $width = $dst_w = $dst_h;
+                }
+                $propor = min(max($dst_w / $src_w, $dst_h / $src_h), 1);
+                $dst_w = (int)round($src_w * $propor);
+                $dst_h = (int)round($src_h * $propor);
+                $x = ($width - $dst_w) / 2;
+                $y = ($height - $dst_h) / 2;
+            }
+        } else {
+            $proportion = min($proportion, 1);
+            $height = $dst_h = $src_h * $proportion;
+            $width = $dst_w = $src_w * $proportion;
+        }
+
+        if (!function_exists($createfun)) {
+            return false;
+        }
+
+        $src = $createfun($src_img);
+        $dst = imagecreatetruecolor($width ? $width : $dst_w, $height ? $height : $dst_h);
+        try {
+            $white = imagecolorallocate($dst, 255, 255, 255);
+            imagefill($dst, 0, 0, $white);
+        } catch (Exception $e) {
+
+        }
+        if (function_exists('imagecopyresampled')) {
+            imagecopyresampled($dst, $src, $x, $y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
+        } else {
+            imagecopyresized($dst, $src, $x, $y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
+        }
+        $otfunc($dst, $dst_img);
+        imagedestroy($dst);
+        imagedestroy($src);
+        return true;
+    }
+
+    /**
+     * 排列组合(无重复)
+     * @param $arr
+     * @param $m
+     * @return array
+     */
+    public static function getCombinationToString($arr, $m)
+    {
+        $result = [];
+        if ($m == 1) {
+            return $arr;
+        }
+
+        if ($m == count($arr)) {
+            $result[] = implode(',', $arr);
+            return $result;
+        }
+
+        $temp_firstelement = $arr[0];
+        unset($arr[0]);
+        $arr = array_values($arr);
+        $temp_list1 = self::getCombinationToString($arr, ($m - 1));
+
+        foreach ($temp_list1 as $s) {
+            $s = $temp_firstelement . ',' . $s;
+            $result[] = $s;
+        }
+        unset($temp_list1);
+
+        $temp_list2 = self::getCombinationToString($arr, $m);
+        foreach ($temp_list2 as $s) {
+            $result[] = $s;
+        }
+        unset($temp_list2);
+
+        return $result;
+    }
+
+    /**
+     * 不同元素交叉组合(多个数组)
+     * @return array
+     */
+    public static function getNewArray()
+    {
+        $args = func_get_args();
+        $pailie = function ($arr1, $arr2) {
+            $arr = [];
+            $k = 0;
+            foreach ($arr1 as $k1 => $v1) {
+                foreach ($arr2 as $k2 => $v2) {
+                    $arr[$k] = $v1 . "," . $v2;
+                    $k++;
+                }
+            }
+            return $arr;
+        };
+        $arr = [];
+        foreach ($args as $k => $v) {
+            if (isset($args[$k + 1]) && $args[$k + 1]) {
+                switch ($k) {
+                    case 0:
+                        $arr[$k] = $pailie($v, $args[$k + 1]);
+                        break;
+                    default:
+                        $arr[$k] = $pailie($arr[$k - 1], $args[$k + 1]);
+                        break;
+                }
+            }
+        }
+        $key = count($arr) - 1;
+        return array_values($arr[$key]);
+    }
+
+    /**
+     * 获取当前是本月第几个星期
+     * @return false|float
+     */
+    public static function getMonthWeek()
+    {
+        $time = strtotime(date("Y-m-01"));
+        $w = date('w', $time);
+        $j = date("j");
+        return ceil(($j + $w) / 7);
+    }
+
+    /**
+     * 把返回的数据集转换成Tree
+     * @param array $list           要转换的数据集
+     * @param string $pk            id标记字段
+     * @param string $pid           parent标记字段
+     * @param string $child         生成子类字段
+     * @param int $root
+     * @return array
+     */
+    public static function list2Tree($list, $pk='id', $pid = 'pid', $child = 'children', $root = 0) {
+        if (!is_array($list)) {
+            return [];
+        }
+
+        // 创建基于主键的数组引用
+        $aRefer = [];
+        foreach ($list as $key => $data) {
+            $list[$key][$child] = [];
+            $aRefer[$data[$pk]] = & $list[$key];
+        }
+
+        $tree = [];
+
+        foreach ($list as $key => $data) {
+            // 判断是否存在parent
+            $parentId = $data[$pid];
+            if ($root === $parentId) {
+                $tree[] = & $list[$key];
+            } else {
+                if (isset($aRefer[$parentId])) {
+                    $parent = & $aRefer[$parentId];
+                    $parent[$child][] = & $list[$key];
+                }
+            }
+        }
+
+        return $tree;
+    }
+
+    /**
+     * 遍历获取文件
+     * @param $dir
+     * @return array
+     */
+    public static function readDir($dir)
+    {
+        $files = array();
+        $dir_list = scandir($dir);
+        foreach ($dir_list as $file) {
+            if ($file != '..' && $file != '.') {
+                if (is_dir($dir . '/' . $file)) {
+                    $files = array_merge($files, self::readDir($dir . '/' . $file));
+                } else {
+                    $files[] = $dir . "/" . $file;
+                }
+            }
+        }
+        return $files;
+    }
+
+    /**
+     * 获取中文字符拼音首字母
+     * @param $str
+     * @return string
+     */
+    public static function getFirstCharter($str)
+    {
+        if (empty($str)) {
+            return '';
+        }
+        $fchar = ord($str[0]);
+        if ($fchar >= ord('A') && $fchar <= ord('z')) return strtoupper($str[0]);
+        $s1 = iconv('UTF-8', 'gb2312', $str);
+        $s2 = iconv('gb2312', 'UTF-8', $s1);
+        $s = $s2 == $str ? $s1 : $str;
+        $asc = ord($s[0]) * 256 + ord($s[1]) - 65536;
+        if ($asc >= -20319 && $asc <= -20284) return 'A';
+        if ($asc >= -20283 && $asc <= -19776) return 'B';
+        if ($asc >= -19775 && $asc <= -19219) return 'C';
+        if ($asc >= -19218 && $asc <= -18711) return 'D';
+        if ($asc >= -18710 && $asc <= -18527) return 'E';
+        if ($asc >= -18526 && $asc <= -18240) return 'F';
+        if ($asc >= -18239 && $asc <= -17923) return 'G';
+        if ($asc >= -17922 && $asc <= -17418) return 'H';
+        if ($asc >= -17417 && $asc <= -16475) return 'J';
+        if ($asc >= -16474 && $asc <= -16213) return 'K';
+        if ($asc >= -16212 && $asc <= -15641) return 'L';
+        if ($asc >= -15640 && $asc <= -15166) return 'M';
+        if ($asc >= -15165 && $asc <= -14923) return 'N';
+        if ($asc >= -14922 && $asc <= -14915) return 'O';
+        if ($asc >= -14914 && $asc <= -14631) return 'P';
+        if ($asc >= -14630 && $asc <= -14150) return 'Q';
+        if ($asc >= -14149 && $asc <= -14091) return 'R';
+        if ($asc >= -14090 && $asc <= -13319) return 'S';
+        if ($asc >= -13318 && $asc <= -12839) return 'T';
+        if ($asc >= -12838 && $asc <= -12557) return 'W';
+        if ($asc >= -12556 && $asc <= -11848) return 'X';
+        if ($asc >= -11847 && $asc <= -11056) return 'Y';
+        if ($asc >= -11055 && $asc <= -10247) return 'Z';
+        return '#';
+    }
+
+    /**
+     * 缓存数据
+     * @param $title
+     * @param null $value
+     * @return mixed|null
+     */
+    public static function cacheData($title, $value = null)
+    {
+        $title = "cacheData::" . $title;
+        $tmp = DB::table('tmp')->where('title', $title)->select('value')->first();
+        if ($value !== null ) {
+            if (empty($tmp)) {
+                DB::table('tmp')->insert(['title'=>$title, 'value'=>$value]);
+            }else{
+                DB::table('tmp')->where('title', $title)->update(['value'=>$value]);
+            }
+            return $value;
+        }else{
+            return $tmp->value;
+        }
+    }
+}

+ 144 - 0
app/Module/BillExport.php

@@ -0,0 +1,144 @@
+<?php
+
+namespace App\Module;
+
+use Excel;
+use Maatwebsite\Excel\Concerns\FromCollection;
+use Maatwebsite\Excel\Concerns\WithEvents;
+use Maatwebsite\Excel\Concerns\WithHeadings;
+use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
+use Maatwebsite\Excel\Concerns\WithTitle;
+use Maatwebsite\Excel\Events\AfterSheet;
+use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
+use PhpOffice\PhpSpreadsheet\Writer\Exception;
+
+class BillExport implements WithHeadings, WithEvents, FromCollection, WithTitle, WithStrictNullComparison
+{
+    public $title;
+    public $headings = [];
+    public $data = [];
+    public $typeLists = [];
+    public $typeNumber = 0;
+
+    public function __construct($title, array $data)
+    {
+        $this->title = $title;
+        $this->data = $data;
+    }
+
+    public static function create($data = [], $title = "Sheet1") {
+        if (is_string($data)) {
+            list($title, $data) = [$data, $title];
+        }
+        if (!is_array($data)) {
+            $data = [];
+        }
+        return new BillExport($title, $data);
+    }
+
+    public function setTitle($title) {
+        $this->title = $title;
+        return $this;
+    }
+
+    public function setHeadings(array $headings) {
+        $this->headings = $headings;
+        return $this;
+    }
+
+    public function setData(array $data) {
+        $this->data = $data;
+        return $this;
+    }
+
+    public function setTypeList(array $typeList, $number = 0) {
+        $this->typeLists = $typeList;
+        $this->typeNumber = $number;
+        return $this;
+    }
+
+    public function store($fileName = '') {
+        if (empty($fileName)) {
+            $fileName = date("YmdHis") . '.xls';
+        }
+        try {
+            return Excel::store($this, $fileName);
+        } catch (Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        } catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        }
+    }
+
+    public function download($fileName = '') {
+        if (empty($fileName)) {
+            $fileName = date("YmdHis") . '.xls';
+        }
+        try {
+            return Excel::download($this, $fileName);
+        } catch (Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        } catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
+            return "导出错误:" . $e->getMessage();
+        }
+    }
+
+    /**
+     * 导出的文件标题
+     * @return string
+     */
+    public function title(): string
+    {
+        return $this->title;
+    }
+
+    /**
+     * 标题行
+     * @return array
+     */
+    public function headings(): array
+    {
+        return $this->headings;
+    }
+
+    /**
+     * 导出的内容
+     * @return \Illuminate\Support\Collection
+     */
+    public function collection()
+    {
+        return collect($this->data);
+    }
+
+    /**
+     * 设置单元格事件
+     * @return array
+     */
+    public function registerEvents(): array
+    {
+        return [
+            AfterSheet::Class => function (AfterSheet $event) {
+                $count = count($this->data);
+                foreach ($this->typeLists AS $cell => $typeList) {
+                    if ($cell && $typeList) {
+                        $p = $this->headings ? 1 : 0;
+                        for ($i = 1 + $p; $i <= max($count, $this->typeNumber) + $p; $i++) {
+                            $validation = $event->sheet->getDelegate()->getCell($cell . $i)->getDataValidation();
+                            $validation->setType(DataValidation::TYPE_LIST);
+                            $validation->setErrorStyle(DataValidation::STYLE_WARNING);
+                            $validation->setAllowBlank(false);
+                            $validation->setShowDropDown(true);
+                            $validation->setShowInputMessage(true);
+                            $validation->setShowErrorMessage(true);
+                            $validation->setErrorTitle('输入的值不合法');
+                            $validation->setError('选择的值不在列表中,请选择列表中的值');
+                            $validation->setPromptTitle('从列表中选择');
+                            $validation->setPrompt('请选择下拉列表中的值');
+                            $validation->setFormula1('"' . implode(',', $typeList) . '"');
+                        }
+                    }
+                }
+            }
+        ];
+    }
+}

+ 16 - 0
app/Module/BillImport.php

@@ -0,0 +1,16 @@
+<?php
+
+
+namespace App\Module;
+
+
+use Maatwebsite\Excel\Concerns\ToArray;
+
+class BillImport implements ToArray
+{
+    public function Array(Array $tables)
+    {
+        return $tables;
+    }
+
+}

+ 245 - 0
app/Module/Chat.php

@@ -0,0 +1,245 @@
+<?php
+
+namespace App\Module;
+
+use Cache;
+use DB;
+
+/**
+ * Class Chat
+ * @package App\Module
+ */
+class Chat
+{
+    /**
+     * 打开对话(创建对话)
+     * @param string $username      发送者用户名
+     * @param string $receive       接受者用户名
+     * @param bool $forceRefresh    是否强制刷新缓存
+     * @return mixed
+     */
+    public static function openDialog($username, $receive, $forceRefresh = false)
+    {
+        if (!$username || !$receive) {
+            return Base::retError('参数错误!');
+        }
+        $cacheKey = $username . "@" . $receive;
+        if ($forceRefresh === true) {
+            Cache::forget($cacheKey);
+        }
+        $result = Cache::remember($cacheKey, now()->addMinutes(10), function() use ($receive, $username) {
+            $row = Base::DBC2A(DB::table('chat_dialog')->where([
+                'user1' => $username,
+                'user2' => $receive,
+            ])->first());
+            if ($row) {
+                $row['recField'] = 2;   //接受者的字段位置
+                return Base::retSuccess('already1', $row);
+            }
+            $row = Base::DBC2A(DB::table('chat_dialog')->where([
+                'user1' => $receive,
+                'user2' => $username,
+            ])->first());
+            if ($row) {
+                $row['recField'] = 1;
+                return Base::retSuccess('already2', $row);
+            }
+            //
+            DB::table('chat_dialog')->insert([
+                'user1' => $username,
+                'user2' => $receive,
+                'indate' => Base::time()
+            ]);
+            $row = Base::DBC2A(DB::table('chat_dialog')->where([
+                'user1' => $username,
+                'user2' => $receive,
+            ])->first());
+            if ($row) {
+                $row['recField'] = 2;
+                return Base::retSuccess('success', $row);
+            }
+            //
+            return Base::retError('系统繁忙,请稍后再试!');
+        });
+        if (Base::isError($result)) {
+            Cache::forget($cacheKey);
+        }
+        return $result;
+    }
+
+    /**
+     * 删除对话缓存
+     * @param $username
+     * @param $receive
+     * @return bool
+     */
+    public static function forgetDialog($username, $receive)
+    {
+        if (!$username || !$receive) {
+            return false;
+        }
+        Cache::forget($username . "@" . $receive);
+        Cache::forget($receive . "@" . $username);
+        return true;
+    }
+
+    /**
+     * 保存对话消息
+     * @param string $username      发送者用户名
+     * @param string $receive       接受者用户名
+     * @param array $message
+     * @return mixed
+     */
+    public static function saveMessage($username, $receive, $message)
+    {
+        $dialog = self::openDialog($username, $receive);
+        if (Base::isError($dialog)) {
+            return $dialog;
+        } else {
+            $dialog = $dialog['data'];
+        }
+        //
+        $indate = abs($message['indate'] - time()) > 60 ? time() : $message['indate'];
+        if (isset($message['id'])) unset($message['id']);
+        if (isset($message['username'])) unset($message['username']);
+        if (isset($message['userimg'])) unset($message['userimg']);
+        if (isset($message['indate'])) unset($message['indate']);
+        if (isset($message['replaceId'])) unset($message['replaceId']);
+        $inArray = [
+            'did' => $dialog['id'],
+            'username' => $username,
+            'receive' => $receive,
+            'message' => Base::array2string($message),
+            'indate' => $indate
+        ];
+        //
+        if (mb_strlen($message['text']) > 20000) {
+            return Base::retError("发送内容长度已超出最大限制!");
+        }
+        $field = ($dialog['recField'] == 1 ? 'unread1' : 'unread2');
+        $unread = intval(DB::table('chat_dialog')->where('id', $dialog['id'])->value($field));
+        $lastText = self::messageDesc($message);
+        if ($lastText) {
+            $upArray = [];
+            if ($username != $receive) {
+                $upArray = Base::DBUP([
+                    $field => 1,
+                ]);
+                $unread += 1;
+            }
+            $upArray['lasttext'] = mb_substr($lastText, 0, 100);
+            $upArray['lastdate'] = $indate;
+            if ($dialog['del1']) {
+                $upArray['del1'] = 0;
+            }
+            if ($dialog['del2']) {
+                $upArray['del2'] = 0;
+            }
+            DB::table('chat_dialog')->where('id', $dialog['id'])->update($upArray);
+            if ($dialog['del1'] || $dialog['del2']) {
+                Chat::forgetDialog($dialog['user1'], $dialog['user2']);
+            }
+        }
+        $inArray['id'] = DB::table('chat_msg')->insertGetId($inArray);
+        $inArray['message'] = $message;
+        $inArray['unread'] = $unread;
+        //
+        return Base::retSuccess('success', $inArray);
+    }
+
+    /**
+     * 格式化信息(来自接收)
+     * @param $data
+     * @return array
+     */
+    public static function formatMsgReceive($data) {
+        return self::formatMsgData(Base::json2array($data));
+    }
+
+    /**
+     * 格式化信息(用于发送)
+     * @param $array
+     * @return string
+     */
+    public static function formatMsgSend($array) {
+        return Base::array2json(self::formatMsgData($array));
+    }
+
+    /**
+     * 格式化信息
+     * @param array $array
+     * @return array
+     */
+    public static function formatMsgData($array = []) {
+        if (!is_array($array)) {
+            $array = [];
+        }
+        //messageType来自客户端(前端->后端):refresh/unread/read/roger/user/info/team/docs/appActivity
+        //messageType来自服务端(后端->前端):error/open/kick/user/back/unread/docs
+        if (!isset($array['messageType'])) $array['messageType'] = '';  //消息类型
+        if (!isset($array['messageId'])) $array['messageId'] = '';      //消息ID(用于back给客户端)
+        if (!isset($array['contentId'])) $array['contentId'] = 0;       //消息数据ID(用于roger给服务端)
+        if (!isset($array['channel'])) $array['channel'] = '';          //渠道(用于多端登录)
+        if (!isset($array['username'])) $array['username'] = '';        //发送者
+        if (!isset($array['target'])) $array['target'] = null;          //接受者
+        if (!isset($array['body'])) $array['body'] = [];                //正文内容
+        if (!isset($array['time'])) $array['time'] = time();            //时间
+        //
+        $array['contentId'] = intval($array['contentId']);
+        if (!is_array($array['body']) || empty($array['body'])) $array['body'] = ['_' => time()];
+        return $array;
+    }
+
+    /**
+     * 获取跟任务有关系的(在线)用户(关注的、在项目里的、负责人、创建者)
+     * @param $taskId
+     * @return array
+     */
+    public static function getTaskUsers($taskId)
+    {
+        $tmpLists = Project::taskSomeUsers($taskId);
+        if (empty($tmpLists)) {
+            return [];
+        }
+        //
+        return Base::DBC2A(DB::table('ws')->select(['fd', 'username', 'channel'])->where([
+            ['update', '>', time() - 600],
+        ])->whereIn('username', array_values(array_unique($tmpLists)))->get());
+    }
+
+    /**
+     * 获取消息简述
+     * @param array $message
+     * @return mixed|string
+     */
+    public static function messageDesc($message)
+    {
+        switch ($message['type']) {
+            case 'text':
+                $lastText = $message['text'];
+                break;
+            case 'image':
+                $lastText = '[图片]';
+                break;
+            case 'file':
+                $lastText = '[文件]';
+                break;
+            case 'taskB':
+                $lastText = $message['text'] . " [来自关注任务]";
+                break;
+            case 'report':
+                $lastText = $message['text'] . " [来自工作报告]";
+                break;
+            case 'video':
+                $lastText = '[视频通话]';
+                break;
+            case 'voice':
+                $lastText = '[语音通话]';
+                break;
+            default:
+                $lastText = '[未知类型]';
+                break;
+        }
+        return $lastText;
+    }
+}

+ 105 - 0
app/Module/Docs.php

@@ -0,0 +1,105 @@
+<?php
+
+namespace App\Module;
+
+use App\Tasks\PushTask;
+use Cache;
+use DB;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+
+/**
+ * Class Docs
+ * @package App\Module
+ */
+class Docs
+{
+    /**
+     * 检验是否有阅读或修改权限
+     * @param $bookid
+     * @param string $checkType     edit|view
+     * @return array|mixed
+     */
+    public static function checkRole($bookid, $checkType = 'edit')
+    {
+        $row = Base::DBC2A(DB::table('docs_book')->where('id', $bookid)->first());
+        if (empty($row)) {
+            return Base::retError('知识库不存在或已被删除!', -1000);
+        }
+        $userE = Users::authE();
+        if (Base::isError($userE)) {
+            $user = [];
+        } else {
+            $user = $userE['data'];
+        }
+        $checkType = $checkType == 'edit' ? 'edit' : 'view';
+        if ($checkType == 'edit') {
+            if (empty($user)) {
+                return $userE;
+            }
+        } else {
+            if ($row['role_view'] != 'all') {
+                if (empty($user)) {
+                    return Base::retError('知识库仅对会员开放,请登录后再试!', -1001);
+                }
+            }
+        }
+        if ($user['username'] == $row['username']) {
+            return Base::retSuccess('success');
+        }
+        //
+        if ($row['role_' . $checkType] == 'member') {
+            if (!DB::table('docs_users')->where('bookid', $bookid)->where('username', $user['username'])->exists()) {
+                return Base::retError('知识库仅对成员开放!', $checkType == 'edit' && $row['role_look'] == 'reg' ? 1002 : -1002);
+            }
+        } elseif ($row['role_' . $checkType] == 'private') {
+            if ($row['username'] != $user['username']) {
+                return Base::retError('知识库仅对作者开放!', $checkType == 'edit' && $row['role_look'] == 'reg' ? 1003 : -1003);
+            }
+        }
+        //
+        return Base::retSuccess('success');
+    }
+
+    /**
+     * 通知正在编辑的成员
+     *
+     * @param integer $sid      章节ID
+     * @param array $bodyArray  body参数
+     */
+    public static function notice($sid, $bodyArray = [])
+    {
+        $user = Users::auth();
+        $array = Base::json2array(Cache::get("docs::" . $sid));
+        if ($array) {
+            foreach ($array as $uname => $vbody) {
+                if (intval($vbody['indate']) + 20 < time()) {
+                    unset($array[$uname]);
+                }
+            }
+        }
+        $pushLists = [];
+        if ($array) {
+            foreach ($array AS $tuser) {
+                $uLists = Base::DBC2A(DB::table('ws')->select(['fd', 'username', 'channel'])->where('username', $tuser['username'])->get());
+                foreach ($uLists AS $item) {
+                    if ($item['username'] == $user['username']) {
+                        continue;
+                    }
+                    $pushLists[] = [
+                        'fd' => $item['fd'],
+                        'msg' => [
+                            'messageType' => 'docs',
+                            'body' => array_merge([
+                                'sid' => $sid,
+                                'nickname' => $user['nickname'] ?: $user['username'],
+                                'time' => time(),
+                            ], $bodyArray)
+                        ]
+                    ];
+                }
+            }
+        }
+        $pushTask = new PushTask($pushLists);
+        Task::deliver($pushTask);
+    }
+}

+ 235 - 0
app/Module/Ihttp.php

@@ -0,0 +1,235 @@
+<?php
+
+namespace App\Module;
+
+use Exception;
+
+@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
+
+class Ihttp
+{
+
+    public static function ihttp_request($url, $post = [], $extra = [], $timeout = 60, $retRaw = false, $isGb2312 = false) {
+        $urlset = parse_url($url);
+        if(empty($urlset['path'])) {
+            $urlset['path'] = '/';
+        }
+        if(!empty($urlset['query'])) {
+            $urlset['query'] = "?{$urlset['query']}";
+        }
+        if(empty($urlset['port'])) {
+            $urlset['port'] = $urlset['scheme'] == 'https' ? '443' : '80';
+        }
+        if (Base::strExists($url, 'https://') && !extension_loaded('openssl')) {
+            if (!extension_loaded("openssl")) {
+                return Base::retError('请开启您PHP环境的openssl');
+            }
+        }
+        if(function_exists('curl_init') && function_exists('curl_exec')) {
+            $ch = curl_init();
+            curl_setopt($ch, CURLOPT_URL, $urlset['scheme']. '://' .$urlset['host'].($urlset['port'] == '80' ? '' : ':'.$urlset['port']).$urlset['path'].$urlset['query']);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+            curl_setopt($ch, CURLOPT_HEADER, 1);
+            if($post) {
+                if (is_array($post)) {
+                    $filepost = false;
+                    foreach ($post as $name => $value) {
+                        if (is_string($value) && substr($value, 0, 1) == '@') {
+                            $filepost = true;
+                            break;
+                        }
+                    }
+                    if (!$filepost) {
+                        $post = http_build_query($post);
+                    }
+                }
+                curl_setopt($ch, CURLOPT_POST, 1);
+                curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
+            }
+            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+            curl_setopt($ch, CURLOPT_SSLVERSION, 1);
+            if (defined('CURL_SSLVERSION_TLSv1')) {
+                curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
+            }
+            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1');
+            if (!empty($extra) && is_array($extra)) {
+                $headers = array();
+                foreach ($extra as $opt => $value) {
+                    if (Base::strExists($opt, 'CURLOPT_')) {
+                        curl_setopt($ch, constant($opt), $value);
+                    } elseif (is_numeric($opt)) {
+                        curl_setopt($ch, $opt, $value);
+                    } else {
+                        $headers[] = "{$opt}: {$value}";
+                    }
+                }
+                if(!empty($headers)) {
+                    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+                }
+            }
+            $data = curl_exec($ch);
+            //$status = curl_getinfo($ch);
+            $errno = curl_errno($ch);
+            $error = curl_error($ch);
+            curl_close($ch);
+            if($errno || empty($data)) {
+                return Base::retError($error);
+            } else {
+                if ($isGb2312) {
+                    try { $data = iconv('GB2312', 'UTF-8', $data); }catch (Exception $e) { }
+                }
+                $response = self::ihttp_response_parse($data);
+                if ($retRaw === true) {
+                    return Base::retSuccess($response['code'], $response);
+                }
+                return Base::retSuccess($response['code'], $response['content']);
+            }
+        }
+        $method = empty($post) ? 'GET' : 'POST';
+        $fdata = "{$method} {$urlset['path']}{$urlset['query']} HTTP/1.1\r\n";
+        $fdata .= "Host: {$urlset['host']}\r\n";
+        if(function_exists('gzdecode')) {
+            $fdata .= "Accept-Encoding: gzip, deflate\r\n";
+        }
+        $fdata .= "Connection: close\r\n";
+        if (!empty($extra) && is_array($extra)) {
+            foreach ($extra as $opt => $value) {
+                if (!Base::strExists($opt, 'CURLOPT_')) {
+                    $fdata .= "{$opt}: {$value}\r\n";
+                }
+            }
+        }
+        //$body = '';
+        if ($post) {
+            if (is_array($post)) {
+                $body = http_build_query($post);
+            } else {
+                $body = urlencode((string)$post);
+            }
+            $fdata .= 'Content-Length: ' . strlen($body) . "\r\n\r\n{$body}";
+        } else {
+            $fdata .= "\r\n";
+        }
+        if($urlset['scheme'] == 'https') {
+            $fp = fsockopen('ssl://' . $urlset['host'], $urlset['port'], $errno, $error);
+        } else {
+            $fp = fsockopen($urlset['host'], $urlset['port'], $errno, $error);
+        }
+        stream_set_blocking($fp, true);
+        stream_set_timeout($fp, $timeout);
+        if (!$fp) {
+            return Base::retError( $error);
+        } else {
+            fwrite($fp, $fdata);
+            $content = '';
+            while (!feof($fp))
+                $content .= fgets($fp, 512);
+            fclose($fp);
+            if ($isGb2312) {
+                try { $content = iconv('GB2312', 'UTF-8', $content); }catch (Exception $e) { }
+            }
+            $response = self::ihttp_response_parse($content, true);
+            if ($retRaw === true) {
+                return Base::retSuccess($response['code'], $response);
+            }
+            return Base::retSuccess($response['code'], $response['content']);
+        }
+    }
+
+    public static function ihttp_get($url) {
+        return self::ihttp_request($url);
+    }
+
+    public static function ihttp_post($url, $data, $timeout = 60) {
+        $headers = array('Content-Type' => 'application/x-www-form-urlencoded');
+        return self::ihttp_request($url, $data, $headers, $timeout);
+    }
+
+    public static function ihttp_proxy($url, $post = [], $timeout = 20, $extra = []) {
+        return self::ihttp_request($url, $post, $extra, $timeout);
+    }
+
+    private static function ihttp_response_parse($data, $chunked = false) {
+        $rlt = array();
+        $pos = strpos($data, "\r\n\r\n");
+        if (Base::strExists(substr($data, 0, $pos), "Proxy-agent:")) {
+            $data = substr($data, $pos + 4, strlen($data));
+            $pos = strpos($data, "\r\n\r\n");
+        }
+        $split1[0] = substr($data, 0, $pos);
+        $split1[1] = substr($data, $pos + 4, strlen($data));
+
+        $split2 = explode("\r\n", $split1[0], 2);
+        preg_match('/^(\S+) (\S+) (\S+)$/', $split2[0], $matches);
+        $rlt['code'] = $matches[2];
+        $rlt['status'] = $matches[3];
+        $rlt['responseline'] = $split2[0];
+        $header = explode("\r\n", $split2[1]);
+        $isgzip = false;
+        $ischunk = false;
+        foreach ($header as $v) {
+            $row = explode(':', $v);
+            $key = trim($row[0]);
+            $value = trim(substr($v, strlen($row[0]) + 1));
+            if (is_array($rlt['headers'][$key])) {
+                $rlt['headers'][$key][] = $value;
+            } elseif (!empty($rlt['headers'][$key])) {
+                $temp = $rlt['headers'][$key];
+                unset($rlt['headers'][$key]);
+                $rlt['headers'][$key][] = $temp;
+                $rlt['headers'][$key][] = $value;
+            } else {
+                $rlt['headers'][$key] = $value;
+            }
+            if(!$isgzip && strtolower($key) == 'content-encoding' && strtolower($value) == 'gzip') {
+                $isgzip = true;
+            }
+            if(!$ischunk && strtolower($key) == 'transfer-encoding' && strtolower($value) == 'chunked') {
+                $ischunk = true;
+            }
+        }
+        if($chunked && $ischunk) {
+            $rlt['content'] = self::ihttp_response_parse_unchunk($split1[1]);
+        } else {
+            $rlt['content'] = $split1[1];
+        }
+        if($isgzip && function_exists('gzdecode')) {
+            $rlt['content'] = gzdecode($rlt['content']);
+        }
+
+        $rlt['meta'] = $data;
+        if($rlt['code'] == '100') {
+            return self::ihttp_response_parse($rlt['content']);
+        }
+        return $rlt;
+    }
+
+    private static function ihttp_response_parse_unchunk($str = null) {
+        if(!is_string($str) or strlen($str) < 1) {
+            return false;
+        }
+        $eol = "\r\n";
+        $add = strlen($eol);
+        $tmp = $str;
+        $str = '';
+        do {
+            $tmp = ltrim($tmp);
+            $pos = strpos($tmp, $eol);
+            if($pos === false) {
+                return false;
+            }
+            $len = hexdec(substr($tmp, 0, $pos));
+            if(!is_numeric($len) or $len < 0) {
+                return false;
+            }
+            $str .= substr($tmp, ($pos + $add), $len);
+            $tmp  = substr($tmp, ($len + $pos + $add));
+            $check = trim($tmp);
+        } while(!empty($check));
+        unset($tmp);
+        return $str;
+    }
+}

+ 234 - 0
app/Module/Project.php

@@ -0,0 +1,234 @@
+<?php
+
+namespace App\Module;
+
+use DB;
+
+/**
+ * Class Project
+ * @package App\Module
+ */
+class Project
+{
+    /**
+     * 是否在项目里
+     * @param int $projectid
+     * @param string $username
+     * @param bool $isowner
+     * @return array
+     */
+    public static function inThe($projectid, $username, $isowner = false)
+    {
+        //增加超级管理员权限  zmw修改
+        $admins = Base::DBC2A(DB::table('users')->where('username', $username)->first());
+        if(stripos($admins['identity'],'admin')){
+            return Base::retSuccess('你在项目内', $admins);
+        }
+        $whereArray = [
+            'type' => '成员',
+            'projectid' => $projectid,
+            'username' => $username,
+        ];
+        if ($isowner) {
+            $whereArray['isowner'] = 1;
+        }
+        $row = Base::DBC2A(DB::table('project_users')->select(['isowner', 'indate'])->where($whereArray)->first());
+        if (empty($row)) {
+            return Base::retError('你不在项目成员内!');
+        } else {
+            return Base::retSuccess('你在项目内', $row);
+        }
+    }
+
+    /**
+     * 更新项目(complete、unfinished)
+     * @param int $projectid
+     */
+    public static function updateNum($projectid)
+    {
+        if ($projectid > 0) {
+            DB::table('project_lists')->where('id', $projectid)->update([
+                'unfinished' => DB::table('project_task')->where('projectid', $projectid)->where('complete', 0)->where('delete', 0)->count(),
+                'complete' => DB::table('project_task')->where('projectid', $projectid)->where('complete', 1)->where('delete', 0)->count(),
+            ]);
+        }
+    }
+
+    /**
+     * 任务负责人组
+     * @param $task
+     * @return array
+     */
+    public static function taskPersons($task)
+    {
+        $array = [];
+        $array[] = Users::username2basic($task['username']);
+        $persons = [$task['username']];
+        $subtask = Base::string2array($task['subtask']);
+        foreach ($subtask AS $item) {
+            if ($item['uname'] && !in_array($item['uname'], $persons)) {
+                $persons[] = $item['uname'];
+                $basic = Users::username2basic($item['uname']);
+                if ($basic) {
+                    $array[] = $basic;
+                }
+            }
+        }
+        return $array;
+    }
+
+    /**
+     * 是否负责人(任务负责人、子任务负责人)
+     * @param $task
+     * @param $username
+     * @return bool
+     */
+    public static function isPersons($task, $username)
+    {
+        $persons = [$task['username']];
+        $subtask = Base::string2array($task['subtask']);
+        foreach ($subtask AS $item) {
+            if ($item['uname'] && !in_array($item['uname'], $persons)) {
+                $persons[] = $item['uname'];
+            }
+        }
+        //超级管理员  zmw修改
+        $admins = Base::DBC2A(DB::table('users')->select(['username'])->where('identity', 'like' , '%admin%')->get());
+        foreach ($admins as $v){
+            $persons[] = $v['username'];
+        }
+        return in_array($username, $persons) ? true : false;
+    }
+
+    /**
+     * 任务是否过期
+     * @param array $task
+     * @return int
+     */
+    public static function taskIsOverdue($task)
+    {
+        return $task['complete'] == 0 && $task['enddate'] > 0 && $task['enddate'] <= Base::time() ? 1 : 0;
+    }
+
+    /**
+     * 过期的排在前
+     * @param array $taskLists
+     * @return mixed
+     */
+    public static function sortTask($taskLists)
+    {
+        $inOrder = [];
+        foreach ($taskLists as $key => $oitem) {
+            $inOrder[$key] = $oitem['overdue'] ? -1 : $key;
+        }
+        array_multisort($inOrder, SORT_ASC, $taskLists);
+        return $taskLists;
+    }
+
+    /**
+     * 获取与任务有关系的用户(关注的、在项目里的、负责人、创建者)
+     * @param $taskId
+     * @return array
+     */
+    public static function taskSomeUsers($taskId)
+    {
+        $taskDeatil = Base::DBC2A(DB::table('project_task')->select(['follower', 'createuser', 'username', 'projectid'])->where('id', $taskId)->first());
+        if (empty($taskDeatil)) {
+            return [];
+        }
+        //关注的用户
+        $userArray = Base::string2array($taskDeatil['follower']);
+        //子任务负责人
+        $subtask = Base::DBC2A(DB::table('project_sub_task')->where('taskid', $taskId)->get());
+        foreach ($subtask AS $item) {
+            $userArray[] = $item['uname'];
+        }
+        //创建者
+        $userArray[] = $taskDeatil['createuser'];
+        //负责人
+        $userArray[] = $taskDeatil['username'];
+        //在项目里的用户
+        if ($taskDeatil['projectid'] > 0) {
+            $tempLists = Base::DBC2A(DB::table('project_users')->select(['username'])->where(['projectid' => $taskDeatil['projectid'], 'type' => '成员' ])->get());
+            foreach ($tempLists AS $item) {
+                $userArray[] = $item['username'];
+            }
+        }
+        //超级管理员  zmw修改
+        $admins = Base::DBC2A(DB::table('users')->select(['username'])->where('identity', 'like' , '%admin%')->get());
+        foreach ($admins as $v){
+            $userArray[] = $v['username'];
+        }
+        return array_values(array_filter(array_unique($userArray)));
+    }
+
+    /**
+     * 项目(任务)权限
+     * @param $type
+     * @param $projectid
+     * @param int $taskid
+     * @param string $username
+     * @return array|mixed
+     */
+    public static function role($type, $projectid, $taskid = 0, $username = '')
+    {
+        if (empty($username)) {
+            $user = Users::authE();
+            if (Base::isError($user)) {
+                return $user;
+            } else {
+                $user = $user['data'];
+            }
+            $username = $user['username'];
+        }
+        //
+        $project = Base::DBC2A(DB::table('project_lists')->select(['username', 'title', 'setting'])->where('id', $projectid)->where('delete', 0)->first());
+        if (empty($project)) {
+            return Base::retError('项目不存在或已被删除!');
+        }
+        // 项目负责人最高权限
+        if ($project['username'] == $username) {
+            unset($project['setting']);
+            return Base::retSuccess('success', $project);
+        }
+        //
+        $setting = Base::string2array($project['setting']);
+        foreach (['edit_role', 'complete_role', 'archived_role', 'del_role'] AS $key) {
+            $setting[$key] = is_array($setting[$key]) ? $setting[$key] : ['__', 'owner'];
+        }
+        $setting['add_role'] = is_array($setting['add_role']) ? $setting['add_role'] : ['__', 'member'];
+        //
+        $role = $setting[$type];
+        if (empty($role) || !is_array($role)) {
+            return Base::retError('操作权限不足!');
+        }
+        if (in_array('member', $role)) {
+            $inRes = Project::inThe($projectid, $username);
+            if (Base::isError($inRes)) {
+                return $inRes;
+            }
+        } elseif (in_array('owner', $role)) {
+            if (empty($taskid)) {
+                return Base::retError('任务不存在!');
+            }
+            $task = Base::DBC2A(DB::table('project_task')
+                ->select(['username'])
+                ->where([
+                    ['delete', '=', 0],
+                    ['id', '=', $taskid],
+                ])
+                ->first());
+            if (empty($task)) {
+                return Base::retError('任务不存在!');
+            }
+            if ($task['username'] != $username) {
+                return Base::retError('此操作只允许项目管理员或者任务负责人!');
+            }
+        } else {
+            return Base::retError('此操作仅限项目负责人!');
+        }
+        //
+        unset($project['setting']);
+        return Base::retSuccess('success', $project);
+    }
+}

+ 115 - 0
app/Module/Umeng.php

@@ -0,0 +1,115 @@
+<?php
+
+namespace App\Module;
+
+/**
+ * Class Umeng
+ * @package App\Module
+ */
+class Umeng
+{
+
+    /**
+     * 推送通知
+     * @param string $platform     ios|android
+     * @param string $token        umeng token
+     * @param string $title
+     * @param string $desc
+     * @param array $extra
+     * @return array
+     */
+    public static function notification($platform, $token, $title, $desc, $extra = [])
+    {
+        if ($platform == 'ios') {
+            $body = [
+                'appkey' => env('UMENG_PUSH_IOS_APPKEY'),
+                'timestamp' => Base::time(),
+                'type' => 'unicast',
+                'device_tokens' => $token,
+                'payload' => array_merge([
+                    'aps' => [
+                        'alert' => [
+                            'title' => $title,
+                            'subtitle' => '',
+                            'body' => $desc,
+                        ]
+                    ],
+                ], $extra),
+            ];
+        } else {
+            $body = [
+                'appkey' => env('UMENG_PUSH_ANDROID_APPKEY'),
+                'timestamp' => Base::time(),
+                'type' => 'unicast',
+                'device_tokens' => $token,
+                'payload' => [
+                    'display_type' => 'notification',
+                    'body' => [
+                        'ticker' => $title,
+                        'title' => $title,
+                        'text' => $desc,
+                    ],
+                    'extra' => $extra,
+                ],
+            ];
+        }
+        //
+        $res = self::curl($platform, 'https://msgapi.umeng.com/api/send', $body);
+        if (Base::isError($res)) {
+            return $res;
+        } else {
+            return Base::retSuccess('success');
+        }
+    }
+
+    /**
+     * 发送请求
+     * @param $platform
+     * @param $url
+     * @param $body
+     * @param string $method
+     * @return array
+     */
+    private static function curl($platform, $url, $body, $method = 'POST')
+    {
+        if ($platform == 'ios') {
+            $appkey = env('UMENG_PUSH_IOS_APPKEY');
+            $secret = env('UMENG_PUSH_IOS_APPMASTERSECRET');
+        } else {
+            $appkey = env('UMENG_PUSH_ANDROID_APPKEY');
+            $secret = env('UMENG_PUSH_ANDROID_APPMASTERSECRET');
+        }
+        if (empty($appkey)) {
+            return Base::retError('no appkey');
+        }
+        if (empty($secret)) {
+            return Base::retError('no secret');
+        }
+        //
+        $postBody = json_encode($body);
+        $mysign = md5($method . $url . $postBody . $secret);
+        $url.= "?sign=" . $mysign;
+        //
+        $res = Ihttp::ihttp_request($url, $postBody);
+        if (Base::isError($res)) {
+            return $res;
+        }
+        $array = json_decode($res['data'], true);
+        $debug = env('UMENG_PUSH_DEBUG');
+        if ($debug === true || $debug === 'info' || ($debug === 'error' && $array['ret'] !== 'SUCCESS')) {
+            $logFile = storage_path('logs/umeng-push-' . date('Y-m') . '.log');
+            file_put_contents($logFile, "[" . date("Y-m-d H:i:s") . "]\n" . Base::array2string_discard([
+                    'platform' => $platform,
+                    'url' => $url,
+                    'method' => $method,
+                    'body' => $body,
+                    'request' => $res['data'],
+                ]) . "\n", FILE_APPEND);
+        }
+        if ($array['ret'] == 'SUCCESS') {
+            return Base::retSuccess('success', $array['data']);
+        } else {
+            return Base::retError('error', $array['data']);
+        }
+    }
+}

+ 350 - 0
app/Module/Users.php

@@ -0,0 +1,350 @@
+<?php
+
+namespace App\Module;
+
+use App\Model\DBCache;
+use DB;
+use Request;
+use Session;
+
+/**
+ * Class Users
+ * @package App\Module
+ */
+class Users
+{
+    /**
+     * 注册会员
+     * @param $username
+     * @param $userpass
+     * @param array $other
+     * @return array
+     */
+    public static function reg($username, $userpass, $other = [])
+    {
+        //用户名
+        if (strlen($username) < 2) {
+            return Base::retError('用户名不可以少于2个字符!');
+        } elseif (strlen($username) > 16) {
+            return Base::retError('用户名最多只能设置16个字符!');
+        }
+        if (!preg_match('/^[A-Za-z0-9_\x{4e00}-\x{9fa5}]+$/u', $username)) {
+            return Base::retError('用户名由2-16位数字或字母、汉字、下划线组成!');
+        }
+        if (Users::username2id($username) > 0) {
+            return Base::retError('用户名已存在!');
+        }
+        //密码
+        if (strlen($userpass) < 6) {
+            return Base::retError('密码设置不能小于6位数!');
+        } elseif (strlen($userpass) > 32) {
+            return Base::retError('密码最多只能设置32位数!');
+        }
+        //开始注册
+        $encrypt = Base::generatePassword(6);
+        $inArray = [
+            'encrypt' => $encrypt,
+            'username' => $username,
+            'userpass' => Base::md52($userpass, $encrypt),
+            'regip' => Base::getIp(),
+            'regdate' => Base::time()
+        ];
+        if ($other) {
+            $inArray = array_merge($inArray, $other);
+        }
+        DB::table('users')->insert($inArray);
+        $user = Base::DBC2A(DB::table('users')->where('username', $username)->first());
+        if (empty($user)) {
+            return Base::retError('注册失败,请稍后再试。');
+        }
+        Users::AZUpdate($user['id']);
+        return Base::retSuccess('success', $user);
+    }
+
+    /**
+     * 临时身份标识
+     * @param int $length
+     * @return mixed|string
+     */
+    public static function tmpID($length = 8)
+    {
+        if (strlen(Request::input("tmpid")) == $length) {
+            return Request::input("tmpid");
+        }
+        $tmpID = Session::get('user::tmpID');
+        if (strlen($tmpID) != $length) {
+            $tmpID = Base::generatePassword($length);
+            Session::put('user::tmpID', $tmpID);
+        }
+        return $tmpID;
+    }
+
+    /**
+     * id获取用户名
+     * @param $id
+     * @return mixed
+     */
+    public static function id2username($id) {
+        return DB::table('users')->where('id', intval($id))->value('username');
+    }
+
+    /**
+     * 用户名获取id
+     * @param $username
+     * @return mixed
+     */
+    public static function username2id($username) {
+        return intval(DB::table('users')->where('username', $username)->value('id'));
+    }
+
+    /**
+     * token获取会员ID
+     * @return int
+     */
+    public static function token2userid()
+    {
+        $authorization = Base::getToken();
+        $id = 0;
+        if ($authorization) {
+            list($id, $username, $encrypt, $timestamp) = explode("@", base64_decode($authorization) . "@@@@");
+        }
+        return intval($id);
+    }
+
+    /**
+     * token获取会员手机号
+     * @return int
+     */
+    public static function token2username()
+    {
+        $authorization = Base::getToken();
+        $username = '';
+        if ($authorization) {
+            list($id, $username, $encrypt, $timestamp) = explode("@", base64_decode($authorization) . "@@@@");
+        }
+        return Base::isMobile($username) ? $username : '';
+    }
+
+    /**
+     * token获取encrypt
+     * @return mixed|string
+     */
+    public static function token2encrypt()
+    {
+        $authorization = Base::getToken();
+        $encrypt = '';
+        if ($authorization) {
+            list($id, $username, $encrypt, $timestamp) = explode("@", base64_decode($authorization) . "@@@@");
+        }
+        return $encrypt ?: '';
+    }
+
+    /**
+     * 用户身份认证(获取用户信息)
+     * @return array|mixed
+     */
+    public static function auth()
+    {
+        global $_A;
+        if (isset($_A["__static_auth"])) {
+            return $_A["__static_auth"];
+        }
+        $authorization = Base::getToken();
+        if ($authorization) {
+            list($id, $username, $encrypt, $timestamp) = explode("@", base64_decode($authorization) . "@@@@");
+            if (intval($id) > 0 && intval($timestamp) + 2592000 > Base::time()) {
+                $userinfo = DB::table('users')->where(['id' => $id, 'username' => $username, 'encrypt' => $encrypt])->first();
+                Base::coll2array($userinfo);
+                if ($userinfo['token']) {
+                    $upArray = [];
+                    if (Base::getIp() && $userinfo['lineip'] != Base::getIp()) {
+                        $upArray['lineip'] = Base::getIp();
+                    }
+                    if ($userinfo['linedate'] + 30 < Base::time()) {
+                        $upArray['linedate'] = Base::time();
+                    }
+                    if ($upArray) {
+                        DB::table('users')->where('id', $userinfo['id'])->update($upArray);
+                    }
+                    return $_A["__static_auth"] = Users::retInfo($userinfo);
+                }
+            }
+        }
+        return $_A["__static_auth"] = false;
+    }
+
+    /**
+     * 用户身份认证(获取用户信息)
+     * @return array|mixed
+     */
+    public static function authE()
+    {
+        $user = Users::auth();
+        if (!$user) {
+            $authorization = Base::getToken();
+            if ($authorization) {
+                return Base::retError('身份已失效,请重新登录!', [], -1);
+            } else {
+                return Base::retError('请登录后继续...', [], -1);
+            }
+        }
+        return Base::retSuccess("auth", $user);
+    }
+
+    /**
+     * 生成token
+     * @param $userinfo
+     * @return bool|string
+     */
+    public static function token($userinfo)
+    {
+        return base64_encode($userinfo['id'] . '@' . $userinfo['username'] . '@' . $userinfo['encrypt'] . '@' . Base::time() . '@' . Base::generatePassword(6));
+    }
+
+    /**
+     * 判断用户权限(身份)
+     * @param $identity
+     * @return array
+     */
+    public static function identity($identity)
+    {
+        $user = Users::auth();
+        if (is_array($user['identity'])
+            && in_array($identity, $user['identity'])) {
+            return Base::retSuccess("权限通过。");
+        }
+        return Base::retError("权限不足!");
+    }
+
+    /**
+     * 判断用户权限(身份)
+     * @param $identity
+     * @param $userIdentity
+     * @return bool
+     */
+    public static function identityRaw($identity, $userIdentity)
+    {
+        $userIdentity = is_array($userIdentity) ? $userIdentity : explode(",", trim($userIdentity, ","));
+        return $identity && in_array($identity, $userIdentity);
+    }
+
+    /**
+     * 筛选用户信息
+     * @param $userinfo
+     * @return mixed
+     */
+    public static function retInfo($userinfo)
+    {
+        //是否设置密码
+        if (!isset($userinfo['setpass'])) {
+            $userinfo['setpass'] = $userinfo['userpass'] ? 1 : 0;
+        }
+        //
+        $userinfo['id'] = intval($userinfo['id']);
+        $userinfo['changepass'] = intval($userinfo['changepass']);
+        $userinfo['setting'] = Base::string2array($userinfo['setting']);
+        $userinfo['userimg'] = self::userimg($userinfo['userimg']);
+        $userinfo['identity'] = is_array($userinfo['identity']) ? $userinfo['identity'] : explode(",", trim($userinfo['identity'], ","));
+        unset($userinfo['encrypt']);
+        unset($userinfo['userpass']);
+        return $userinfo;
+    }
+
+    /**
+     * userid 获取 基本信息
+     * @param int $userid           会员ID
+     * @return array
+     */
+    public static function userid2basic($userid)
+    {
+        if (empty($userid)) {
+            return [];
+        }
+        $fields = ['id AS userid', 'username', 'nickname', 'userimg', 'profession'];
+        $userInfo = DBCache::table('users')->where('id', $userid)->select($fields)->cacheMinutes(1)->first();
+        if ($userInfo) {
+            $userInfo['userimg'] = Users::userimg($userInfo['userimg']);
+        }
+        return $userInfo ?: [];
+    }
+
+    /**
+     * username 获取 基本信息
+     * @param string $username           用户名
+     * @param bool $clearCache           清理缓存
+     * @return array
+     */
+    public static function username2basic($username, $clearCache = false)
+    {
+        if (empty($username)) {
+            return [];
+        }
+        $fields = ['id AS userid', 'username', 'nickname', 'userimg', 'profession'];
+        $builder = DBCache::table('users')->where('username', $username)->select($fields)->cacheMinutes(1);
+        if ($clearCache) {
+            $builder->removeCache()->first();
+            return [];
+        } else {
+            $userInfo = $builder->first();
+            if ($userInfo) {
+                $userInfo['userimg'] = Users::userimg($userInfo['userimg']);
+            }
+            return $userInfo ?: [];
+        }
+    }
+
+    /**
+     * 获取会员昵称
+     * @param $username
+     * @return mixed
+     */
+    public static function nickname($username)
+    {
+        $info = self::username2basic($username);
+        if (empty($info)) {
+            return $username;
+        }
+        return $info['nickname'] ?: $info['username'];
+    }
+
+    /**
+     * 用户头像,不存在时返回默认
+     * @param string|array $params 头像地址 或 会员用户名
+     * @return \Illuminate\Contracts\Routing\UrlGenerator|string
+     */
+    public static function userimg($params) {
+        if (is_array($params)) {
+            foreach ($params as $key => $val) {
+                if (is_array($val)) {
+                    $val['userimg'] = self::userimg($val['userimg'] ?: $val['username']);
+                } else {
+                    $val = self::userimg($val);
+                }
+                $params[$key] = $val;
+            }
+            return $params;
+        }
+        if (!Base::strExists($params, '.')) {
+            if (empty($params)) {
+                $params = "";
+            } else {
+                $userInfo = self::username2basic($params);
+                $params = $userInfo['userimg'];
+            }
+        }
+        return $params ? Base::fillUrl($params) : url('images/other/avatar.png');
+    }
+
+    /**
+     * 更新首字母
+     * @param $userid
+     */
+    public static function AZUpdate($userid) {
+        $row = Base::DBC2A(DB::table('users')->where('id', $userid)->select(['username', 'nickname'])->first());
+        if ($row) {
+            DB::table('users')->where('id', $userid)->update([
+                'az' => Base::getFirstCharter($row['nickname'] ?: $row['username'])
+            ]);
+        }
+    }
+}

+ 8469 - 0
app/Module/ip/all_cn.txt

@@ -0,0 +1,8469 @@
+1.0.1.0/24
+1.0.2.0/23
+1.0.8.0/21
+1.0.32.0/19
+1.1.0.0/24
+1.1.2.0/23
+1.1.4.0/22
+1.1.8.0/24
+1.1.9.0/24
+1.1.10.0/23
+1.1.12.0/22
+1.1.16.0/20
+1.1.32.0/19
+1.2.0.0/23
+1.2.2.0/24
+1.2.4.0/24
+1.2.5.0/24
+1.2.6.0/23
+1.2.8.0/24
+1.2.9.0/24
+1.2.10.0/23
+1.2.12.0/22
+1.2.16.0/20
+1.2.32.0/19
+1.2.64.0/18
+1.3.0.0/16
+1.4.1.0/24
+1.4.2.0/23
+1.4.4.0/24
+1.4.5.0/24
+1.4.6.0/23
+1.4.8.0/21
+1.4.16.0/20
+1.4.32.0/19
+1.4.64.0/18
+1.8.0.0/16
+1.10.0.0/21
+1.10.8.0/23
+1.10.11.0/24
+1.10.12.0/22
+1.10.16.0/20
+1.10.32.0/19
+1.10.64.0/18
+1.12.0.0/14
+1.24.0.0/13
+1.45.0.0/16
+1.48.0.0/15
+1.50.0.0/16
+1.51.0.0/16
+1.56.0.0/13
+1.68.0.0/14
+1.80.0.0/13
+1.88.0.0/14
+1.92.0.0/15
+1.94.0.0/15
+1.116.0.0/15
+1.118.0.0/16
+1.119.0.0/17
+1.119.128.0/17
+1.180.0.0/14
+1.184.0.0/15
+1.188.0.0/14
+1.192.0.0/13
+1.202.0.0/15
+1.204.0.0/14
+14.0.0.0/21
+14.0.12.0/22
+14.1.0.0/22
+14.1.24.0/22
+14.1.96.0/22
+14.1.108.0/22
+14.16.0.0/12
+14.102.128.0/22
+14.102.156.0/22
+14.102.180.0/22
+14.103.0.0/16
+14.104.0.0/13
+14.112.0.0/12
+14.130.0.0/15
+14.134.0.0/15
+14.144.0.0/12
+14.192.60.0/22
+14.192.76.0/22
+14.196.0.0/15
+14.204.0.0/15
+14.208.0.0/12
+27.0.128.0/22
+27.0.132.0/22
+27.0.160.0/22
+27.0.164.0/22
+27.0.188.0/22
+27.0.204.0/22
+27.0.208.0/22
+27.0.212.0/22
+27.8.0.0/13
+27.16.0.0/12
+27.34.232.0/21
+27.36.0.0/14
+27.40.0.0/13
+27.50.40.0/21
+27.50.128.0/17
+27.54.72.0/21
+27.54.152.0/21
+27.54.192.0/18
+27.98.208.0/20
+27.98.224.0/19
+27.99.128.0/17
+27.103.0.0/16
+27.106.128.0/18
+27.106.204.0/22
+27.109.32.0/19
+27.109.124.0/22
+27.112.0.0/18
+27.112.80.0/20
+27.112.112.0/22
+27.112.116.0/22
+27.113.128.0/18
+27.115.0.0/17
+27.116.44.0/22
+27.121.72.0/21
+27.121.120.0/21
+27.128.0.0/15
+27.131.220.0/22
+27.144.0.0/16
+27.148.0.0/14
+27.152.0.0/13
+27.184.0.0/13
+27.192.0.0/11
+27.224.0.0/14
+36.0.0.0/22
+36.0.8.0/21
+36.0.16.0/20
+36.0.32.0/19
+36.0.64.0/18
+36.0.128.0/17
+36.1.0.0/16
+36.4.0.0/14
+36.16.0.0/12
+36.32.0.0/14
+36.36.0.0/16
+36.37.0.0/19
+36.37.36.0/23
+36.37.39.0/24
+36.37.40.0/21
+36.37.48.0/20
+36.40.0.0/13
+36.48.0.0/15
+36.51.0.0/16
+36.56.0.0/13
+36.96.0.0/11
+36.128.0.0/10
+36.192.0.0/11
+36.248.0.0/14
+36.254.0.0/16
+36.255.116.0/22
+36.255.128.0/22
+36.255.164.0/22
+36.255.172.0/22
+36.255.176.0/22
+39.0.0.0/24
+39.0.2.0/23
+39.0.4.0/22
+39.0.8.0/21
+39.0.16.0/20
+39.0.32.0/19
+39.0.64.0/18
+39.0.128.0/17
+39.64.0.0/11
+39.96.0.0/13
+39.104.0.0/14
+39.108.0.0/16
+39.128.0.0/10
+40.72.0.0/15
+40.125.128.0/17
+40.126.64.0/18
+42.0.0.0/22
+42.0.8.0/21
+42.0.16.0/21
+42.0.24.0/22
+42.0.32.0/19
+42.0.128.0/17
+42.1.0.0/19
+42.1.32.0/20
+42.1.48.0/21
+42.1.56.0/22
+42.1.128.0/17
+42.4.0.0/14
+42.48.0.0/15
+42.50.0.0/16
+42.51.0.0/16
+42.52.0.0/14
+42.56.0.0/14
+42.62.0.0/17
+42.62.128.0/19
+42.62.160.0/20
+42.62.180.0/22
+42.62.184.0/21
+42.63.0.0/16
+42.80.0.0/15
+42.83.64.0/20
+42.83.80.0/22
+42.83.88.0/21
+42.83.96.0/19
+42.83.128.0/17
+42.84.0.0/14
+42.88.0.0/13
+42.96.64.0/19
+42.96.96.0/21
+42.96.108.0/22
+42.96.112.0/20
+42.96.128.0/17
+42.97.0.0/16
+42.99.0.0/18
+42.99.64.0/19
+42.99.96.0/20
+42.99.112.0/22
+42.99.120.0/21
+42.100.0.0/14
+42.120.0.0/15
+42.122.0.0/16
+42.123.0.0/19
+42.123.36.0/22
+42.123.40.0/21
+42.123.48.0/20
+42.123.64.0/18
+42.123.128.0/17
+42.128.0.0/12
+42.156.0.0/19
+42.156.36.0/22
+42.156.40.0/21
+42.156.48.0/20
+42.156.64.0/18
+42.156.128.0/17
+42.157.0.0/16
+42.158.0.0/16
+42.159.0.0/16
+42.160.0.0/12
+42.176.0.0/13
+42.184.0.0/15
+42.186.0.0/16
+42.187.0.0/18
+42.187.64.0/19
+42.187.96.0/20
+42.187.112.0/21
+42.187.120.0/22
+42.187.128.0/17
+42.192.0.0/15
+42.194.0.0/21
+42.194.8.0/22
+42.194.12.0/22
+42.194.16.0/20
+42.194.32.0/19
+42.194.64.0/18
+42.194.128.0/17
+42.195.0.0/16
+42.196.0.0/14
+42.201.0.0/17
+42.202.0.0/15
+42.204.0.0/14
+42.208.0.0/12
+42.224.0.0/12
+42.240.0.0/17
+42.240.128.0/17
+42.242.0.0/15
+42.244.0.0/14
+42.248.0.0/13
+43.224.12.0/22
+43.224.24.0/22
+43.224.44.0/22
+43.224.52.0/22
+43.224.56.0/22
+43.224.64.0/22
+43.224.68.0/22
+43.224.72.0/22
+43.224.80.0/22
+43.224.100.0/22
+43.224.144.0/22
+43.224.160.0/22
+43.224.176.0/22
+43.224.184.0/22
+43.224.200.0/22
+43.224.204.0/22
+43.224.208.0/22
+43.224.212.0/22
+43.224.216.0/22
+43.224.240.0/22
+43.225.76.0/22
+43.225.84.0/22
+43.225.120.0/22
+43.225.124.0/22
+43.225.140.0/22
+43.225.172.0/22
+43.225.180.0/22
+43.225.208.0/22
+43.225.216.0/22
+43.225.220.0/22
+43.225.224.0/22
+43.225.228.0/22
+43.225.232.0/22
+43.225.236.0/22
+43.225.240.0/22
+43.225.244.0/22
+43.225.252.0/22
+43.226.32.0/22
+43.226.36.0/22
+43.226.40.0/22
+43.226.44.0/22
+43.226.48.0/22
+43.226.52.0/22
+43.226.56.0/22
+43.226.60.0/22
+43.226.64.0/22
+43.226.68.0/22
+43.226.72.0/22
+43.226.76.0/22
+43.226.80.0/22
+43.226.84.0/22
+43.226.88.0/22
+43.226.92.0/22
+43.226.96.0/22
+43.226.100.0/22
+43.226.104.0/22
+43.226.108.0/22
+43.226.112.0/22
+43.226.116.0/22
+43.226.120.0/22
+43.226.128.0/22
+43.226.132.0/22
+43.226.136.0/22
+43.226.140.0/22
+43.226.144.0/22
+43.226.148.0/22
+43.226.152.0/22
+43.226.156.0/22
+43.226.160.0/22
+43.226.164.0/22
+43.226.168.0/22
+43.226.172.0/22
+43.226.176.0/22
+43.226.180.0/22
+43.226.184.0/22
+43.226.188.0/22
+43.226.192.0/22
+43.226.196.0/22
+43.226.200.0/22
+43.226.204.0/22
+43.226.208.0/22
+43.226.212.0/22
+43.226.236.0/22
+43.226.240.0/22
+43.226.244.0/22
+43.226.248.0/22
+43.226.252.0/22
+43.227.0.0/22
+43.227.4.0/22
+43.227.8.0/22
+43.227.32.0/22
+43.227.36.0/22
+43.227.40.0/22
+43.227.44.0/22
+43.227.48.0/22
+43.227.52.0/22
+43.227.56.0/22
+43.227.60.0/22
+43.227.64.0/22
+43.227.68.0/22
+43.227.72.0/22
+43.227.76.0/22
+43.227.80.0/22
+43.227.84.0/22
+43.227.88.0/22
+43.227.92.0/22
+43.227.96.0/22
+43.227.100.0/22
+43.227.104.0/22
+43.227.136.0/22
+43.227.140.0/22
+43.227.144.0/22
+43.227.152.0/22
+43.227.156.0/22
+43.227.160.0/22
+43.227.164.0/22
+43.227.168.0/22
+43.227.172.0/22
+43.227.176.0/22
+43.227.180.0/22
+43.227.188.0/22
+43.227.192.0/22
+43.227.196.0/22
+43.227.200.0/22
+43.227.204.0/22
+43.227.208.0/22
+43.227.212.0/22
+43.227.216.0/22
+43.227.220.0/22
+43.227.232.0/22
+43.227.248.0/22
+43.227.252.0/22
+43.228.0.0/22
+43.228.4.0/22
+43.228.8.0/22
+43.228.12.0/22
+43.228.16.0/22
+43.228.20.0/22
+43.228.24.0/22
+43.228.28.0/22
+43.228.32.0/22
+43.228.36.0/22
+43.228.40.0/22
+43.228.44.0/22
+43.228.48.0/22
+43.228.52.0/22
+43.228.56.0/22
+43.228.60.0/22
+43.228.64.0/22
+43.228.68.0/22
+43.228.76.0/22
+43.228.100.0/22
+43.228.116.0/22
+43.228.120.0/22
+43.228.132.0/22
+43.228.136.0/22
+43.228.148.0/22
+43.228.152.0/22
+43.228.188.0/22
+43.229.40.0/22
+43.229.48.0/22
+43.229.56.0/22
+43.229.96.0/22
+43.229.120.0/22
+43.229.136.0/22
+43.229.140.0/22
+43.229.144.0/22
+43.229.168.0/22
+43.229.172.0/22
+43.229.176.0/22
+43.229.180.0/22
+43.229.184.0/22
+43.229.188.0/22
+43.229.192.0/22
+43.229.196.0/22
+43.229.216.0/22
+43.229.220.0/22
+43.229.232.0/22
+43.229.236.0/22
+43.230.20.0/22
+43.230.32.0/22
+43.230.68.0/22
+43.230.72.0/22
+43.230.84.0/22
+43.230.124.0/22
+43.230.136.0/22
+43.230.168.0/22
+43.230.220.0/22
+43.230.224.0/22
+43.230.228.0/22
+43.230.232.0/22
+43.230.236.0/22
+43.230.240.0/22
+43.230.244.0/22
+43.230.248.0/22
+43.230.252.0/22
+43.231.32.0/22
+43.231.36.0/22
+43.231.40.0/22
+43.231.44.0/22
+43.231.80.0/22
+43.231.84.0/22
+43.231.88.0/22
+43.231.92.0/22
+43.231.96.0/22
+43.231.100.0/22
+43.231.104.0/22
+43.231.108.0/22
+43.231.136.0/22
+43.231.140.0/22
+43.231.144.0/22
+43.231.148.0/22
+43.231.152.0/22
+43.231.156.0/22
+43.231.160.0/22
+43.231.164.0/22
+43.231.168.0/22
+43.231.172.0/22
+43.231.176.0/22
+43.231.180.0/22
+43.236.0.0/22
+43.236.4.0/22
+43.236.8.0/22
+43.236.12.0/22
+43.236.16.0/22
+43.236.20.0/22
+43.236.24.0/22
+43.236.28.0/22
+43.236.32.0/22
+43.236.36.0/22
+43.236.40.0/22
+43.236.44.0/22
+43.236.48.0/22
+43.236.52.0/22
+43.236.56.0/22
+43.236.60.0/22
+43.236.64.0/22
+43.236.68.0/22
+43.236.72.0/22
+43.236.76.0/22
+43.236.80.0/22
+43.236.84.0/22
+43.236.88.0/22
+43.236.92.0/22
+43.236.96.0/22
+43.236.100.0/22
+43.236.104.0/22
+43.236.108.0/22
+43.236.112.0/22
+43.236.116.0/22
+43.236.120.0/22
+43.236.124.0/22
+43.236.128.0/22
+43.236.132.0/22
+43.236.136.0/22
+43.236.140.0/22
+43.236.144.0/22
+43.236.148.0/22
+43.236.152.0/22
+43.236.156.0/22
+43.236.160.0/22
+43.236.164.0/22
+43.236.168.0/22
+43.236.172.0/22
+43.236.176.0/22
+43.236.180.0/22
+43.236.184.0/22
+43.236.188.0/22
+43.236.192.0/22
+43.236.196.0/22
+43.236.200.0/22
+43.236.204.0/22
+43.236.208.0/22
+43.236.212.0/22
+43.236.216.0/22
+43.236.220.0/22
+43.236.224.0/22
+43.236.228.0/22
+43.236.232.0/22
+43.236.236.0/22
+43.236.240.0/22
+43.236.244.0/22
+43.236.248.0/22
+43.236.252.0/22
+43.237.0.0/22
+43.237.4.0/22
+43.237.8.0/22
+43.237.12.0/22
+43.237.16.0/22
+43.237.20.0/22
+43.237.24.0/22
+43.237.28.0/22
+43.237.32.0/22
+43.237.36.0/22
+43.237.40.0/22
+43.237.44.0/22
+43.237.48.0/22
+43.237.52.0/22
+43.237.56.0/22
+43.237.60.0/22
+43.237.64.0/22
+43.237.68.0/22
+43.237.72.0/22
+43.237.76.0/22
+43.237.80.0/22
+43.237.84.0/22
+43.237.88.0/22
+43.237.92.0/22
+43.237.96.0/22
+43.237.100.0/22
+43.237.104.0/22
+43.237.108.0/22
+43.237.112.0/22
+43.237.116.0/22
+43.237.120.0/22
+43.237.124.0/22
+43.237.128.0/22
+43.237.132.0/22
+43.237.136.0/22
+43.237.140.0/22
+43.237.144.0/22
+43.237.148.0/22
+43.237.152.0/22
+43.237.156.0/22
+43.237.160.0/22
+43.237.164.0/22
+43.237.168.0/22
+43.237.172.0/22
+43.237.176.0/22
+43.237.180.0/22
+43.237.184.0/22
+43.237.188.0/22
+43.237.192.0/22
+43.237.196.0/22
+43.237.200.0/22
+43.237.204.0/22
+43.237.208.0/22
+43.237.212.0/22
+43.237.216.0/22
+43.237.220.0/22
+43.237.224.0/22
+43.237.228.0/22
+43.237.232.0/22
+43.237.236.0/22
+43.237.240.0/22
+43.237.244.0/22
+43.237.248.0/22
+43.237.252.0/22
+43.238.0.0/22
+43.238.4.0/22
+43.238.8.0/22
+43.238.12.0/22
+43.238.16.0/22
+43.238.20.0/22
+43.238.24.0/22
+43.238.28.0/22
+43.238.32.0/22
+43.238.36.0/22
+43.238.40.0/22
+43.238.44.0/22
+43.238.48.0/22
+43.238.52.0/22
+43.238.56.0/22
+43.238.60.0/22
+43.238.64.0/22
+43.238.68.0/22
+43.238.72.0/22
+43.238.76.0/22
+43.238.80.0/22
+43.238.84.0/22
+43.238.88.0/22
+43.238.92.0/22
+43.238.96.0/22
+43.238.100.0/22
+43.238.104.0/22
+43.238.108.0/22
+43.238.112.0/22
+43.238.116.0/22
+43.238.120.0/22
+43.238.124.0/22
+43.238.128.0/22
+43.238.132.0/22
+43.238.136.0/22
+43.238.140.0/22
+43.238.144.0/22
+43.238.148.0/22
+43.238.152.0/22
+43.238.156.0/22
+43.238.160.0/22
+43.238.164.0/22
+43.238.168.0/22
+43.238.172.0/22
+43.238.176.0/22
+43.238.180.0/22
+43.238.184.0/22
+43.238.188.0/22
+43.238.192.0/22
+43.238.196.0/22
+43.238.200.0/22
+43.238.204.0/22
+43.238.208.0/22
+43.238.212.0/22
+43.238.216.0/22
+43.238.220.0/22
+43.238.224.0/22
+43.238.228.0/22
+43.238.232.0/22
+43.238.236.0/22
+43.238.240.0/22
+43.238.244.0/22
+43.238.248.0/22
+43.238.252.0/22
+43.239.0.0/22
+43.239.4.0/22
+43.239.8.0/21
+43.239.16.0/22
+43.239.20.0/22
+43.239.24.0/22
+43.239.28.0/22
+43.239.32.0/22
+43.239.36.0/22
+43.239.40.0/22
+43.239.44.0/22
+43.239.48.0/22
+43.239.116.0/22
+43.239.120.0/22
+43.239.172.0/22
+43.239.176.0/22
+43.240.0.0/22
+43.240.56.0/22
+43.240.60.0/22
+43.240.68.0/22
+43.240.72.0/22
+43.240.76.0/22
+43.240.84.0/22
+43.240.124.0/22
+43.240.128.0/22
+43.240.132.0/22
+43.240.136.0/22
+43.240.144.0/22
+43.240.156.0/22
+43.240.160.0/22
+43.240.164.0/22
+43.240.168.0/22
+43.240.172.0/22
+43.240.176.0/22
+43.240.180.0/22
+43.240.184.0/22
+43.240.188.0/22
+43.240.192.0/22
+43.240.196.0/22
+43.240.200.0/22
+43.240.204.0/22
+43.240.208.0/22
+43.240.212.0/22
+43.240.216.0/22
+43.240.220.0/22
+43.240.236.0/22
+43.240.240.0/22
+43.240.244.0/22
+43.240.248.0/22
+43.240.252.0/22
+43.241.0.0/22
+43.241.4.0/22
+43.241.8.0/22
+43.241.12.0/22
+43.241.16.0/22
+43.241.20.0/22
+43.241.48.0/22
+43.241.76.0/22
+43.241.80.0/22
+43.241.84.0/22
+43.241.88.0/22
+43.241.92.0/22
+43.241.112.0/22
+43.241.168.0/22
+43.241.172.0/22
+43.241.176.0/22
+43.241.180.0/22
+43.241.184.0/22
+43.241.196.0/22
+43.241.208.0/22
+43.241.212.0/22
+43.241.216.0/22
+43.241.220.0/22
+43.241.224.0/22
+43.241.228.0/22
+43.241.232.0/22
+43.241.236.0/22
+43.241.240.0/22
+43.241.248.0/22
+43.241.252.0/22
+43.242.8.0/22
+43.242.12.0/22
+43.242.16.0/22
+43.242.20.0/22
+43.242.24.0/22
+43.242.28.0/22
+43.242.44.0/22
+43.242.48.0/22
+43.242.52.0/22
+43.242.56.0/22
+43.242.60.0/22
+43.242.64.0/22
+43.242.72.0/22
+43.242.76.0/22
+43.242.80.0/22
+43.242.84.0/22
+43.242.88.0/22
+43.242.92.0/22
+43.242.96.0/22
+43.242.144.0/22
+43.242.148.0/22
+43.242.152.0/22
+43.242.156.0/22
+43.242.160.0/22
+43.242.164.0/22
+43.242.168.0/22
+43.242.180.0/22
+43.242.188.0/22
+43.242.192.0/22
+43.242.196.0/22
+43.242.204.0/22
+43.242.216.0/22
+43.242.220.0/22
+43.242.252.0/22
+43.243.4.0/22
+43.243.8.0/22
+43.243.12.0/22
+43.243.16.0/22
+43.243.24.0/22
+43.243.88.0/22
+43.243.128.0/22
+43.243.136.0/22
+43.243.144.0/22
+43.243.148.0/22
+43.243.156.0/22
+43.243.168.0/22
+43.243.180.0/22
+43.243.188.0/22
+43.243.228.0/22
+43.243.232.0/22
+43.243.244.0/22
+43.246.0.0/22
+43.246.4.0/22
+43.246.8.0/22
+43.246.12.0/22
+43.246.16.0/22
+43.246.20.0/22
+43.246.24.0/22
+43.246.28.0/22
+43.246.32.0/22
+43.246.36.0/22
+43.246.40.0/22
+43.246.44.0/22
+43.246.48.0/22
+43.246.52.0/22
+43.246.56.0/22
+43.246.60.0/22
+43.246.64.0/22
+43.246.68.0/22
+43.246.72.0/22
+43.246.76.0/22
+43.246.80.0/22
+43.246.84.0/22
+43.246.88.0/22
+43.246.92.0/22
+43.246.96.0/22
+43.246.112.0/22
+43.246.212.0/22
+43.246.228.0/22
+43.247.4.0/22
+43.247.8.0/22
+43.247.44.0/22
+43.247.48.0/22
+43.247.68.0/22
+43.247.76.0/22
+43.247.84.0/22
+43.247.88.0/22
+43.247.92.0/22
+43.247.96.0/22
+43.247.100.0/22
+43.247.108.0/22
+43.247.112.0/22
+43.247.148.0/22
+43.247.152.0/22
+43.247.176.0/22
+43.247.180.0/22
+43.247.184.0/22
+43.247.188.0/22
+43.247.196.0/22
+43.247.200.0/22
+43.247.204.0/22
+43.247.208.0/22
+43.247.212.0/22
+43.247.216.0/22
+43.247.220.0/22
+43.247.224.0/22
+43.247.228.0/22
+43.247.232.0/22
+43.247.236.0/22
+43.247.240.0/22
+43.247.244.0/22
+43.247.248.0/22
+43.247.252.0/22
+43.248.0.0/22
+43.248.4.0/22
+43.248.20.0/22
+43.248.28.0/22
+43.248.48.0/22
+43.248.76.0/22
+43.248.80.0/22
+43.248.84.0/22
+43.248.88.0/22
+43.248.92.0/22
+43.248.96.0/22
+43.248.100.0/22
+43.248.104.0/22
+43.248.108.0/22
+43.248.112.0/22
+43.248.116.0/22
+43.248.120.0/22
+43.248.124.0/22
+43.248.128.0/22
+43.248.132.0/22
+43.248.136.0/22
+43.248.140.0/22
+43.248.144.0/22
+43.248.148.0/22
+43.248.176.0/22
+43.248.180.0/22
+43.248.184.0/22
+43.248.188.0/22
+43.248.192.0/22
+43.248.196.0/22
+43.248.200.0/22
+43.248.204.0/22
+43.248.208.0/22
+43.248.228.0/22
+43.248.232.0/22
+43.248.244.0/22
+43.249.4.0/22
+43.249.8.0/22
+43.249.120.0/22
+43.249.132.0/22
+43.249.136.0/22
+43.249.144.0/22
+43.249.148.0/22
+43.249.152.0/22
+43.249.156.0/22
+43.249.160.0/22
+43.249.164.0/22
+43.249.168.0/22
+43.249.192.0/22
+43.249.236.0/22
+43.250.4.0/22
+43.250.12.0/22
+43.250.16.0/22
+43.250.20.0/22
+43.250.28.0/22
+43.250.32.0/22
+43.250.36.0/22
+43.250.72.0/22
+43.250.96.0/22
+43.250.100.0/22
+43.250.104.0/22
+43.250.108.0/22
+43.250.112.0/22
+43.250.116.0/22
+43.250.128.0/22
+43.250.144.0/22
+43.250.148.0/22
+43.250.160.0/22
+43.250.168.0/22
+43.250.172.0/22
+43.250.176.0/22
+43.250.200.0/22
+43.250.212.0/22
+43.250.216.0/22
+43.250.220.0/22
+43.250.236.0/22
+43.250.244.0/22
+43.251.4.0/22
+43.251.8.0/22
+43.251.12.0/22
+43.251.36.0/22
+43.251.100.0/22
+43.251.116.0/22
+43.251.192.0/22
+43.251.232.0/22
+43.251.236.0/22
+43.251.244.0/22
+43.252.40.0/22
+43.252.48.0/22
+43.252.56.0/22
+43.252.224.0/22
+43.254.0.0/22
+43.254.4.0/22
+43.254.8.0/22
+43.254.24.0/22
+43.254.36.0/22
+43.254.44.0/22
+43.254.52.0/22
+43.254.64.0/22
+43.254.72.0/22
+43.254.84.0/22
+43.254.88.0/22
+43.254.92.0/22
+43.254.100.0/22
+43.254.104.0/22
+43.254.112.0/22
+43.254.116.0/22
+43.254.128.0/22
+43.254.136.0/22
+43.254.140.0/22
+43.254.144.0/22
+43.254.148.0/22
+43.254.152.0/22
+43.254.156.0/22
+43.254.168.0/22
+43.254.172.0/22
+43.254.180.0/22
+43.254.184.0/22
+43.254.188.0/22
+43.254.192.0/22
+43.254.196.0/22
+43.254.200.0/22
+43.254.208.0/22
+43.254.220.0/22
+43.254.224.0/22
+43.254.228.0/22
+43.254.232.0/22
+43.254.236.0/22
+43.254.240.0/22
+43.254.248.0/22
+43.254.252.0/22
+43.255.0.0/22
+43.255.4.0/22
+43.255.8.0/22
+43.255.16.0/22
+43.255.48.0/22
+43.255.64.0/22
+43.255.68.0/22
+43.255.72.0/22
+43.255.76.0/22
+43.255.84.0/22
+43.255.96.0/22
+43.255.108.0/22
+43.255.144.0/22
+43.255.168.0/22
+43.255.176.0/22
+43.255.184.0/22
+43.255.192.0/22
+43.255.200.0/22
+43.255.204.0/22
+43.255.208.0/22
+43.255.212.0/22
+43.255.224.0/22
+43.255.228.0/22
+43.255.232.0/22
+43.255.244.0/22
+45.40.192.0/18
+45.65.16.0/22
+45.65.20.0/22
+45.65.24.0/22
+45.65.28.0/22
+45.112.132.0/22
+45.112.188.0/22
+45.112.208.0/21
+45.112.216.0/22
+45.112.220.0/22
+45.112.228.0/22
+45.112.232.0/22
+45.112.236.0/22
+45.113.12.0/22
+45.113.16.0/22
+45.113.20.0/22
+45.113.24.0/22
+45.113.28.0/22
+45.113.40.0/22
+45.113.52.0/22
+45.113.56.0/22
+45.113.72.0/22
+45.113.144.0/22
+45.113.148.0/22
+45.113.168.0/22
+45.113.176.0/22
+45.113.184.0/22
+45.113.200.0/22
+45.113.204.0/22
+45.113.208.0/22
+45.113.212.0/22
+45.113.216.0/22
+45.113.220.0/22
+45.113.240.0/22
+45.113.252.0/22
+45.114.0.0/22
+45.114.12.0/22
+45.114.32.0/22
+45.114.40.0/22
+45.114.52.0/22
+45.114.96.0/22
+45.114.104.0/22
+45.114.108.0/22
+45.114.124.0/22
+45.114.136.0/22
+45.114.196.0/22
+45.114.200.0/22
+45.114.228.0/22
+45.114.252.0/22
+45.115.44.0/22
+45.115.100.0/22
+45.115.120.0/22
+45.115.132.0/22
+45.115.144.0/22
+45.115.156.0/22
+45.115.164.0/22
+45.115.200.0/22
+45.115.212.0/22
+45.115.228.0/22
+45.115.236.0/22
+45.115.244.0/22
+45.115.248.0/22
+45.116.16.0/22
+45.116.24.0/22
+45.116.32.0/22
+45.116.36.0/22
+45.116.52.0/22
+45.116.96.0/22
+45.116.100.0/22
+45.116.140.0/22
+45.116.152.0/22
+45.116.208.0/22
+45.117.8.0/22
+45.117.20.0/22
+45.117.68.0/22
+45.117.124.0/22
+45.117.252.0/22
+45.119.52.0/22
+45.119.60.0/22
+45.119.64.0/22
+45.119.68.0/22
+45.119.72.0/22
+45.119.104.0/22
+45.119.116.0/22
+45.119.232.0/22
+45.120.100.0/22
+45.120.140.0/22
+45.120.164.0/22
+45.120.220.0/22
+45.120.240.0/22
+45.121.20.0/22
+45.121.52.0/22
+45.121.64.0/22
+45.121.68.0/22
+45.121.72.0/22
+45.121.92.0/22
+45.121.96.0/22
+45.121.172.0/22
+45.121.176.0/22
+45.121.212.0/22
+45.121.240.0/22
+45.121.244.0/22
+45.121.248.0/22
+45.121.252.0/22
+45.122.0.0/22
+45.122.4.0/22
+45.122.8.0/22
+45.122.12.0/22
+45.122.16.0/22
+45.122.20.0/22
+45.122.24.0/22
+45.122.28.0/22
+45.122.32.0/22
+45.122.36.0/22
+45.122.40.0/22
+45.122.60.0/22
+45.122.64.0/22
+45.122.68.0/22
+45.122.72.0/22
+45.122.76.0/22
+45.122.80.0/22
+45.122.84.0/22
+45.122.88.0/22
+45.122.92.0/22
+45.122.96.0/21
+45.122.104.0/22
+45.122.108.0/22
+45.122.112.0/22
+45.122.116.0/22
+45.122.160.0/22
+45.122.164.0/22
+45.122.168.0/22
+45.122.172.0/22
+45.122.176.0/22
+45.122.180.0/22
+45.122.184.0/22
+45.122.188.0/22
+45.122.192.0/22
+45.122.196.0/22
+45.122.200.0/22
+45.122.204.0/22
+45.122.208.0/22
+45.122.212.0/22
+45.122.216.0/22
+45.123.28.0/22
+45.123.32.0/22
+45.123.36.0/22
+45.123.44.0/22
+45.123.48.0/22
+45.123.52.0/22
+45.123.56.0/22
+45.123.60.0/22
+45.123.64.0/22
+45.123.68.0/22
+45.123.72.0/22
+45.123.76.0/22
+45.123.80.0/22
+45.123.84.0/22
+45.123.88.0/22
+45.123.120.0/22
+45.123.128.0/22
+45.123.132.0/22
+45.123.136.0/22
+45.123.148.0/22
+45.123.152.0/22
+45.123.156.0/22
+45.123.164.0/22
+45.123.168.0/22
+45.123.172.0/22
+45.123.176.0/22
+45.123.180.0/22
+45.123.184.0/22
+45.123.204.0/22
+45.123.212.0/22
+45.123.224.0/22
+45.123.228.0/22
+45.123.232.0/22
+45.123.236.0/22
+45.123.240.0/22
+45.123.244.0/22
+45.123.248.0/22
+45.123.252.0/22
+45.124.0.0/22
+45.124.20.0/22
+45.124.28.0/22
+45.124.32.0/22
+45.124.36.0/22
+45.124.44.0/22
+45.124.68.0/22
+45.124.76.0/22
+45.124.80.0/22
+45.124.100.0/22
+45.124.124.0/22
+45.124.172.0/22
+45.124.176.0/22
+45.124.208.0/22
+45.124.248.0/22
+45.125.12.0/22
+45.125.16.0/22
+45.125.24.0/22
+45.125.28.0/22
+45.125.32.0/22
+45.125.44.0/22
+45.125.52.0/22
+45.125.56.0/22
+45.125.76.0/22
+45.125.80.0/22
+45.125.84.0/22
+45.125.88.0/22
+45.125.92.0/22
+45.125.96.0/22
+45.125.100.0/22
+45.125.104.0/22
+45.125.136.0/22
+45.126.48.0/22
+45.126.52.0/22
+45.126.100.0/22
+45.126.108.0/22
+45.126.112.0/22
+45.126.116.0/22
+45.126.120.0/22
+45.126.212.0/22
+45.126.220.0/22
+45.127.8.0/22
+45.127.12.0/22
+45.127.96.0/22
+45.127.116.0/22
+45.127.124.0/22
+45.127.128.0/22
+45.127.144.0/22
+45.127.148.0/22
+45.127.156.0/22
+45.127.216.0/22
+45.248.8.0/22
+45.248.80.0/22
+45.248.84.0/22
+45.248.88.0/22
+45.248.96.0/22
+45.248.100.0/22
+45.248.104.0/22
+45.248.108.0/22
+45.248.128.0/22
+45.248.132.0/22
+45.248.204.0/22
+45.248.208.0/22
+45.248.212.0/22
+45.248.216.0/22
+45.248.220.0/22
+45.248.224.0/22
+45.248.228.0/22
+45.248.232.0/22
+45.248.236.0/22
+45.248.240.0/22
+45.248.244.0/22
+45.248.248.0/22
+45.248.252.0/22
+45.249.0.0/22
+45.249.4.0/22
+45.249.12.0/22
+45.249.16.0/22
+45.249.20.0/22
+45.249.24.0/22
+45.249.28.0/22
+45.249.32.0/22
+45.249.36.0/22
+45.249.92.0/22
+45.249.112.0/22
+45.249.180.0/22
+45.249.188.0/22
+45.249.192.0/22
+45.249.196.0/22
+45.249.200.0/22
+45.249.204.0/22
+45.249.208.0/22
+45.249.212.0/22
+45.250.12.0/22
+45.250.16.0/22
+45.250.28.0/22
+45.250.32.0/22
+45.250.36.0/22
+45.250.40.0/22
+45.250.76.0/22
+45.250.80.0/22
+45.250.84.0/22
+45.250.88.0/22
+45.250.92.0/22
+45.250.96.0/22
+45.250.104.0/22
+45.250.108.0/22
+45.250.112.0/22
+45.250.116.0/22
+45.250.120.0/22
+45.250.124.0/22
+45.250.128.0/22
+45.250.132.0/22
+45.250.136.0/22
+45.250.140.0/22
+45.250.144.0/22
+45.250.148.0/22
+45.250.152.0/22
+45.250.164.0/22
+45.250.180.0/22
+45.250.184.0/22
+45.250.188.0/22
+45.250.192.0/22
+45.251.0.0/22
+45.251.8.0/22
+45.251.16.0/22
+45.251.20.0/22
+45.251.52.0/22
+45.251.84.0/22
+45.251.88.0/22
+45.251.92.0/22
+45.251.96.0/22
+45.251.100.0/22
+45.251.120.0/22
+45.251.124.0/22
+45.251.136.0/22
+45.251.140.0/22
+45.251.144.0/22
+45.251.148.0/22
+45.251.152.0/22
+45.251.156.0/22
+45.251.160.0/22
+45.251.164.0/22
+45.251.168.0/22
+45.251.172.0/22
+45.251.176.0/22
+45.251.180.0/22
+45.251.184.0/22
+45.251.188.0/22
+45.251.192.0/22
+45.251.196.0/22
+45.251.200.0/22
+45.251.204.0/22
+45.251.208.0/22
+45.251.212.0/22
+45.251.216.0/22
+45.251.220.0/22
+45.251.224.0/22
+45.251.240.0/22
+45.252.0.0/22
+45.252.4.0/22
+45.252.8.0/22
+45.252.12.0/22
+45.252.16.0/22
+45.252.20.0/22
+45.252.24.0/22
+45.252.28.0/22
+45.252.32.0/22
+45.252.36.0/22
+45.252.40.0/22
+45.252.44.0/22
+45.252.48.0/22
+45.252.60.0/22
+45.252.84.0/22
+45.252.88.0/22
+45.252.92.0/22
+45.252.96.0/22
+45.252.100.0/22
+45.252.104.0/22
+45.252.108.0/22
+45.252.112.0/22
+45.252.116.0/22
+45.252.120.0/22
+45.252.124.0/22
+45.252.128.0/22
+45.252.132.0/22
+45.252.136.0/22
+45.252.140.0/22
+45.252.144.0/22
+45.252.148.0/22
+45.252.152.0/22
+45.252.156.0/22
+45.252.160.0/22
+45.252.164.0/22
+45.252.168.0/22
+45.252.172.0/22
+45.252.176.0/22
+45.252.192.0/22
+45.252.196.0/22
+45.252.200.0/22
+45.252.204.0/22
+45.252.208.0/22
+45.252.212.0/22
+45.252.216.0/22
+45.252.220.0/22
+45.252.224.0/22
+45.252.228.0/22
+45.252.232.0/22
+45.253.0.0/22
+45.253.4.0/22
+45.253.8.0/22
+45.253.12.0/22
+45.253.16.0/22
+45.253.20.0/22
+45.253.24.0/22
+45.253.28.0/22
+45.253.32.0/22
+45.253.36.0/22
+45.253.40.0/22
+45.253.44.0/22
+45.253.48.0/22
+45.253.52.0/22
+45.253.56.0/22
+45.253.60.0/22
+45.253.64.0/22
+45.253.68.0/22
+45.253.72.0/22
+45.253.76.0/22
+45.253.80.0/22
+45.253.84.0/22
+45.253.92.0/22
+45.253.96.0/22
+45.253.100.0/22
+45.253.104.0/22
+45.253.108.0/22
+45.253.112.0/22
+45.253.116.0/22
+45.253.120.0/22
+45.253.132.0/22
+45.253.136.0/22
+45.253.140.0/22
+45.253.144.0/22
+45.253.148.0/22
+45.253.152.0/22
+45.253.156.0/22
+45.253.160.0/22
+45.253.164.0/22
+45.253.168.0/22
+45.253.172.0/22
+45.253.176.0/22
+45.253.180.0/22
+45.253.184.0/22
+45.253.188.0/22
+45.253.192.0/22
+45.253.196.0/22
+45.253.200.0/22
+45.253.204.0/22
+45.253.208.0/22
+45.253.212.0/22
+45.253.216.0/22
+45.253.220.0/22
+45.253.224.0/22
+45.253.228.0/22
+45.253.232.0/22
+45.253.236.0/22
+45.253.240.0/22
+45.254.0.0/22
+45.254.4.0/22
+45.254.8.0/22
+45.254.12.0/22
+45.254.16.0/22
+45.254.20.0/22
+45.254.24.0/22
+45.254.28.0/22
+45.254.40.0/22
+45.254.48.0/22
+45.254.52.0/22
+45.254.56.0/22
+45.254.60.0/22
+45.254.64.0/22
+45.254.68.0/22
+45.254.72.0/22
+45.254.76.0/22
+45.254.80.0/22
+45.254.84.0/22
+45.254.88.0/22
+45.254.92.0/22
+45.254.96.0/22
+45.254.100.0/22
+45.254.104.0/22
+45.254.108.0/22
+45.254.112.0/22
+45.254.116.0/22
+45.254.120.0/22
+45.254.124.0/22
+45.254.128.0/22
+45.254.132.0/22
+45.254.136.0/22
+45.254.140.0/22
+45.254.144.0/22
+45.254.148.0/22
+45.254.152.0/22
+45.254.156.0/22
+45.254.160.0/22
+45.254.164.0/22
+45.254.168.0/22
+45.254.172.0/22
+45.254.176.0/22
+45.254.180.0/22
+45.254.184.0/22
+45.254.188.0/22
+45.254.192.0/22
+45.254.196.0/22
+45.254.200.0/22
+45.254.204.0/22
+45.254.208.0/22
+45.254.212.0/22
+45.254.216.0/22
+45.254.220.0/22
+45.254.224.0/22
+45.254.228.0/22
+45.254.236.0/22
+45.254.240.0/22
+45.254.248.0/22
+45.255.0.0/22
+45.255.4.0/22
+45.255.8.0/22
+45.255.12.0/22
+45.255.16.0/22
+45.255.20.0/22
+45.255.24.0/22
+45.255.28.0/22
+45.255.32.0/22
+45.255.36.0/22
+45.255.40.0/22
+45.255.44.0/22
+45.255.48.0/22
+45.255.52.0/22
+45.255.56.0/22
+45.255.60.0/22
+45.255.64.0/22
+45.255.68.0/22
+45.255.72.0/22
+45.255.76.0/22
+45.255.80.0/22
+45.255.84.0/22
+45.255.88.0/22
+45.255.92.0/22
+45.255.96.0/22
+45.255.100.0/22
+45.255.104.0/22
+45.255.108.0/22
+45.255.112.0/22
+45.255.116.0/22
+45.255.120.0/22
+45.255.124.0/22
+45.255.132.0/22
+45.255.136.0/22
+45.255.140.0/22
+45.255.144.0/22
+45.255.148.0/22
+45.255.152.0/22
+45.255.156.0/22
+45.255.160.0/22
+45.255.164.0/22
+45.255.168.0/22
+45.255.172.0/22
+45.255.176.0/22
+45.255.180.0/22
+45.255.184.0/22
+45.255.188.0/22
+45.255.192.0/22
+45.255.196.0/22
+45.255.200.0/22
+45.255.204.0/22
+45.255.208.0/22
+45.255.212.0/22
+45.255.216.0/22
+45.255.220.0/22
+45.255.224.0/22
+45.255.228.0/22
+45.255.232.0/22
+45.255.236.0/22
+45.255.240.0/22
+45.255.244.0/22
+45.255.248.0/22
+47.92.0.0/14
+47.96.0.0/11
+49.4.0.0/14
+49.51.0.0/16
+49.52.0.0/14
+49.64.0.0/11
+49.112.0.0/13
+49.120.0.0/14
+49.128.0.0/24
+49.128.2.0/23
+49.128.4.0/22
+49.140.0.0/15
+49.152.0.0/14
+49.208.0.0/15
+49.210.0.0/15
+49.220.0.0/14
+49.232.0.0/14
+49.239.0.0/18
+49.239.192.0/18
+49.246.224.0/19
+52.80.0.0/15
+52.82.0.0/15
+52.130.0.0/15
+54.222.0.0/15
+58.14.0.0/15
+58.16.0.0/16
+58.17.0.0/17
+58.17.128.0/17
+58.18.0.0/16
+58.19.0.0/16
+58.20.0.0/16
+58.21.0.0/16
+58.22.0.0/15
+58.24.0.0/15
+58.30.0.0/15
+58.32.0.0/13
+58.40.0.0/15
+58.42.0.0/16
+58.43.0.0/16
+58.44.0.0/14
+58.48.0.0/13
+58.56.0.0/15
+58.58.0.0/16
+58.59.0.0/17
+58.59.128.0/17
+58.60.0.0/14
+58.65.232.0/21
+58.66.0.0/15
+58.68.128.0/17
+58.82.0.0/17
+58.83.0.0/17
+58.83.128.0/17
+58.87.64.0/18
+58.99.128.0/17
+58.100.0.0/15
+58.116.0.0/14
+58.128.0.0/13
+58.144.0.0/16
+58.154.0.0/15
+58.192.0.0/15
+58.194.0.0/15
+58.196.0.0/15
+58.198.0.0/15
+58.200.0.0/13
+58.208.0.0/12
+58.240.0.0/15
+58.242.0.0/15
+58.244.0.0/15
+58.246.0.0/15
+58.248.0.0/13
+59.32.0.0/13
+59.40.0.0/15
+59.42.0.0/16
+59.43.0.0/16
+59.44.0.0/14
+59.48.0.0/16
+59.49.0.0/17
+59.49.128.0/17
+59.50.0.0/16
+59.51.0.0/17
+59.51.128.0/17
+59.52.0.0/14
+59.56.0.0/14
+59.60.0.0/15
+59.62.0.0/15
+59.64.0.0/14
+59.68.0.0/14
+59.72.0.0/15
+59.74.0.0/15
+59.76.0.0/16
+59.77.0.0/16
+59.78.0.0/15
+59.80.0.0/15
+59.82.0.0/15
+59.107.0.0/17
+59.107.128.0/17
+59.108.0.0/15
+59.110.0.0/15
+59.151.0.0/17
+59.152.16.0/22
+59.152.20.0/22
+59.152.24.0/22
+59.152.28.0/22
+59.152.32.0/22
+59.152.36.0/22
+59.152.64.0/22
+59.152.68.0/22
+59.152.72.0/22
+59.152.76.0/22
+59.152.112.0/22
+59.152.116.0/22
+59.153.4.0/22
+59.153.32.0/22
+59.153.60.0/22
+59.153.64.0/22
+59.153.68.0/22
+59.153.72.0/22
+59.153.92.0/22
+59.153.116.0/22
+59.153.136.0/22
+59.153.152.0/22
+59.153.156.0/22
+59.153.164.0/22
+59.153.168.0/22
+59.153.172.0/22
+59.153.176.0/22
+59.153.180.0/22
+59.153.184.0/22
+59.153.188.0/22
+59.153.192.0/22
+59.155.0.0/16
+59.172.0.0/15
+59.174.0.0/15
+59.191.0.0/17
+59.191.240.0/20
+59.192.0.0/10
+60.0.0.0/13
+60.8.0.0/15
+60.10.0.0/16
+60.11.0.0/16
+60.12.0.0/16
+60.13.0.0/18
+60.13.64.0/18
+60.13.128.0/17
+60.14.0.0/15
+60.16.0.0/13
+60.24.0.0/14
+60.28.0.0/15
+60.30.0.0/16
+60.31.0.0/16
+60.55.0.0/16
+60.63.0.0/16
+60.160.0.0/15
+60.162.0.0/15
+60.164.0.0/15
+60.166.0.0/15
+60.168.0.0/13
+60.176.0.0/12
+60.194.0.0/15
+60.200.0.0/14
+60.204.0.0/16
+60.205.0.0/16
+60.206.0.0/15
+60.208.0.0/13
+60.216.0.0/15
+60.218.0.0/15
+60.220.0.0/14
+60.232.0.0/15
+60.235.0.0/16
+60.245.128.0/17
+60.247.0.0/16
+60.252.0.0/16
+60.253.128.0/17
+60.255.0.0/16
+61.4.80.0/22
+61.4.84.0/22
+61.4.88.0/21
+61.4.176.0/20
+61.8.160.0/20
+61.14.212.0/22
+61.14.216.0/22
+61.14.220.0/22
+61.14.240.0/22
+61.14.244.0/22
+61.28.0.0/20
+61.28.16.0/20
+61.28.32.0/19
+61.28.64.0/18
+61.29.128.0/18
+61.29.192.0/19
+61.29.224.0/20
+61.45.128.0/18
+61.45.224.0/20
+61.47.128.0/18
+61.48.0.0/14
+61.52.0.0/15
+61.54.0.0/16
+61.55.0.0/16
+61.87.192.0/18
+61.128.0.0/15
+61.130.0.0/15
+61.132.0.0/16
+61.133.0.0/17
+61.133.128.0/17
+61.134.0.0/18
+61.134.64.0/19
+61.134.96.0/19
+61.134.128.0/18
+61.134.192.0/18
+61.135.0.0/16
+61.136.0.0/18
+61.136.64.0/18
+61.136.128.0/17
+61.137.0.0/17
+61.137.128.0/17
+61.138.0.0/18
+61.138.64.0/18
+61.138.128.0/18
+61.138.192.0/18
+61.139.0.0/17
+61.139.128.0/18
+61.139.192.0/18
+61.140.0.0/14
+61.144.0.0/14
+61.148.0.0/15
+61.150.0.0/15
+61.152.0.0/16
+61.153.0.0/16
+61.154.0.0/15
+61.156.0.0/16
+61.157.0.0/16
+61.158.0.0/17
+61.158.128.0/17
+61.159.0.0/18
+61.159.64.0/18
+61.159.128.0/17
+61.160.0.0/16
+61.161.0.0/18
+61.161.64.0/18
+61.161.128.0/17
+61.162.0.0/16
+61.163.0.0/16
+61.164.0.0/16
+61.165.0.0/16
+61.166.0.0/16
+61.167.0.0/16
+61.168.0.0/16
+61.169.0.0/16
+61.170.0.0/15
+61.172.0.0/14
+61.176.0.0/16
+61.177.0.0/16
+61.178.0.0/16
+61.179.0.0/16
+61.180.0.0/17
+61.180.128.0/17
+61.181.0.0/16
+61.182.0.0/16
+61.183.0.0/16
+61.184.0.0/14
+61.188.0.0/16
+61.189.0.0/17
+61.189.128.0/17
+61.190.0.0/15
+61.232.0.0/14
+61.236.0.0/15
+61.240.0.0/14
+62.234.0.0/16
+68.79.0.0/18
+69.230.192.0/18
+69.231.128.0/18
+69.234.192.0/18
+69.235.128.0/18
+71.131.192.0/18
+71.132.0.0/18
+71.136.64.0/18
+71.137.0.0/18
+81.68.0.0/14
+82.156.0.0/15
+94.191.0.0/17
+101.0.0.0/22
+101.1.0.0/22
+101.2.172.0/22
+101.4.0.0/14
+101.16.0.0/12
+101.33.128.0/17
+101.34.0.0/15
+101.36.0.0/17
+101.36.128.0/17
+101.37.0.0/16
+101.38.0.0/15
+101.40.0.0/15
+101.42.0.0/15
+101.44.0.0/14
+101.48.0.0/15
+101.50.8.0/22
+101.50.12.0/22
+101.50.56.0/22
+101.52.0.0/16
+101.53.100.0/22
+101.54.0.0/16
+101.55.224.0/21
+101.64.0.0/13
+101.72.0.0/14
+101.76.0.0/15
+101.78.0.0/22
+101.78.32.0/19
+101.80.0.0/12
+101.96.0.0/21
+101.96.8.0/22
+101.96.16.0/20
+101.96.128.0/17
+101.99.96.0/19
+101.101.64.0/19
+101.101.100.0/24
+101.101.102.0/23
+101.101.104.0/21
+101.101.112.0/20
+101.102.64.0/19
+101.102.100.0/23
+101.102.102.0/24
+101.102.104.0/21
+101.102.112.0/20
+101.104.0.0/14
+101.110.64.0/19
+101.110.96.0/20
+101.110.116.0/22
+101.110.120.0/21
+101.120.0.0/14
+101.124.0.0/15
+101.126.0.0/16
+101.128.0.0/22
+101.128.8.0/21
+101.128.16.0/20
+101.128.32.0/19
+101.129.0.0/16
+101.130.0.0/15
+101.132.0.0/14
+101.144.0.0/12
+101.192.0.0/14
+101.196.0.0/16
+101.197.0.0/16
+101.198.0.0/15
+101.200.0.0/15
+101.203.128.0/19
+101.203.160.0/21
+101.203.172.0/22
+101.203.176.0/20
+101.204.0.0/14
+101.224.0.0/13
+101.232.0.0/15
+101.234.64.0/21
+101.234.76.0/22
+101.234.80.0/20
+101.234.96.0/19
+101.236.0.0/14
+101.240.0.0/14
+101.244.0.0/14
+101.248.0.0/15
+101.251.0.0/22
+101.251.8.0/21
+101.251.16.0/20
+101.251.32.0/19
+101.251.64.0/18
+101.251.128.0/17
+101.252.0.0/15
+101.254.0.0/16
+103.1.8.0/22
+103.1.20.0/22
+103.1.24.0/22
+103.1.72.0/22
+103.1.88.0/22
+103.1.168.0/22
+103.2.108.0/22
+103.2.156.0/22
+103.2.164.0/22
+103.2.200.0/22
+103.2.204.0/22
+103.2.208.0/22
+103.2.212.0/22
+103.3.84.0/22
+103.3.88.0/22
+103.3.92.0/22
+103.3.96.0/22
+103.3.100.0/22
+103.3.104.0/22
+103.3.108.0/22
+103.3.112.0/22
+103.3.116.0/22
+103.3.120.0/22
+103.3.124.0/22
+103.3.128.0/22
+103.3.132.0/22
+103.3.136.0/22
+103.3.140.0/22
+103.3.148.0/22
+103.3.152.0/22
+103.3.156.0/22
+103.4.56.0/22
+103.4.168.0/22
+103.4.184.0/22
+103.4.224.0/22
+103.5.36.0/22
+103.5.52.0/22
+103.5.56.0/22
+103.5.152.0/22
+103.5.168.0/22
+103.5.192.0/22
+103.5.252.0/22
+103.6.76.0/22
+103.6.108.0/22
+103.6.220.0/22
+103.6.228.0/22
+103.7.4.0/22
+103.7.28.0/22
+103.7.140.0/22
+103.7.212.0/22
+103.7.216.0/22
+103.7.220.0/22
+103.8.0.0/22
+103.8.4.0/22
+103.8.8.0/22
+103.8.32.0/22
+103.8.52.0/22
+103.8.68.0/22
+103.8.108.0/22
+103.8.156.0/22
+103.8.200.0/22
+103.8.204.0/22
+103.8.220.0/22
+103.9.8.0/22
+103.9.24.0/22
+103.9.108.0/22
+103.9.152.0/22
+103.9.192.0/22
+103.9.248.0/22
+103.9.252.0/22
+103.10.0.0/22
+103.10.16.0/22
+103.10.84.0/22
+103.10.140.0/22
+103.11.16.0/22
+103.11.168.0/22
+103.11.180.0/22
+103.12.32.0/22
+103.12.68.0/22
+103.12.92.0/22
+103.12.136.0/22
+103.12.184.0/22
+103.12.232.0/22
+103.13.12.0/22
+103.13.124.0/22
+103.13.144.0/22
+103.13.196.0/22
+103.13.220.0/22
+103.13.244.0/22
+103.14.32.0/22
+103.14.84.0/22
+103.14.100.0/22
+103.14.132.0/22
+103.14.136.0/22
+103.14.156.0/22
+103.14.240.0/22
+103.15.4.0/22
+103.15.8.0/22
+103.15.16.0/22
+103.15.96.0/22
+103.15.200.0/22
+103.16.52.0/22
+103.16.80.0/22
+103.16.84.0/22
+103.16.88.0/22
+103.16.108.0/22
+103.16.124.0/22
+103.17.40.0/22
+103.17.64.0/22
+103.17.120.0/22
+103.17.136.0/22
+103.17.160.0/22
+103.17.204.0/22
+103.17.228.0/22
+103.18.192.0/22
+103.18.208.0/22
+103.18.212.0/22
+103.18.224.0/22
+103.19.0.0/22
+103.19.12.0/22
+103.19.40.0/22
+103.19.44.0/22
+103.19.64.0/22
+103.19.68.0/22
+103.19.72.0/22
+103.19.232.0/22
+103.20.12.0/22
+103.20.32.0/22
+103.20.44.0/22
+103.20.68.0/22
+103.20.112.0/22
+103.20.128.0/22
+103.20.160.0/22
+103.20.248.0/22
+103.21.112.0/22
+103.21.116.0/22
+103.21.136.0/22
+103.21.140.0/22
+103.21.176.0/22
+103.21.208.0/22
+103.21.240.0/22
+103.22.0.0/22
+103.22.4.0/22
+103.22.8.0/22
+103.22.12.0/22
+103.22.16.0/22
+103.22.20.0/22
+103.22.24.0/22
+103.22.28.0/22
+103.22.32.0/22
+103.22.36.0/22
+103.22.40.0/22
+103.22.44.0/22
+103.22.48.0/22
+103.22.52.0/22
+103.22.56.0/22
+103.22.60.0/22
+103.22.64.0/22
+103.22.68.0/22
+103.22.72.0/22
+103.22.76.0/22
+103.22.80.0/22
+103.22.84.0/22
+103.22.88.0/22
+103.22.92.0/22
+103.22.100.0/22
+103.22.104.0/22
+103.22.108.0/22
+103.22.112.0/22
+103.22.116.0/22
+103.22.120.0/22
+103.22.124.0/22
+103.22.188.0/22
+103.22.228.0/22
+103.22.252.0/22
+103.23.8.0/22
+103.23.56.0/22
+103.23.160.0/22
+103.23.164.0/22
+103.23.176.0/22
+103.23.228.0/22
+103.24.24.0/22
+103.24.116.0/22
+103.24.128.0/22
+103.24.144.0/22
+103.24.176.0/22
+103.24.184.0/22
+103.24.220.0/22
+103.24.228.0/22
+103.24.248.0/22
+103.24.252.0/22
+103.25.8.0/23
+103.25.20.0/22
+103.25.24.0/22
+103.25.28.0/22
+103.25.32.0/22
+103.25.36.0/22
+103.25.40.0/22
+103.25.48.0/22
+103.25.64.0/22
+103.25.68.0/22
+103.25.148.0/22
+103.25.156.0/22
+103.25.216.0/22
+103.26.0.0/22
+103.26.64.0/22
+103.26.76.0/22
+103.26.132.0/22
+103.26.156.0/22
+103.26.160.0/22
+103.26.228.0/22
+103.26.240.0/22
+103.27.4.0/22
+103.27.12.0/22
+103.27.24.0/22
+103.27.56.0/22
+103.27.96.0/22
+103.27.184.0/22
+103.27.208.0/22
+103.27.212.0/22
+103.27.240.0/22
+103.28.4.0/22
+103.28.8.0/22
+103.28.184.0/22
+103.28.204.0/22
+103.28.212.0/22
+103.29.16.0/22
+103.29.128.0/22
+103.29.132.0/22
+103.29.136.0/22
+103.30.20.0/22
+103.30.96.0/22
+103.30.148.0/22
+103.30.200.0/22
+103.30.228.0/22
+103.30.236.0/22
+103.31.0.0/22
+103.31.48.0/22
+103.31.52.0/22
+103.31.56.0/22
+103.31.60.0/22
+103.31.64.0/22
+103.31.68.0/22
+103.31.148.0/22
+103.31.160.0/22
+103.31.168.0/22
+103.31.200.0/22
+103.31.236.0/22
+103.32.0.0/22
+103.32.4.0/22
+103.32.8.0/22
+103.32.12.0/22
+103.32.16.0/22
+103.32.20.0/22
+103.32.24.0/22
+103.32.28.0/22
+103.32.32.0/22
+103.32.36.0/22
+103.32.40.0/22
+103.32.44.0/22
+103.32.48.0/22
+103.32.52.0/22
+103.32.56.0/22
+103.32.60.0/22
+103.32.64.0/22
+103.32.68.0/22
+103.32.72.0/22
+103.32.76.0/22
+103.32.80.0/22
+103.32.84.0/22
+103.32.88.0/22
+103.32.92.0/22
+103.32.96.0/22
+103.32.100.0/22
+103.32.104.0/22
+103.32.108.0/22
+103.32.112.0/22
+103.32.116.0/22
+103.32.120.0/22
+103.32.124.0/22
+103.32.128.0/22
+103.32.132.0/22
+103.32.136.0/22
+103.32.140.0/22
+103.32.144.0/22
+103.32.148.0/22
+103.32.152.0/22
+103.32.156.0/22
+103.32.160.0/22
+103.32.164.0/22
+103.32.168.0/22
+103.32.172.0/22
+103.32.176.0/22
+103.32.180.0/22
+103.32.184.0/22
+103.32.188.0/22
+103.32.192.0/22
+103.32.196.0/22
+103.32.200.0/22
+103.32.204.0/22
+103.32.208.0/22
+103.32.212.0/22
+103.32.216.0/22
+103.32.220.0/22
+103.32.224.0/22
+103.32.228.0/22
+103.32.232.0/22
+103.32.236.0/22
+103.32.240.0/22
+103.32.244.0/22
+103.32.248.0/22
+103.32.252.0/22
+103.33.0.0/22
+103.33.4.0/22
+103.33.8.0/22
+103.33.12.0/22
+103.33.16.0/22
+103.33.20.0/22
+103.33.24.0/22
+103.33.28.0/22
+103.33.32.0/22
+103.33.36.0/22
+103.33.40.0/22
+103.33.44.0/22
+103.33.48.0/22
+103.33.52.0/22
+103.33.56.0/22
+103.33.60.0/22
+103.33.64.0/22
+103.33.68.0/22
+103.33.72.0/22
+103.33.76.0/22
+103.33.80.0/22
+103.33.84.0/22
+103.33.88.0/22
+103.33.92.0/22
+103.33.96.0/22
+103.33.100.0/22
+103.33.104.0/22
+103.33.108.0/22
+103.33.112.0/22
+103.33.116.0/22
+103.33.120.0/22
+103.33.124.0/22
+103.33.128.0/22
+103.33.132.0/22
+103.33.136.0/22
+103.33.140.0/22
+103.33.144.0/22
+103.33.148.0/22
+103.33.152.0/22
+103.33.156.0/22
+103.33.160.0/22
+103.33.164.0/22
+103.33.168.0/22
+103.33.172.0/22
+103.33.176.0/22
+103.33.180.0/22
+103.33.184.0/22
+103.33.188.0/22
+103.33.192.0/22
+103.33.196.0/22
+103.33.200.0/22
+103.33.204.0/22
+103.33.208.0/22
+103.33.212.0/22
+103.33.216.0/22
+103.33.220.0/22
+103.33.224.0/22
+103.33.228.0/22
+103.33.232.0/22
+103.33.236.0/22
+103.33.240.0/22
+103.33.244.0/22
+103.33.248.0/22
+103.33.252.0/22
+103.34.0.0/22
+103.34.4.0/22
+103.34.8.0/22
+103.34.12.0/22
+103.34.16.0/22
+103.34.20.0/22
+103.34.24.0/22
+103.34.28.0/22
+103.34.32.0/22
+103.34.36.0/22
+103.34.40.0/22
+103.34.44.0/22
+103.34.48.0/22
+103.34.52.0/22
+103.34.56.0/22
+103.34.60.0/22
+103.34.64.0/22
+103.34.68.0/22
+103.34.72.0/22
+103.34.76.0/22
+103.34.80.0/22
+103.34.84.0/22
+103.34.88.0/22
+103.34.92.0/22
+103.34.96.0/22
+103.34.100.0/22
+103.34.104.0/22
+103.34.108.0/22
+103.34.112.0/22
+103.34.116.0/22
+103.34.120.0/22
+103.34.124.0/22
+103.34.128.0/22
+103.34.132.0/22
+103.34.136.0/22
+103.34.140.0/22
+103.34.144.0/22
+103.34.148.0/22
+103.34.152.0/22
+103.34.156.0/22
+103.34.160.0/22
+103.34.164.0/22
+103.34.168.0/22
+103.34.172.0/22
+103.34.176.0/22
+103.34.180.0/22
+103.34.184.0/22
+103.34.188.0/22
+103.34.192.0/22
+103.34.196.0/22
+103.34.200.0/22
+103.34.204.0/22
+103.34.208.0/22
+103.34.212.0/22
+103.34.216.0/22
+103.34.220.0/22
+103.34.224.0/22
+103.34.228.0/22
+103.34.232.0/22
+103.34.236.0/22
+103.34.240.0/22
+103.34.244.0/22
+103.34.248.0/22
+103.34.252.0/22
+103.35.0.0/22
+103.35.4.0/22
+103.35.8.0/22
+103.35.12.0/22
+103.35.16.0/22
+103.35.20.0/22
+103.35.24.0/22
+103.35.28.0/22
+103.35.32.0/22
+103.35.36.0/22
+103.35.40.0/22
+103.35.44.0/22
+103.35.48.0/22
+103.35.104.0/22
+103.35.116.0/22
+103.35.180.0/22
+103.35.200.0/22
+103.35.220.0/22
+103.36.28.0/22
+103.36.36.0/22
+103.36.56.0/22
+103.36.60.0/22
+103.36.64.0/22
+103.36.72.0/22
+103.36.96.0/22
+103.36.132.0/22
+103.36.136.0/22
+103.36.160.0/22
+103.36.164.0/22
+103.36.168.0/22
+103.36.172.0/22
+103.36.176.0/22
+103.36.180.0/22
+103.36.184.0/22
+103.36.188.0/22
+103.36.192.0/22
+103.36.196.0/22
+103.36.200.0/22
+103.36.204.0/22
+103.36.208.0/22
+103.36.212.0/22
+103.36.216.0/22
+103.36.220.0/22
+103.36.224.0/22
+103.36.228.0/22
+103.36.232.0/22
+103.36.236.0/22
+103.36.240.0/22
+103.36.244.0/22
+103.37.0.0/22
+103.37.12.0/22
+103.37.16.0/22
+103.37.24.0/22
+103.37.44.0/22
+103.37.52.0/22
+103.37.56.0/22
+103.37.72.0/22
+103.37.100.0/22
+103.37.104.0/22
+103.37.124.0/22
+103.37.136.0/22
+103.37.140.0/22
+103.37.144.0/22
+103.37.148.0/22
+103.37.152.0/22
+103.37.156.0/22
+103.37.160.0/22
+103.37.164.0/22
+103.37.172.0/22
+103.37.176.0/22
+103.37.188.0/22
+103.37.208.0/22
+103.37.212.0/22
+103.37.216.0/22
+103.37.220.0/22
+103.37.248.0/22
+103.37.252.0/22
+103.38.0.0/22
+103.38.32.0/22
+103.38.40.0/22
+103.38.44.0/22
+103.38.56.0/22
+103.38.76.0/22
+103.38.84.0/22
+103.38.92.0/22
+103.38.96.0/22
+103.38.116.0/22
+103.38.132.0/22
+103.38.140.0/22
+103.38.224.0/22
+103.38.228.0/22
+103.38.232.0/22
+103.38.252.0/22
+103.39.16.0/22
+103.39.64.0/22
+103.39.88.0/22
+103.39.100.0/22
+103.39.104.0/22
+103.39.108.0/22
+103.39.160.0/22
+103.39.164.0/22
+103.39.168.0/22
+103.39.172.0/22
+103.39.176.0/22
+103.39.180.0/22
+103.39.184.0/22
+103.39.188.0/22
+103.39.200.0/22
+103.39.204.0/22
+103.39.208.0/22
+103.39.212.0/22
+103.39.216.0/22
+103.39.220.0/22
+103.39.224.0/22
+103.39.228.0/22
+103.39.232.0/22
+103.40.12.0/22
+103.40.16.0/22
+103.40.20.0/22
+103.40.24.0/22
+103.40.28.0/22
+103.40.32.0/22
+103.40.36.0/22
+103.40.40.0/22
+103.40.44.0/22
+103.40.88.0/22
+103.40.100.0/22
+103.40.192.0/22
+103.40.212.0/22
+103.40.220.0/22
+103.40.228.0/22
+103.40.232.0/22
+103.40.236.0/22
+103.40.240.0/22
+103.40.244.0/22
+103.40.248.0/22
+103.40.252.0/22
+103.41.0.0/22
+103.41.16.0/22
+103.41.52.0/22
+103.41.140.0/22
+103.41.148.0/22
+103.41.152.0/22
+103.41.160.0/22
+103.41.164.0/22
+103.41.220.0/22
+103.41.224.0/22
+103.41.228.0/22
+103.41.232.0/22
+103.42.8.0/22
+103.42.24.0/22
+103.42.28.0/22
+103.42.32.0/22
+103.42.64.0/22
+103.42.68.0/22
+103.42.76.0/22
+103.42.104.0/22
+103.42.180.0/22
+103.42.232.0/22
+103.43.16.0/22
+103.43.84.0/22
+103.43.96.0/22
+103.43.100.0/22
+103.43.104.0/22
+103.43.124.0/22
+103.43.184.0/22
+103.43.192.0/22
+103.43.196.0/22
+103.43.208.0/22
+103.43.220.0/22
+103.43.224.0/22
+103.43.240.0/22
+103.44.56.0/22
+103.44.80.0/22
+103.44.88.0/22
+103.44.120.0/22
+103.44.124.0/22
+103.44.132.0/22
+103.44.144.0/22
+103.44.168.0/22
+103.44.176.0/22
+103.44.180.0/22
+103.44.184.0/22
+103.44.188.0/22
+103.44.192.0/22
+103.44.196.0/22
+103.44.200.0/22
+103.44.204.0/22
+103.44.224.0/22
+103.44.236.0/22
+103.44.240.0/22
+103.44.244.0/22
+103.44.248.0/22
+103.44.252.0/22
+103.45.0.0/22
+103.45.4.0/22
+103.45.8.0/22
+103.45.12.0/22
+103.45.16.0/22
+103.45.20.0/22
+103.45.24.0/22
+103.45.28.0/22
+103.45.32.0/22
+103.45.36.0/22
+103.45.40.0/22
+103.45.44.0/22
+103.45.48.0/22
+103.45.52.0/22
+103.45.56.0/22
+103.45.60.0/22
+103.45.72.0/22
+103.45.76.0/22
+103.45.80.0/22
+103.45.84.0/22
+103.45.88.0/22
+103.45.92.0/22
+103.45.96.0/22
+103.45.100.0/22
+103.45.104.0/22
+103.45.108.0/22
+103.45.112.0/22
+103.45.116.0/22
+103.45.120.0/22
+103.45.124.0/22
+103.45.128.0/22
+103.45.132.0/22
+103.45.136.0/22
+103.45.140.0/22
+103.45.144.0/22
+103.45.148.0/22
+103.45.152.0/22
+103.45.156.0/22
+103.45.160.0/22
+103.45.164.0/22
+103.45.168.0/22
+103.45.172.0/22
+103.45.176.0/22
+103.45.180.0/22
+103.45.184.0/22
+103.45.188.0/22
+103.45.192.0/22
+103.45.196.0/22
+103.45.200.0/22
+103.45.204.0/22
+103.45.208.0/22
+103.45.212.0/22
+103.45.216.0/22
+103.45.220.0/22
+103.45.224.0/22
+103.45.248.0/22
+103.46.0.0/22
+103.46.12.0/22
+103.46.16.0/22
+103.46.20.0/22
+103.46.24.0/22
+103.46.28.0/22
+103.46.32.0/22
+103.46.36.0/22
+103.46.40.0/22
+103.46.44.0/22
+103.46.48.0/22
+103.46.52.0/22
+103.46.56.0/22
+103.46.60.0/22
+103.46.64.0/22
+103.46.68.0/22
+103.46.72.0/22
+103.46.76.0/22
+103.46.80.0/22
+103.46.84.0/22
+103.46.88.0/22
+103.46.92.0/22
+103.46.96.0/22
+103.46.100.0/22
+103.46.104.0/22
+103.46.108.0/22
+103.46.112.0/22
+103.46.116.0/22
+103.46.120.0/22
+103.46.124.0/22
+103.46.128.0/22
+103.46.132.0/22
+103.46.136.0/22
+103.46.152.0/22
+103.46.156.0/22
+103.46.160.0/22
+103.46.164.0/22
+103.46.168.0/22
+103.46.172.0/22
+103.46.176.0/22
+103.46.180.0/22
+103.46.244.0/22
+103.46.248.0/22
+103.47.4.0/22
+103.47.20.0/22
+103.47.36.0/22
+103.47.40.0/22
+103.47.48.0/22
+103.47.80.0/22
+103.47.96.0/22
+103.47.108.0/22
+103.47.116.0/22
+103.47.120.0/22
+103.47.136.0/22
+103.47.140.0/22
+103.47.212.0/22
+103.48.52.0/22
+103.48.92.0/22
+103.48.144.0/22
+103.48.148.0/22
+103.48.152.0/22
+103.48.156.0/22
+103.48.202.0/23
+103.48.216.0/22
+103.48.220.0/22
+103.48.224.0/22
+103.48.228.0/22
+103.48.232.0/22
+103.48.236.0/22
+103.48.240.0/22
+103.48.244.0/22
+103.49.12.0/22
+103.49.20.0/22
+103.49.72.0/22
+103.49.76.0/22
+103.49.92.0/22
+103.49.96.0/22
+103.49.108.0/22
+103.49.128.0/22
+103.49.176.0/22
+103.49.180.0/22
+103.49.196.0/22
+103.49.248.0/22
+103.50.36.0/22
+103.50.44.0/22
+103.50.48.0/22
+103.50.52.0/22
+103.50.56.0/22
+103.50.60.0/22
+103.50.64.0/22
+103.50.68.0/22
+103.50.72.0/22
+103.50.108.0/22
+103.50.112.0/22
+103.50.116.0/22
+103.50.120.0/22
+103.50.124.0/22
+103.50.132.0/22
+103.50.136.0/22
+103.50.140.0/22
+103.50.172.0/22
+103.50.176.0/22
+103.50.180.0/22
+103.50.184.0/22
+103.50.188.0/22
+103.50.192.0/22
+103.50.196.0/22
+103.50.200.0/22
+103.50.220.0/22
+103.50.224.0/22
+103.50.228.0/22
+103.50.232.0/22
+103.50.236.0/22
+103.50.240.0/22
+103.50.244.0/22
+103.50.248.0/22
+103.52.40.0/22
+103.52.72.0/22
+103.52.76.0/22
+103.52.80.0/22
+103.52.84.0/22
+103.52.96.0/22
+103.52.100.0/22
+103.52.104.0/22
+103.52.160.0/22
+103.52.164.0/22
+103.52.172.0/22
+103.52.176.0/22
+103.52.184.0/22
+103.52.196.0/22
+103.53.4.0/22
+103.53.64.0/22
+103.53.68.0/22
+103.53.92.0/22
+103.53.100.0/22
+103.53.124.0/22
+103.53.128.0/22
+103.53.132.0/22
+103.53.136.0/22
+103.53.140.0/22
+103.53.144.0/22
+103.53.180.0/22
+103.53.204.0/22
+103.53.208.0/22
+103.53.212.0/22
+103.53.216.0/22
+103.53.236.0/22
+103.53.248.0/22
+103.54.8.0/22
+103.54.48.0/22
+103.54.60.0/22
+103.54.160.0/22
+103.54.164.0/22
+103.54.212.0/22
+103.54.240.0/22
+103.55.24.0/22
+103.55.80.0/22
+103.55.120.0/22
+103.55.152.0/22
+103.55.172.0/22
+103.55.204.0/22
+103.55.208.0/22
+103.55.228.0/22
+103.55.236.0/22
+103.56.8.0/22
+103.56.16.0/22
+103.56.20.0/22
+103.56.32.0/22
+103.56.52.0/22
+103.56.56.0/22
+103.56.60.0/22
+103.56.72.0/22
+103.56.76.0/22
+103.56.140.0/22
+103.56.152.0/22
+103.56.184.0/22
+103.56.200.0/22
+103.57.12.0/22
+103.57.52.0/22
+103.57.56.0/22
+103.57.76.0/22
+103.57.136.0/22
+103.57.196.0/22
+103.58.24.0/22
+103.59.76.0/22
+103.59.100.0/22
+103.59.112.0/22
+103.59.116.0/22
+103.59.120.0/22
+103.59.124.0/22
+103.59.128.0/22
+103.59.148.0/22
+103.59.164.0/22
+103.60.32.0/22
+103.60.44.0/22
+103.60.164.0/22
+103.60.228.0/22
+103.60.236.0/22
+103.61.60.0/22
+103.61.104.0/22
+103.61.140.0/22
+103.61.152.0/22
+103.61.156.0/22
+103.61.160.0/22
+103.61.172.0/22
+103.61.176.0/22
+103.61.184.0/22
+103.61.188.0/22
+103.62.24.0/22
+103.62.52.0/22
+103.62.72.0/22
+103.62.76.0/22
+103.62.80.0/22
+103.62.84.0/22
+103.62.88.0/22
+103.62.96.0/22
+103.62.100.0/22
+103.62.104.0/22
+103.62.108.0/22
+103.62.112.0/22
+103.62.116.0/22
+103.62.120.0/22
+103.62.124.0/22
+103.62.128.0/22
+103.62.132.0/22
+103.62.156.0/22
+103.62.160.0/22
+103.62.164.0/22
+103.62.168.0/22
+103.62.172.0/22
+103.62.176.0/22
+103.62.180.0/22
+103.62.184.0/22
+103.62.188.0/22
+103.62.192.0/22
+103.62.204.0/22
+103.62.208.0/22
+103.62.212.0/22
+103.62.216.0/22
+103.62.220.0/22
+103.62.224.0/22
+103.63.32.0/22
+103.63.36.0/22
+103.63.40.0/22
+103.63.44.0/22
+103.63.48.0/22
+103.63.52.0/22
+103.63.56.0/22
+103.63.60.0/22
+103.63.64.0/22
+103.63.68.0/22
+103.63.72.0/22
+103.63.76.0/22
+103.63.80.0/22
+103.63.84.0/22
+103.63.88.0/22
+103.63.140.0/22
+103.63.144.0/22
+103.63.152.0/22
+103.63.160.0/22
+103.63.164.0/22
+103.63.168.0/22
+103.63.172.0/22
+103.63.176.0/22
+103.63.180.0/22
+103.63.184.0/22
+103.63.192.0/22
+103.63.196.0/22
+103.63.200.0/22
+103.63.204.0/22
+103.63.208.0/22
+103.63.240.0/22
+103.63.244.0/22
+103.63.248.0/22
+103.63.252.0/22
+103.64.0.0/22
+103.64.4.0/22
+103.64.24.0/22
+103.64.28.0/22
+103.64.32.0/22
+103.64.36.0/22
+103.64.40.0/22
+103.64.44.0/22
+103.64.48.0/22
+103.64.52.0/22
+103.64.56.0/22
+103.64.60.0/22
+103.64.64.0/22
+103.64.68.0/22
+103.64.72.0/22
+103.64.76.0/22
+103.64.80.0/22
+103.64.84.0/22
+103.64.88.0/22
+103.64.92.0/22
+103.64.96.0/22
+103.64.100.0/22
+103.64.104.0/22
+103.64.108.0/22
+103.64.112.0/22
+103.64.116.0/22
+103.64.120.0/22
+103.64.124.0/22
+103.64.140.0/22
+103.64.144.0/22
+103.64.152.0/22
+103.64.156.0/22
+103.64.160.0/22
+103.64.164.0/22
+103.64.168.0/22
+103.64.172.0/22
+103.64.176.0/22
+103.64.180.0/22
+103.64.184.0/22
+103.64.188.0/22
+103.64.192.0/22
+103.64.196.0/22
+103.64.200.0/22
+103.64.204.0/22
+103.64.208.0/22
+103.64.212.0/22
+103.64.216.0/22
+103.64.220.0/22
+103.64.224.0/22
+103.64.228.0/22
+103.64.232.0/22
+103.64.236.0/22
+103.64.240.0/22
+103.64.244.0/22
+103.64.248.0/22
+103.64.252.0/22
+103.65.0.0/22
+103.65.4.0/22
+103.65.8.0/22
+103.65.12.0/22
+103.65.16.0/22
+103.65.36.0/22
+103.65.40.0/22
+103.65.48.0/22
+103.65.52.0/22
+103.65.56.0/22
+103.65.60.0/22
+103.65.64.0/22
+103.65.68.0/22
+103.65.72.0/22
+103.65.76.0/22
+103.65.80.0/22
+103.65.84.0/22
+103.65.88.0/22
+103.65.92.0/22
+103.65.100.0/22
+103.65.104.0/22
+103.65.108.0/22
+103.65.112.0/22
+103.65.144.0/22
+103.65.148.0/22
+103.65.152.0/22
+103.65.156.0/22
+103.65.160.0/22
+103.65.164.0/22
+103.65.168.0/22
+103.65.172.0/22
+103.66.32.0/22
+103.66.40.0/22
+103.66.92.0/22
+103.66.108.0/22
+103.66.200.0/22
+103.66.216.0/22
+103.66.240.0/22
+103.66.244.0/22
+103.66.248.0/22
+103.66.252.0/22
+103.67.0.0/22
+103.67.4.0/22
+103.67.8.0/22
+103.67.100.0/22
+103.67.104.0/22
+103.67.108.0/22
+103.67.112.0/22
+103.67.116.0/22
+103.67.120.0/22
+103.67.124.0/22
+103.67.128.0/22
+103.67.132.0/22
+103.67.136.0/22
+103.67.140.0/22
+103.67.144.0/22
+103.67.148.0/22
+103.67.172.0/22
+103.67.192.0/22
+103.67.212.0/22
+103.67.252.0/22
+103.68.64.0/22
+103.68.88.0/22
+103.68.100.0/22
+103.68.128.0/22
+103.68.192.0/22
+103.69.16.0/22
+103.69.116.0/22
+103.69.132.0/22
+103.69.152.0/22
+103.69.212.0/22
+103.70.8.0/22
+103.70.148.0/22
+103.70.184.0/22
+103.70.220.0/22
+103.70.224.0/22
+103.70.236.0/22
+103.70.252.0/22
+103.71.0.0/22
+103.71.32.0/22
+103.71.48.0/22
+103.71.68.0/22
+103.71.72.0/22
+103.71.80.0/22
+103.71.84.0/22
+103.71.88.0/22
+103.71.120.0/22
+103.71.124.0/22
+103.71.128.0/22
+103.71.144.0/22
+103.71.196.0/22
+103.71.200.0/22
+103.71.232.0/22
+103.72.12.0/22
+103.72.16.0/22
+103.72.20.0/22
+103.72.24.0/22
+103.72.28.0/22
+103.72.32.0/22
+103.72.36.0/22
+103.72.40.0/22
+103.72.44.0/22
+103.72.48.0/22
+103.72.52.0/22
+103.72.112.0/22
+103.72.116.0/22
+103.72.120.0/22
+103.72.124.0/22
+103.72.128.0/22
+103.72.132.0/22
+103.72.144.0/22
+103.72.148.0/22
+103.72.172.0/22
+103.72.180.0/22
+103.72.224.0/22
+103.72.228.0/22
+103.72.232.0/22
+103.72.236.0/22
+103.72.240.0/22
+103.72.244.0/22
+103.72.248.0/22
+103.72.252.0/22
+103.73.0.0/22
+103.73.4.0/22
+103.73.8.0/22
+103.73.12.0/22
+103.73.16.0/22
+103.73.20.0/22
+103.73.24.0/22
+103.73.28.0/22
+103.73.48.0/22
+103.73.88.0/22
+103.73.96.0/22
+103.73.116.0/22
+103.73.120.0/22
+103.73.128.0/22
+103.73.132.0/22
+103.73.136.0/22
+103.73.140.0/22
+103.73.144.0/22
+103.73.168.0/22
+103.73.176.0/22
+103.73.204.0/22
+103.73.208.0/22
+103.73.240.0/22
+103.73.244.0/22
+103.73.248.0/22
+103.74.24.0/22
+103.74.28.0/22
+103.74.32.0/22
+103.74.36.0/22
+103.74.40.0/22
+103.74.44.0/22
+103.74.48.0/22
+103.74.56.0/22
+103.74.60.0/22
+103.74.80.0/22
+103.74.124.0/22
+103.74.148.0/22
+103.74.152.0/22
+103.74.156.0/22
+103.74.204.0/22
+103.74.232.0/22
+103.75.16.0/22
+103.75.88.0/22
+103.75.92.0/22
+103.75.104.0/22
+103.75.108.0/22
+103.75.112.0/22
+103.75.120.0/22
+103.75.128.0/22
+103.75.144.0/22
+103.75.152.0/22
+103.75.236.0/24
+103.76.60.0/22
+103.76.64.0/22
+103.76.68.0/22
+103.76.72.0/22
+103.76.84.0/22
+103.76.92.0/22
+103.76.216.0/22
+103.76.220.0/22
+103.76.224.0/22
+103.77.28.0/22
+103.77.52.0/22
+103.77.56.0/22
+103.77.72.0/22
+103.77.88.0/22
+103.77.92.0/22
+103.77.132.0/22
+103.77.148.0/22
+103.77.220.0/22
+103.78.56.0/22
+103.78.60.0/22
+103.78.64.0/22
+103.78.68.0/22
+103.78.124.0/22
+103.78.172.0/22
+103.78.176.0/22
+103.78.196.0/22
+103.78.228.0/22
+103.79.24.0/22
+103.79.28.0/22
+103.79.36.0/22
+103.79.40.0/22
+103.79.44.0/22
+103.79.52.0/22
+103.79.56.0/22
+103.79.60.0/22
+103.79.64.0/22
+103.79.68.0/22
+103.79.80.0/22
+103.79.84.0/22
+103.79.120.0/22
+103.79.136.0/22
+103.79.188.0/22
+103.79.192.0/22
+103.79.196.0/22
+103.79.200.0/22
+103.79.204.0/22
+103.79.208.0/22
+103.79.212.0/22
+103.79.240.0/22
+103.80.24.0/22
+103.80.28.0/22
+103.80.44.0/22
+103.80.72.0/22
+103.80.176.0/22
+103.80.180.0/22
+103.80.184.0/22
+103.80.192.0/22
+103.80.200.0/22
+103.80.232.0/22
+103.81.4.0/22
+103.81.8.0/22
+103.81.16.0/22
+103.81.20.0/22
+103.81.44.0/22
+103.81.48.0/22
+103.81.96.0/22
+103.81.120.0/22
+103.81.148.0/22
+103.81.164.0/22
+103.81.168.0/22
+103.81.183.0/24
+103.81.184.0/22
+103.81.200.0/22
+103.81.232.0/22
+103.82.52.0/22
+103.82.60.0/22
+103.82.68.0/22
+103.82.84.0/22
+103.82.104.0/22
+103.82.224.0/22
+103.82.236.0/22
+103.83.44.0/22
+103.83.52.0/22
+103.83.60.0/22
+103.83.64.0/22
+103.83.72.0/22
+103.83.112.0/22
+103.83.120.0/22
+103.83.180.0/22
+103.84.0.0/22
+103.84.12.0/22
+103.84.16.0/22
+103.84.20.0/22
+103.84.24.0/22
+103.84.28.0/22
+103.84.48.0/22
+103.84.64.0/22
+103.84.72.0/22
+103.84.92.0/22
+103.84.108.0/22
+103.84.136.0/22
+103.85.20.0/22
+103.85.24.0/22
+103.85.44.0/22
+103.85.48.0/22
+103.85.84.0/22
+103.85.136.0/22
+103.85.144.0/22
+103.85.164.0/22
+103.85.168.0/22
+103.85.172.0/22
+103.85.176.0/22
+103.85.224.0/22
+103.86.28.0/22
+103.86.32.0/22
+103.86.44.0/22
+103.86.60.0/22
+103.86.68.0/22
+103.86.80.0/22
+103.86.84.0/22
+103.86.88.0/22
+103.86.204.0/22
+103.86.208.0/22
+103.86.212.0/22
+103.86.216.0/22
+103.86.220.0/22
+103.86.224.0/22
+103.86.228.0/22
+103.86.232.0/22
+103.86.236.0/22
+103.86.240.0/22
+103.86.244.0/22
+103.86.248.0/22
+103.86.252.0/22
+103.87.0.0/22
+103.87.4.0/22
+103.87.20.0/22
+103.87.32.0/22
+103.87.72.0/22
+103.87.96.0/22
+103.87.132.0/22
+103.87.180.0/22
+103.87.224.0/22
+103.88.4.0/22
+103.88.8.0/22
+103.88.12.0/22
+103.88.16.0/22
+103.88.20.0/22
+103.88.32.0/22
+103.88.36.0/22
+103.88.60.0/22
+103.88.64.0/22
+103.88.72.0/22
+103.88.96.0/22
+103.88.100.0/22
+103.88.164.0/22
+103.88.176.0/22
+103.88.184.0/22
+103.88.188.0/22
+103.88.212.0/22
+103.89.28.0/22
+103.89.96.0/22
+103.89.100.0/22
+103.89.104.0/22
+103.89.108.0/22
+103.89.112.0/22
+103.89.116.0/22
+103.89.148.0/22
+103.89.172.0/22
+103.89.184.0/22
+103.89.188.0/22
+103.89.192.0/22
+103.89.196.0/22
+103.89.200.0/22
+103.89.204.0/22
+103.89.208.0/22
+103.89.212.0/22
+103.89.216.0/22
+103.89.220.0/22
+103.89.224.0/22
+103.89.228.0/22
+103.90.52.0/22
+103.90.92.0/22
+103.90.100.0/22
+103.90.104.0/22
+103.90.108.0/22
+103.90.112.0/22
+103.90.116.0/22
+103.90.120.0/22
+103.90.124.0/22
+103.90.128.0/22
+103.90.132.0/22
+103.90.152.0/22
+103.90.168.0/22
+103.90.173.0/24
+103.90.176.0/22
+103.90.188.0/22
+103.90.192.0/22
+103.91.36.0/22
+103.91.40.0/22
+103.91.108.0/22
+103.91.152.0/22
+103.91.176.0/22
+103.91.200.0/22
+103.91.208.0/22
+103.91.212.0/22
+103.91.219.0/24
+103.91.236.0/22
+103.91.252.0/22
+103.92.0.0/22
+103.92.4.0/22
+103.92.8.0/22
+103.92.12.0/22
+103.92.48.0/22
+103.92.52.0/22
+103.92.56.0/22
+103.92.60.0/22
+103.92.64.0/22
+103.92.68.0/22
+103.92.72.0/22
+103.92.76.0/22
+103.92.80.0/22
+103.92.86.0/24
+103.92.88.0/22
+103.92.108.0/22
+103.92.124.0/22
+103.92.128.0/24
+103.92.132.0/22
+103.92.156.0/22
+103.92.164.0/22
+103.92.168.0/22
+103.92.172.0/22
+103.92.176.0/22
+103.92.180.0/22
+103.92.184.0/22
+103.92.188.0/22
+103.92.192.0/22
+103.92.236.0/22
+103.92.240.0/22
+103.92.244.0/22
+103.92.248.0/22
+103.92.252.0/22
+103.93.0.0/22
+103.93.4.0/22
+103.93.28.0/22
+103.93.76.0/22
+103.93.84.0/22
+103.93.121.0/24
+103.93.152.0/22
+103.93.180.0/22
+103.93.204.0/22
+103.94.12.0/22
+103.94.20.0/22
+103.94.28.0/22
+103.94.32.0/22
+103.94.36.0/22
+103.94.40.0/22
+103.94.44.0/22
+103.94.72.0/22
+103.94.88.0/22
+103.94.116.0/22
+103.94.160.0/22
+103.94.180.0/22
+103.94.200.0/22
+103.95.28.0/22
+103.95.52.0/22
+103.95.64.0/22
+103.95.68.0/22
+103.95.88.0/22
+103.95.92.0/22
+103.95.116.0/22
+103.95.128.0/22
+103.95.136.0/22
+103.95.140.0/22
+103.95.144.0/22
+103.95.152.0/22
+103.95.207.0/24
+103.95.216.0/22
+103.95.220.0/22
+103.95.224.0/22
+103.95.236.0/22
+103.95.240.0/22
+103.95.244.0/22
+103.95.248.0/22
+103.95.252.0/22
+103.96.0.0/22
+103.96.8.0/22
+103.96.80.0/22
+103.96.124.0/22
+103.96.136.0/22
+103.96.140.0/24
+103.96.148.0/22
+103.96.152.0/22
+103.96.156.0/22
+103.96.160.0/22
+103.96.164.0/22
+103.96.168.0/22
+103.96.172.0/22
+103.96.176.0/22
+103.96.180.0/22
+103.96.184.0/22
+103.96.188.0/22
+103.96.192.0/22
+103.96.196.0/22
+103.96.200.0/22
+103.96.204.0/22
+103.96.208.0/22
+103.96.212.0/22
+103.96.216.0/22
+103.97.8.0/22
+103.97.12.0/22
+103.97.16.0/22
+103.97.20.0/22
+103.97.24.0/22
+103.97.28.0/22
+103.97.32.0/22
+103.97.36.0/22
+103.97.40.0/22
+103.97.56.0/22
+103.97.60.0/22
+103.97.64.0/22
+103.97.68.0/22
+103.97.72.0/22
+103.97.80.0/22
+103.97.112.0/22
+103.97.116.0/22
+103.97.128.0/22
+103.97.144.0/22
+103.97.148.0/22
+103.97.188.0/22
+103.97.192.0/22
+103.97.224.0/22
+103.97.228.0/23
+103.98.28.0/23
+103.98.40.0/22
+103.98.44.0/22
+103.98.48.0/22
+103.98.56.0/22
+103.98.80.0/22
+103.98.88.0/22
+103.98.92.0/22
+103.98.96.0/22
+103.98.100.0/22
+103.98.124.0/22
+103.98.136.0/22
+103.98.140.0/22
+103.98.144.0/22
+103.98.164.0/22
+103.98.168.0/22
+103.98.180.0/22
+103.98.196.0/22
+103.98.216.0/22
+103.98.220.0/22
+103.98.224.0/22
+103.98.228.0/22
+103.98.232.0/22
+103.98.240.0/22
+103.98.244.0/22
+103.98.248.0/22
+103.98.252.0/22
+103.99.40.0/23
+103.99.52.0/22
+103.99.56.0/22
+103.99.60.0/22
+103.99.76.0/22
+103.99.104.0/22
+103.99.116.0/22
+103.99.120.0/22
+103.99.152.0/22
+103.99.220.0/22
+103.99.232.0/22
+103.99.236.0/22
+103.100.0.0/22
+103.100.32.0/22
+103.100.40.0/22
+103.100.48.0/22
+103.100.52.0/22
+103.100.56.0/22
+103.100.60.0/22
+103.100.64.0/22
+103.100.68.0/22
+103.100.88.0/22
+103.100.116.0/22
+103.100.140.0/22
+103.100.144.0/22
+103.100.236.0/22
+103.100.240.0/22
+103.100.248.0/22
+103.100.252.0/22
+103.101.4.0/22
+103.101.8.0/22
+103.101.12.0/22
+103.101.28.0/22
+103.101.60.0/22
+103.101.120.0/22
+103.101.124.0/22
+103.101.144.0/22
+103.101.148.0/22
+103.101.153.0/24
+103.101.180.0/22
+103.101.184.0/22
+103.102.76.0/22
+103.102.80.0/22
+103.102.168.0/22
+103.102.172.0/22
+103.102.180.0/22
+103.102.184.0/22
+103.102.188.0/22
+103.102.192.0/22
+103.102.196.0/22
+103.102.200.0/22
+103.102.208.0/22
+103.102.212.0/22
+103.103.12.0/22
+103.103.16.0/22
+103.103.36.0/22
+103.103.68.0/22
+103.103.72.0/22
+103.103.176.0/22
+103.103.188.0/22
+103.103.200.0/22
+103.103.204.0/22
+103.103.220.0/22
+103.103.224.0/22
+103.103.228.0/22
+103.103.232.0/22
+103.103.248.0/22
+103.103.252.0/22
+103.104.0.0/22
+103.104.4.0/22
+103.104.36.0/22
+103.104.40.0/22
+103.104.64.0/22
+103.104.104.0/22
+103.104.152.0/22
+103.104.168.0/22
+103.104.172.0/22
+103.104.188.0/22
+103.104.198.0/23
+103.104.252.0/22
+103.105.0.0/22
+103.105.4.0/22
+103.105.12.0/22
+103.105.16.0/22
+103.105.23.0/24
+103.105.56.0/22
+103.105.60.0/22
+103.105.116.0/22
+103.105.132.0/22
+103.105.180.0/22
+103.105.184.0/22
+103.105.200.0/22
+103.105.204.0/22
+103.105.220.0/22
+103.106.36.0/22
+103.106.40.0/22
+103.106.44.0/22
+103.106.60.0/22
+103.106.68.0/22
+103.106.96.0/22
+103.106.120.0/22
+103.106.128.0/22
+103.106.132.0/22
+103.106.160.0/22
+103.106.188.0/22
+103.106.196.0/22
+103.106.202.0/23
+103.106.212.0/22
+103.106.244.0/22
+103.106.252.0/22
+103.107.0.0/22
+103.107.8.0/24
+103.107.28.0/22
+103.107.32.0/22
+103.107.44.0/22
+103.107.72.0/22
+103.107.108.0/22
+103.107.164.0/22
+103.107.168.0/22
+103.107.188.0/22
+103.107.192.0/22
+103.107.208.0/22
+103.107.212.0/22
+103.107.216.0/22
+103.107.220.0/22
+103.108.52.0/22
+103.108.64.0/22
+103.108.160.0/22
+103.108.164.0/22
+103.108.184.0/23
+103.108.188.0/23
+103.108.192.0/22
+103.108.196.0/22
+103.108.208.0/22
+103.108.212.0/22
+103.108.224.0/22
+103.108.244.0/22
+103.108.251.0/24
+103.109.20.0/22
+103.109.48.0/22
+103.109.88.0/22
+103.109.106.0/23
+103.109.248.0/22
+103.110.32.0/22
+103.110.80.0/23
+103.110.92.0/22
+103.110.100.0/22
+103.110.116.0/22
+103.110.127.0/24
+103.110.128.0/23
+103.110.131.0/24
+103.110.132.0/22
+103.110.136.0/22
+103.110.152.0/22
+103.110.156.0/22
+103.110.188.0/22
+103.110.204.0/22
+103.111.38.0/23
+103.111.64.0/22
+103.111.172.0/22
+103.111.252.0/22
+103.112.28.0/22
+103.112.68.0/22
+103.112.72.0/22
+103.112.88.0/22
+103.112.92.0/22
+103.112.96.0/22
+103.112.108.0/22
+103.112.112.0/22
+103.112.116.0/22
+103.112.140.0/22
+103.112.172.0/22
+103.112.184.0/22
+103.112.208.0/22
+103.113.4.0/22
+103.113.92.0/22
+103.113.144.0/22
+103.113.220.0/22
+103.113.232.0/22
+103.113.236.0/22
+103.114.4.0/22
+103.114.28.0/22
+103.114.68.0/22
+103.114.72.0/22
+103.114.100.0/22
+103.114.132.0/22
+103.114.148.0/22
+103.114.156.0/22
+103.114.176.0/22
+103.114.212.0/22
+103.114.236.0/22
+103.114.240.0/22
+103.115.16.0/22
+103.115.40.0/22
+103.115.44.0/22
+103.115.48.0/22
+103.115.52.0/22
+103.115.56.0/22
+103.115.60.0/22
+103.115.64.0/22
+103.115.68.0/22
+103.115.92.0/22
+103.115.120.0/22
+103.115.148.0/22
+103.115.204.0/23
+103.115.248.0/22
+103.116.20.0/22
+103.116.40.0/22
+103.116.64.0/22
+103.116.72.0/22
+103.116.76.0/22
+103.116.92.0/22
+103.116.120.0/22
+103.116.128.0/22
+103.116.132.0/23
+103.116.148.0/22
+103.116.184.0/22
+103.116.206.0/23
+103.116.220.0/22
+103.116.224.0/22
+103.116.228.0/22
+103.117.16.0/22
+103.117.72.0/22
+103.117.88.0/22
+103.117.132.0/22
+103.117.136.0/22
+103.117.188.0/22
+103.117.220.0/22
+103.118.19.0/24
+103.118.36.0/22
+103.118.52.0/22
+103.118.56.0/22
+103.118.60.0/22
+103.118.64.0/22
+103.118.68.0/22
+103.118.72.0/22
+103.118.88.0/22
+103.118.173.0/24
+103.118.192.0/22
+103.118.196.0/22
+103.118.200.0/22
+103.118.204.0/22
+103.118.208.0/22
+103.118.212.0/22
+103.118.216.0/22
+103.118.220.0/22
+103.118.240.0/22
+103.118.244.0/22
+103.118.248.0/22
+103.118.252.0/22
+103.119.0.0/22
+103.119.12.0/22
+103.119.16.0/22
+103.119.28.0/22
+103.119.44.0/22
+103.119.104.0/22
+103.119.115.0/24
+103.119.156.0/22
+103.119.180.0/22
+103.119.200.0/22
+103.119.224.0/22
+103.120.52.0/22
+103.120.72.0/22
+103.120.76.0/24
+103.120.88.0/22
+103.120.96.0/22
+103.120.100.0/22
+103.120.140.0/22
+103.120.196.0/22
+103.120.224.0/22
+103.121.52.0/22
+103.121.92.0/22
+103.121.160.0/22
+103.121.164.0/22
+103.121.250.0/24
+103.121.252.0/22
+103.122.48.0/22
+103.122.176.0/22
+103.122.192.0/22
+103.122.240.0/22
+103.123.4.0/22
+103.123.56.0/22
+103.123.88.0/22
+103.123.92.0/22
+103.123.116.0/22
+103.123.160.0/22
+103.123.176.0/22
+103.123.200.0/22
+103.123.204.0/22
+103.123.208.0/22
+103.123.212.0/22
+103.124.24.0/22
+103.124.48.0/22
+103.124.64.0/22
+103.124.212.0/22
+103.124.216.0/22
+103.125.20.0/22
+103.125.44.0/22
+103.125.132.0/22
+103.125.164.0/22
+103.125.196.0/22
+103.125.236.0/22
+103.125.248.0/22
+103.126.0.0/22
+103.126.16.0/22
+103.126.44.0/22
+103.126.100.0/22
+103.126.124.0/22
+103.126.128.0/22
+103.126.132.0/22
+103.126.208.0/22
+103.126.241.0/24
+103.129.52.0/22
+103.130.132.0/22
+103.130.152.0/24
+103.130.160.0/22
+103.130.228.0/22
+103.131.20.0/22
+103.131.36.0/22
+103.131.152.0/22
+103.131.168.0/22
+103.131.176.0/22
+103.131.224.0/22
+103.131.228.0/22
+103.131.240.0/22
+103.132.60.0/22
+103.132.64.0/22
+103.132.68.0/22
+103.132.72.0/22
+103.132.76.0/22
+103.132.80.0/22
+103.132.104.0/22
+103.132.108.0/22
+103.132.112.0/22
+103.132.116.0/22
+103.132.120.0/22
+103.132.160.0/22
+103.132.164.0/22
+103.132.188.0/22
+103.132.208.0/22
+103.132.212.0/22
+103.132.234.0/23
+103.133.12.0/22
+103.133.40.0/22
+103.133.128.0/22
+103.133.136.0/22
+103.133.176.0/22
+103.133.232.0/22
+103.134.12.0/24
+103.134.196.0/22
+103.135.80.0/22
+103.135.124.0/22
+103.135.148.0/22
+103.135.156.0/22
+103.135.160.0/22
+103.135.164.0/22
+103.135.176.0/22
+103.135.184.0/22
+103.135.192.0/22
+103.135.196.0/22
+103.135.236.0/22
+103.136.128.0/22
+103.136.232.0/22
+103.137.58.0/23
+103.137.60.0/24
+103.137.76.0/22
+103.137.136.0/23
+103.137.149.0/24
+103.137.180.0/22
+103.137.236.0/22
+103.138.2.0/23
+103.138.12.0/23
+103.138.80.0/22
+103.138.134.0/23
+103.138.156.0/23
+103.138.208.0/23
+103.138.220.0/23
+103.138.246.0/23
+103.138.248.0/23
+103.139.0.0/23
+103.139.2.0/23
+103.139.22.0/23
+103.139.113.0/24
+103.139.134.0/23
+103.139.136.0/23
+103.139.172.0/23
+103.139.200.0/23
+103.139.204.0/23
+103.139.212.0/23
+103.140.8.0/23
+103.140.14.0/23
+103.140.46.0/23
+103.140.70.0/23
+103.140.126.0/23
+103.140.140.0/23
+103.140.144.0/23
+103.140.152.0/23
+103.140.192.0/23
+103.140.194.0/23
+103.140.228.0/23
+103.141.10.0/23
+103.141.36.0/23
+103.141.58.0/23
+103.141.128.0/23
+103.141.186.0/23
+103.141.190.0/23
+103.141.242.0/23
+103.142.0.0/23
+103.142.28.0/23
+103.142.58.0/23
+103.142.82.0/23
+103.142.96.0/23
+103.142.102.0/23
+103.142.122.0/23
+103.142.126.0/24
+103.142.128.0/23
+103.142.140.0/23
+103.142.154.0/23
+103.142.156.0/23
+103.142.172.0/23
+103.142.180.0/23
+103.142.186.0/23
+103.142.190.0/23
+103.142.220.0/23
+103.142.230.0/24
+103.142.234.0/23
+103.142.238.0/23
+103.142.248.0/23
+103.143.16.0/23
+103.143.18.0/23
+103.143.31.0/24
+103.143.74.0/23
+103.143.120.0/23
+103.143.124.0/23
+103.143.132.0/23
+103.143.134.0/23
+103.143.174.0/23
+103.143.228.0/23
+103.144.40.0/23
+103.144.52.0/23
+103.144.66.0/23
+103.144.70.0/23
+103.144.72.0/23
+103.144.88.0/24
+103.144.108.0/23
+103.144.136.0/23
+103.144.148.0/23
+103.144.158.0/23
+103.144.240.0/23
+103.145.38.0/23
+103.145.40.0/23
+103.145.42.0/23
+103.145.60.0/23
+103.145.72.0/23
+103.145.80.0/23
+103.145.86.0/23
+103.145.92.0/23
+103.145.94.0/23
+103.145.98.0/23
+103.145.106.0/23
+103.145.122.0/23
+103.145.188.0/23
+103.145.190.0/23
+103.146.6.0/23
+103.146.72.0/23
+103.146.88.0/23
+103.146.90.0/23
+103.146.124.0/23
+103.146.126.0/23
+103.146.138.0/23
+103.146.147.0/24
+103.146.230.0/23
+103.146.236.0/23
+103.146.252.0/23
+103.147.12.0/23
+103.192.0.0/22
+103.192.4.0/22
+103.192.8.0/22
+103.192.12.0/22
+103.192.16.0/22
+103.192.20.0/22
+103.192.24.0/22
+103.192.28.0/22
+103.192.48.0/22
+103.192.52.0/22
+103.192.56.0/22
+103.192.84.0/22
+103.192.88.0/22
+103.192.92.0/22
+103.192.96.0/22
+103.192.100.0/22
+103.192.104.0/22
+103.192.108.0/22
+103.192.112.0/22
+103.192.128.0/22
+103.192.132.0/22
+103.192.136.0/22
+103.192.140.0/22
+103.192.144.0/22
+103.192.164.0/22
+103.192.188.0/22
+103.192.208.0/22
+103.192.212.0/22
+103.192.216.0/22
+103.192.252.0/22
+103.193.40.0/22
+103.193.44.0/22
+103.193.120.0/22
+103.193.124.0/22
+103.193.140.0/22
+103.193.144.0/22
+103.193.148.0/22
+103.193.160.0/22
+103.193.188.0/22
+103.193.192.0/22
+103.193.212.0/22
+103.193.216.0/22
+103.193.220.0/22
+103.193.224.0/22
+103.193.228.0/22
+103.193.232.0/22
+103.193.236.0/22
+103.193.240.0/22
+103.194.16.0/22
+103.195.104.0/22
+103.195.112.0/22
+103.195.136.0/22
+103.195.148.0/22
+103.195.152.0/22
+103.195.160.0/22
+103.195.192.0/22
+103.196.60.0/22
+103.196.64.0/22
+103.196.72.0/22
+103.196.88.0/22
+103.196.92.0/22
+103.196.96.0/22
+103.196.168.0/22
+103.196.204.0/22
+103.197.180.0/22
+103.197.228.0/22
+103.198.20.0/22
+103.198.60.0/22
+103.198.64.0/22
+103.198.72.0/22
+103.198.124.0/22
+103.198.156.0/22
+103.198.180.0/22
+103.198.196.0/22
+103.198.200.0/22
+103.198.216.0/22
+103.198.220.0/22
+103.198.224.0/22
+103.198.228.0/22
+103.198.232.0/22
+103.198.236.0/22
+103.198.240.0/22
+103.198.244.0/22
+103.199.164.0/22
+103.199.196.0/22
+103.199.228.0/22
+103.199.248.0/22
+103.199.252.0/22
+103.200.28.0/22
+103.200.32.0/22
+103.200.52.0/22
+103.200.64.0/22
+103.200.68.0/22
+103.200.136.0/22
+103.200.140.0/22
+103.200.144.0/22
+103.200.148.0/22
+103.200.152.0/22
+103.200.156.0/22
+103.200.160.0/22
+103.200.164.0/22
+103.200.168.0/22
+103.200.172.0/22
+103.200.176.0/22
+103.200.180.0/22
+103.200.184.0/22
+103.200.188.0/22
+103.200.192.0/22
+103.200.220.0/22
+103.200.224.0/22
+103.200.228.0/22
+103.200.232.0/22
+103.200.236.0/22
+103.200.240.0/22
+103.200.244.0/22
+103.200.248.0/22
+103.200.252.0/22
+103.201.0.0/22
+103.201.4.0/22
+103.201.8.0/22
+103.201.12.0/22
+103.201.16.0/22
+103.201.20.0/22
+103.201.28.0/22
+103.201.32.0/22
+103.201.36.0/22
+103.201.40.0/22
+103.201.44.0/22
+103.201.48.0/22
+103.201.52.0/22
+103.201.56.0/22
+103.201.60.0/22
+103.201.64.0/22
+103.201.76.0/22
+103.201.80.0/22
+103.201.84.0/22
+103.201.88.0/22
+103.201.92.0/22
+103.201.96.0/22
+103.201.100.0/22
+103.201.104.0/22
+103.201.108.0/22
+103.201.112.0/22
+103.201.116.0/22
+103.201.120.0/22
+103.201.152.0/22
+103.201.156.0/22
+103.201.160.0/22
+103.201.164.0/22
+103.201.168.0/22
+103.201.172.0/22
+103.201.176.0/22
+103.201.180.0/22
+103.201.184.0/22
+103.201.188.0/22
+103.201.192.0/22
+103.201.196.0/22
+103.201.200.0/22
+103.201.204.0/22
+103.201.208.0/22
+103.201.212.0/22
+103.201.216.0/22
+103.201.220.0/22
+103.201.224.0/22
+103.201.228.0/22
+103.201.232.0/22
+103.201.236.0/22
+103.201.240.0/22
+103.201.244.0/22
+103.201.248.0/22
+103.201.252.0/22
+103.202.0.0/22
+103.202.4.0/22
+103.202.8.0/22
+103.202.12.0/22
+103.202.16.0/22
+103.202.20.0/22
+103.202.24.0/22
+103.202.28.0/22
+103.202.32.0/22
+103.202.36.0/22
+103.202.40.0/22
+103.202.44.0/22
+103.202.56.0/22
+103.202.60.0/22
+103.202.64.0/22
+103.202.68.0/22
+103.202.72.0/22
+103.202.76.0/22
+103.202.80.0/22
+103.202.84.0/22
+103.202.88.0/22
+103.202.92.0/22
+103.202.96.0/22
+103.202.100.0/22
+103.202.104.0/22
+103.202.108.0/22
+103.202.112.0/22
+103.202.116.0/22
+103.202.120.0/22
+103.202.124.0/22
+103.202.128.0/22
+103.202.132.0/22
+103.202.136.0/22
+103.202.140.0/22
+103.202.144.0/22
+103.202.152.0/22
+103.202.156.0/22
+103.202.160.0/22
+103.202.164.0/22
+103.202.168.0/22
+103.202.172.0/22
+103.202.176.0/22
+103.202.180.0/22
+103.202.184.0/22
+103.202.188.0/22
+103.202.192.0/22
+103.202.196.0/22
+103.202.200.0/21
+103.202.212.0/22
+103.202.228.0/22
+103.202.236.0/22
+103.202.240.0/22
+103.202.244.0/22
+103.202.248.0/22
+103.202.252.0/22
+103.203.0.0/22
+103.203.4.0/22
+103.203.8.0/22
+103.203.12.0/22
+103.203.16.0/22
+103.203.20.0/22
+103.203.24.0/22
+103.203.28.0/22
+103.203.32.0/22
+103.203.52.0/22
+103.203.56.0/22
+103.203.96.0/22
+103.203.100.0/22
+103.203.104.0/22
+103.203.108.0/22
+103.203.112.0/22
+103.203.116.0/22
+103.203.120.0/22
+103.203.124.0/22
+103.203.128.0/22
+103.203.140.0/22
+103.203.164.0/22
+103.203.168.0/22
+103.203.192.0/22
+103.203.200.0/22
+103.203.212.0/22
+103.203.216.0/22
+103.204.24.0/22
+103.204.72.0/22
+103.204.88.0/22
+103.204.112.0/22
+103.204.136.0/22
+103.204.140.0/22
+103.204.144.0/22
+103.204.148.0/22
+103.204.152.0/22
+103.204.196.0/22
+103.204.232.0/22
+103.204.236.0/22
+103.205.4.0/22
+103.205.8.0/22
+103.205.40.0/22
+103.205.44.0/22
+103.205.52.0/22
+103.205.108.0/22
+103.205.116.0/22
+103.205.120.0/22
+103.205.136.0/22
+103.205.162.0/24
+103.205.188.0/22
+103.205.192.0/22
+103.205.196.0/22
+103.205.200.0/22
+103.205.236.0/22
+103.205.248.0/22
+103.205.252.0/22
+103.206.0.0/22
+103.206.44.0/22
+103.206.108.0/22
+103.206.148.0/22
+103.207.48.0/22
+103.207.104.0/22
+103.207.164.0/22
+103.207.184.0/22
+103.207.188.0/22
+103.207.192.0/22
+103.207.196.0/22
+103.207.200.0/22
+103.207.204.0/22
+103.207.208.0/22
+103.207.212.0/22
+103.207.220.0/22
+103.207.228.0/22
+103.207.232.0/22
+103.208.12.0/22
+103.208.16.0/22
+103.208.28.0/22
+103.208.40.0/22
+103.208.44.0/22
+103.208.48.0/22
+103.208.148.0/22
+103.209.112.0/22
+103.209.136.0/22
+103.209.200.0/22
+103.209.208.0/22
+103.209.216.0/22
+103.210.0.0/22
+103.210.20.0/22
+103.210.96.0/22
+103.210.156.0/22
+103.210.160.0/22
+103.210.164.0/22
+103.210.168.0/22
+103.210.172.0/22
+103.210.176.0/22
+103.210.180.0/22
+103.210.184.0/22
+103.210.188.0/22
+103.210.216.0/22
+103.211.44.0/22
+103.211.96.0/22
+103.211.100.0/22
+103.211.156.0/22
+103.211.164.0/22
+103.211.192.0/22
+103.211.220.0/22
+103.211.224.0/22
+103.211.248.0/22
+103.212.0.0/22
+103.212.4.0/22
+103.212.8.0/22
+103.212.12.0/22
+103.212.32.0/22
+103.212.44.0/22
+103.212.48.0/22
+103.212.84.0/22
+103.212.100.0/22
+103.212.104.0/22
+103.212.108.0/22
+103.212.148.0/22
+103.212.164.0/22
+103.212.196.0/22
+103.212.200.0/22
+103.212.228.0/22
+103.212.252.0/22
+103.213.40.0/22
+103.213.44.0/22
+103.213.48.0/22
+103.213.52.0/22
+103.213.56.0/22
+103.213.60.0/22
+103.213.64.0/22
+103.213.68.0/22
+103.213.72.0/22
+103.213.76.0/22
+103.213.80.0/22
+103.213.84.0/22
+103.213.88.0/22
+103.213.92.0/22
+103.213.96.0/22
+103.213.132.0/22
+103.213.136.0/22
+103.213.140.0/22
+103.213.144.0/22
+103.213.148.0/22
+103.213.152.0/22
+103.213.156.0/22
+103.213.160.0/22
+103.213.164.0/22
+103.213.168.0/22
+103.213.172.0/22
+103.213.176.0/22
+103.213.180.0/22
+103.213.184.0/22
+103.213.188.0/22
+103.213.248.0/22
+103.214.32.0/22
+103.214.48.0/22
+103.214.84.0/22
+103.214.168.0/22
+103.214.212.0/22
+103.214.240.0/22
+103.214.244.0/22
+103.215.28.0/22
+103.215.32.0/22
+103.215.36.0/22
+103.215.44.0/22
+103.215.48.0/22
+103.215.100.0/22
+103.215.104.0/22
+103.215.108.0/22
+103.215.116.0/22
+103.215.120.0/22
+103.215.140.0/22
+103.215.184.0/22
+103.215.228.0/22
+103.216.4.0/22
+103.216.8.0/22
+103.216.12.0/22
+103.216.16.0/22
+103.216.20.0/22
+103.216.24.0/22
+103.216.28.0/22
+103.216.32.0/22
+103.216.36.0/22
+103.216.40.0/22
+103.216.44.0/22
+103.216.64.0/22
+103.216.108.0/22
+103.216.136.0/22
+103.216.152.0/22
+103.216.224.0/22
+103.216.228.0/22
+103.216.240.0/22
+103.216.244.0/22
+103.216.248.0/22
+103.216.252.0/22
+103.217.0.0/22
+103.217.4.0/22
+103.217.8.0/22
+103.217.12.0/22
+103.217.16.0/22
+103.217.20.0/22
+103.217.24.0/22
+103.217.28.0/22
+103.217.32.0/22
+103.217.36.0/22
+103.217.40.0/22
+103.217.44.0/22
+103.217.48.0/22
+103.217.52.0/22
+103.217.56.0/22
+103.217.60.0/22
+103.217.168.0/22
+103.217.180.0/22
+103.217.184.0/22
+103.217.188.0/22
+103.217.192.0/22
+103.217.196.0/22
+103.217.200.0/22
+103.217.204.0/22
+103.218.0.0/22
+103.218.8.0/22
+103.218.12.0/22
+103.218.16.0/22
+103.218.20.0/22
+103.218.28.0/22
+103.218.32.0/22
+103.218.36.0/22
+103.218.40.0/22
+103.218.44.0/22
+103.218.48.0/22
+103.218.52.0/22
+103.218.56.0/22
+103.218.60.0/22
+103.218.64.0/22
+103.218.68.0/22
+103.218.72.0/22
+103.218.76.0/22
+103.218.80.0/22
+103.218.84.0/22
+103.218.88.0/22
+103.218.92.0/22
+103.218.184.0/22
+103.218.192.0/22
+103.218.196.0/22
+103.218.200.0/22
+103.218.204.0/22
+103.218.208.0/22
+103.218.212.0/22
+103.218.216.0/22
+103.219.24.0/22
+103.219.28.0/22
+103.219.32.0/22
+103.219.36.0/22
+103.219.64.0/22
+103.219.84.0/22
+103.219.88.0/22
+103.219.92.0/22
+103.219.96.0/22
+103.219.100.0/22
+103.219.176.0/22
+103.219.184.0/22
+103.220.48.0/22
+103.220.52.0/22
+103.220.56.0/22
+103.220.60.0/22
+103.220.64.0/22
+103.220.92.0/22
+103.220.96.0/22
+103.220.100.0/22
+103.220.104.0/22
+103.220.108.0/22
+103.220.116.0/22
+103.220.120.0/22
+103.220.124.0/22
+103.220.128.0/22
+103.220.132.0/22
+103.220.136.0/22
+103.220.140.0/22
+103.220.144.0/22
+103.220.148.0/22
+103.220.152.0/22
+103.220.160.0/22
+103.220.164.0/22
+103.220.168.0/22
+103.220.172.0/22
+103.220.176.0/22
+103.220.180.0/22
+103.220.184.0/22
+103.220.188.0/22
+103.220.192.0/22
+103.220.196.0/22
+103.220.200.0/22
+103.220.240.0/22
+103.220.244.0/22
+103.220.248.0/22
+103.220.252.0/22
+103.221.0.0/22
+103.221.4.0/22
+103.221.8.0/22
+103.221.12.0/22
+103.221.16.0/22
+103.221.20.0/22
+103.221.24.0/22
+103.221.28.0/22
+103.221.32.0/22
+103.221.36.0/22
+103.221.40.0/22
+103.221.44.0/22
+103.221.48.0/22
+103.221.88.0/22
+103.221.92.0/22
+103.221.96.0/22
+103.221.100.0/22
+103.221.104.0/22
+103.221.108.0/22
+103.221.112.0/22
+103.221.116.0/22
+103.221.120.0/22
+103.221.124.0/22
+103.221.128.0/22
+103.221.132.0/22
+103.221.136.0/22
+103.221.140.0/22
+103.221.144.0/22
+103.221.148.0/22
+103.221.152.0/22
+103.221.156.0/22
+103.221.160.0/22
+103.221.164.0/22
+103.221.168.0/22
+103.221.172.0/22
+103.221.176.0/22
+103.221.180.0/22
+103.221.184.0/22
+103.221.188.0/22
+103.221.192.0/22
+103.221.196.0/22
+103.221.200.0/22
+103.221.204.0/22
+103.222.0.0/22
+103.222.4.0/22
+103.222.8.0/22
+103.222.12.0/22
+103.222.16.0/22
+103.222.24.0/22
+103.222.28.0/22
+103.222.32.0/22
+103.222.36.0/22
+103.222.40.0/22
+103.222.44.0/22
+103.222.48.0/22
+103.222.52.0/22
+103.222.56.0/22
+103.222.60.0/22
+103.222.64.0/22
+103.222.68.0/22
+103.222.72.0/22
+103.222.76.0/22
+103.222.80.0/22
+103.222.84.0/22
+103.222.88.0/22
+103.222.92.0/22
+103.222.96.0/22
+103.222.100.0/22
+103.222.104.0/22
+103.222.108.0/22
+103.222.112.0/22
+103.222.116.0/22
+103.222.120.0/22
+103.222.124.0/22
+103.222.128.0/22
+103.222.132.0/22
+103.222.136.0/22
+103.222.140.0/22
+103.222.144.0/22
+103.222.148.0/22
+103.222.152.0/22
+103.222.156.0/22
+103.222.160.0/22
+103.222.164.0/22
+103.222.168.0/22
+103.222.172.0/22
+103.222.176.0/22
+103.222.180.0/22
+103.222.184.0/22
+103.222.188.0/22
+103.222.192.0/22
+103.222.196.0/22
+103.222.200.0/22
+103.222.204.0/22
+103.222.208.0/22
+103.222.212.0/22
+103.222.216.0/22
+103.222.220.0/22
+103.222.224.0/22
+103.222.228.0/22
+103.222.232.0/22
+103.222.240.0/22
+103.222.244.0/22
+103.223.16.0/22
+103.223.20.0/22
+103.223.24.0/22
+103.223.28.0/22
+103.223.32.0/22
+103.223.36.0/22
+103.223.40.0/22
+103.223.44.0/22
+103.223.48.0/22
+103.223.52.0/22
+103.223.56.0/22
+103.223.60.0/22
+103.223.64.0/22
+103.223.68.0/22
+103.223.72.0/22
+103.223.76.0/22
+103.223.80.0/22
+103.223.84.0/22
+103.223.88.0/22
+103.223.92.0/22
+103.223.96.0/22
+103.223.100.0/22
+103.223.104.0/22
+103.223.108.0/22
+103.223.112.0/22
+103.223.116.0/22
+103.223.120.0/22
+103.223.124.0/22
+103.223.128.0/22
+103.223.132.0/22
+103.223.140.0/22
+103.223.144.0/22
+103.223.148.0/22
+103.223.152.0/22
+103.223.156.0/22
+103.223.160.0/22
+103.223.164.0/22
+103.223.168.0/22
+103.223.172.0/22
+103.223.176.0/22
+103.223.180.0/22
+103.223.188.0/22
+103.223.192.0/22
+103.223.196.0/22
+103.223.200.0/22
+103.223.204.0/22
+103.223.208.0/22
+103.223.212.0/22
+103.223.216.0/22
+103.223.220.0/22
+103.223.224.0/22
+103.223.228.0/22
+103.223.232.0/22
+103.223.236.0/22
+103.223.240.0/22
+103.223.244.0/22
+103.223.248.0/22
+103.223.252.0/22
+103.224.0.0/22
+103.224.40.0/22
+103.224.44.0/22
+103.224.60.0/22
+103.224.80.0/22
+103.224.220.0/22
+103.224.224.0/22
+103.224.228.0/22
+103.224.232.0/22
+103.225.84.0/22
+103.226.16.0/22
+103.226.40.0/22
+103.226.56.0/22
+103.226.60.0/22
+103.226.80.0/22
+103.226.132.0/22
+103.226.156.0/22
+103.226.180.0/22
+103.226.196.0/22
+103.227.48.0/22
+103.227.72.0/22
+103.227.76.0/22
+103.227.80.0/22
+103.227.100.0/22
+103.227.120.0/22
+103.227.132.0/22
+103.227.136.0/22
+103.227.196.0/22
+103.227.204.0/22
+103.227.212.0/22
+103.227.228.0/22
+103.228.12.0/22
+103.228.28.0/22
+103.228.68.0/22
+103.228.88.0/22
+103.228.128.0/22
+103.228.136.0/22
+103.228.160.0/22
+103.228.176.0/22
+103.228.204.0/22
+103.228.208.0/22
+103.228.228.0/22
+103.228.232.0/22
+103.229.20.0/22
+103.229.60.0/22
+103.229.136.0/22
+103.229.148.0/22
+103.229.172.0/22
+103.229.212.0/22
+103.229.216.0/22
+103.229.220.0/22
+103.229.228.0/22
+103.229.236.0/22
+103.229.240.0/22
+103.230.0.0/22
+103.230.28.0/22
+103.230.44.0/22
+103.230.96.0/22
+103.230.196.0/22
+103.230.200.0/22
+103.230.204.0/22
+103.230.212.0/22
+103.230.236.0/22
+103.231.16.0/22
+103.231.20.0/22
+103.231.64.0/22
+103.231.68.0/22
+103.231.144.0/22
+103.231.180.0/22
+103.231.184.0/22
+103.231.244.0/22
+103.232.4.0/22
+103.232.144.0/22
+103.232.188.0/22
+103.232.212.0/22
+103.233.4.0/22
+103.233.44.0/22
+103.233.52.0/22
+103.233.104.0/22
+103.233.128.0/22
+103.233.136.0/22
+103.233.228.0/22
+103.234.0.0/22
+103.234.20.0/22
+103.234.56.0/22
+103.234.128.0/22
+103.234.172.0/22
+103.234.180.0/22
+103.234.244.0/22
+103.235.16.0/22
+103.235.48.0/22
+103.235.56.0/22
+103.235.60.0/22
+103.235.80.0/22
+103.235.84.0/22
+103.235.128.0/22
+103.235.132.0/22
+103.235.136.0/22
+103.235.140.0/22
+103.235.144.0/22
+103.235.148.0/22
+103.235.184.0/22
+103.235.192.0/22
+103.235.200.0/22
+103.235.220.0/22
+103.235.224.0/22
+103.235.228.0/22
+103.235.232.0/22
+103.235.236.0/22
+103.235.240.0/22
+103.235.244.0/22
+103.235.248.0/22
+103.235.252.0/22
+103.236.0.0/22
+103.236.4.0/22
+103.236.8.0/22
+103.236.12.0/22
+103.236.16.0/22
+103.236.20.0/22
+103.236.24.0/22
+103.236.28.0/22
+103.236.32.0/22
+103.236.36.0/22
+103.236.40.0/22
+103.236.44.0/22
+103.236.48.0/22
+103.236.52.0/22
+103.236.56.0/22
+103.236.60.0/22
+103.236.64.0/22
+103.236.68.0/22
+103.236.72.0/22
+103.236.76.0/22
+103.236.80.0/22
+103.236.84.0/22
+103.236.88.0/22
+103.236.92.0/22
+103.236.96.0/22
+103.236.120.0/22
+103.236.184.0/22
+103.236.220.0/22
+103.236.232.0/22
+103.236.240.0/22
+103.236.244.0/22
+103.236.248.0/22
+103.236.252.0/22
+103.237.0.0/22
+103.237.4.0/22
+103.237.8.0/22
+103.237.12.0/22
+103.237.24.0/22
+103.237.28.0/22
+103.237.68.0/22
+103.237.88.0/22
+103.237.152.0/22
+103.237.176.0/22
+103.237.180.0/22
+103.237.184.0/22
+103.237.188.0/22
+103.237.192.0/22
+103.237.196.0/22
+103.237.200.0/22
+103.237.204.0/22
+103.237.208.0/22
+103.237.212.0/22
+103.237.216.0/22
+103.237.220.0/22
+103.237.224.0/22
+103.237.228.0/22
+103.237.232.0/22
+103.237.236.0/22
+103.237.240.0/22
+103.237.244.0/22
+103.237.248.0/22
+103.237.252.0/22
+103.238.0.0/22
+103.238.4.0/22
+103.238.16.0/22
+103.238.20.0/22
+103.238.24.0/22
+103.238.28.0/22
+103.238.32.0/22
+103.238.36.0/22
+103.238.40.0/22
+103.238.44.0/22
+103.238.48.0/22
+103.238.52.0/22
+103.238.56.0/22
+103.238.88.0/22
+103.238.92.0/22
+103.238.96.0/22
+103.238.132.0/22
+103.238.140.0/22
+103.238.144.0/22
+103.238.160.0/22
+103.238.164.0/22
+103.238.168.0/22
+103.238.172.0/22
+103.238.176.0/22
+103.238.180.0/22
+103.238.184.0/22
+103.238.188.0/22
+103.238.196.0/22
+103.238.204.0/22
+103.238.252.0/22
+103.239.0.0/22
+103.239.44.0/22
+103.239.68.0/22
+103.239.96.0/22
+103.239.152.0/22
+103.239.156.0/22
+103.239.176.0/22
+103.239.180.0/22
+103.239.184.0/22
+103.239.192.0/22
+103.239.196.0/22
+103.239.204.0/22
+103.239.208.0/22
+103.239.224.0/22
+103.239.244.0/22
+103.240.16.0/22
+103.240.36.0/22
+103.240.72.0/22
+103.240.84.0/22
+103.240.124.0/22
+103.240.156.0/22
+103.240.172.0/22
+103.240.188.0/22
+103.240.244.0/22
+103.241.12.0/22
+103.241.72.0/22
+103.241.92.0/22
+103.241.96.0/22
+103.241.160.0/22
+103.241.184.0/22
+103.241.188.0/22
+103.241.220.0/22
+103.242.64.0/22
+103.242.128.0/22
+103.242.132.0/22
+103.242.160.0/22
+103.242.168.0/22
+103.242.172.0/22
+103.242.176.0/22
+103.242.200.0/22
+103.242.212.0/22
+103.242.220.0/22
+103.242.240.0/22
+103.243.136.0/22
+103.243.252.0/22
+103.244.16.0/22
+103.244.58.0/23
+103.244.60.0/22
+103.244.64.0/22
+103.244.68.0/22
+103.244.72.0/22
+103.244.76.0/22
+103.244.80.0/22
+103.244.84.0/22
+103.244.116.0/22
+103.244.164.0/22
+103.244.232.0/22
+103.244.252.0/22
+103.245.23.0/24
+103.245.52.0/22
+103.245.60.0/22
+103.245.80.0/22
+103.245.124.0/22
+103.245.128.0/22
+103.246.8.0/22
+103.246.12.0/22
+103.246.120.0/22
+103.246.124.0/22
+103.246.132.0/22
+103.246.152.0/22
+103.246.156.0/22
+103.247.168.0/22
+103.247.172.0/22
+103.247.176.0/22
+103.247.200.0/22
+103.247.212.0/22
+103.248.0.0/23
+103.248.64.0/22
+103.248.100.0/22
+103.248.124.0/22
+103.248.152.0/22
+103.248.168.0/22
+103.248.192.0/22
+103.248.212.0/22
+103.248.220.0/22
+103.248.224.0/22
+103.249.8.0/22
+103.249.12.0/22
+103.249.52.0/22
+103.249.104.0/22
+103.249.128.0/22
+103.249.136.0/22
+103.249.144.0/22
+103.249.164.0/22
+103.249.168.0/22
+103.249.172.0/22
+103.249.176.0/22
+103.249.188.0/22
+103.249.192.0/22
+103.249.244.0/22
+103.249.252.0/22
+103.250.32.0/22
+103.250.104.0/22
+103.250.124.0/22
+103.250.180.0/22
+103.250.192.0/22
+103.250.216.0/22
+103.250.224.0/22
+103.250.236.0/22
+103.250.248.0/22
+103.250.252.0/22
+103.251.32.0/22
+103.251.36.0/22
+103.251.84.0/22
+103.251.96.0/22
+103.251.124.0/22
+103.251.128.0/22
+103.251.160.0/22
+103.251.192.0/22
+103.251.204.0/22
+103.251.236.0/22
+103.251.240.0/22
+103.252.28.0/22
+103.252.36.0/22
+103.252.64.0/22
+103.252.96.0/22
+103.252.104.0/22
+103.252.172.0/22
+103.252.204.0/22
+103.252.208.0/22
+103.252.232.0/22
+103.252.248.0/22
+103.253.4.0/22
+103.253.60.0/22
+103.253.204.0/22
+103.253.220.0/22
+103.253.224.0/22
+103.253.232.0/22
+103.254.8.0/22
+103.254.20.0/22
+103.254.64.0/22
+103.254.68.0/22
+103.254.72.0/22
+103.254.76.0/22
+103.254.112.0/22
+103.254.176.0/22
+103.254.188.0/22
+103.254.196.0/24
+103.254.220.0/22
+103.255.56.0/22
+103.255.68.0/22
+103.255.88.0/22
+103.255.92.0/22
+103.255.136.0/22
+103.255.140.0/22
+103.255.184.0/22
+103.255.200.0/22
+103.255.212.0/22
+103.255.228.0/22
+106.0.0.0/24
+106.0.2.0/23
+106.0.4.0/22
+106.0.8.0/21
+106.0.16.0/20
+106.0.44.0/22
+106.0.64.0/18
+106.2.0.0/15
+106.4.0.0/14
+106.8.0.0/15
+106.11.0.0/16
+106.12.0.0/15
+106.14.0.0/15
+106.16.0.0/12
+106.32.0.0/12
+106.48.0.0/15
+106.50.0.0/16
+106.52.0.0/14
+106.56.0.0/13
+106.74.0.0/16
+106.75.0.0/16
+106.80.0.0/12
+106.108.0.0/14
+106.112.0.0/13
+106.120.0.0/13
+106.224.0.0/12
+109.244.0.0/16
+110.6.0.0/15
+110.16.0.0/14
+110.34.40.0/22
+110.34.44.0/22
+110.40.0.0/14
+110.44.12.0/22
+110.44.144.0/20
+110.48.0.0/16
+110.51.0.0/16
+110.52.0.0/15
+110.56.0.0/13
+110.64.0.0/15
+110.72.0.0/15
+110.75.0.0/17
+110.75.128.0/19
+110.75.160.0/19
+110.75.192.0/18
+110.76.0.0/19
+110.76.32.0/19
+110.76.132.0/22
+110.76.156.0/22
+110.76.184.0/22
+110.76.192.0/18
+110.77.0.0/17
+110.80.0.0/13
+110.88.0.0/14
+110.92.68.0/22
+110.93.32.0/19
+110.94.0.0/15
+110.96.0.0/11
+110.152.0.0/14
+110.156.0.0/15
+110.165.32.0/19
+110.166.0.0/15
+110.172.192.0/18
+110.173.0.0/19
+110.173.32.0/20
+110.173.64.0/19
+110.173.96.0/19
+110.173.192.0/19
+110.176.0.0/13
+110.184.0.0/13
+110.192.0.0/11
+110.228.0.0/14
+110.232.32.0/19
+110.236.0.0/15
+110.240.0.0/12
+111.0.0.0/10
+111.66.0.0/16
+111.67.192.0/20
+111.68.64.0/19
+111.72.0.0/13
+111.85.0.0/16
+111.91.192.0/19
+111.92.248.0/22
+111.92.252.0/22
+111.112.0.0/15
+111.114.0.0/15
+111.116.0.0/15
+111.118.200.0/21
+111.119.64.0/18
+111.119.128.0/19
+111.120.0.0/14
+111.124.0.0/16
+111.126.0.0/15
+111.128.0.0/11
+111.160.0.0/13
+111.170.0.0/16
+111.172.0.0/14
+111.176.0.0/13
+111.186.0.0/15
+111.192.0.0/12
+111.208.0.0/14
+111.212.0.0/14
+111.221.28.0/24
+111.221.128.0/17
+111.222.0.0/16
+111.223.4.0/22
+111.223.8.0/22
+111.223.12.0/22
+111.223.16.0/22
+111.223.240.0/22
+111.223.248.0/22
+111.224.0.0/14
+111.228.0.0/14
+111.235.96.0/19
+111.235.156.0/22
+111.235.160.0/19
+112.0.0.0/10
+112.64.0.0/15
+112.66.0.0/15
+112.73.0.0/16
+112.74.0.0/15
+112.80.0.0/13
+112.88.0.0/13
+112.96.0.0/15
+112.98.0.0/15
+112.100.0.0/14
+112.109.128.0/17
+112.111.0.0/16
+112.112.0.0/14
+112.116.0.0/15
+112.122.0.0/15
+112.124.0.0/14
+112.128.0.0/14
+112.132.0.0/16
+112.137.48.0/21
+112.192.0.0/14
+112.224.0.0/11
+113.0.0.0/13
+113.8.0.0/15
+113.11.192.0/19
+113.12.0.0/14
+113.16.0.0/15
+113.18.0.0/16
+113.21.232.0/22
+113.21.236.0/22
+113.24.0.0/14
+113.31.0.0/16
+113.44.0.0/14
+113.48.0.0/14
+113.52.160.0/19
+113.52.228.0/22
+113.54.0.0/15
+113.56.0.0/15
+113.58.0.0/16
+113.59.0.0/17
+113.59.224.0/22
+113.62.0.0/15
+113.64.0.0/11
+113.96.0.0/12
+113.112.0.0/13
+113.120.0.0/13
+113.128.0.0/15
+113.130.96.0/20
+113.130.112.0/21
+113.132.0.0/14
+113.136.0.0/13
+113.194.0.0/15
+113.197.100.0/22
+113.200.0.0/15
+113.202.0.0/16
+113.204.0.0/14
+113.208.96.0/19
+113.208.128.0/17
+113.209.0.0/16
+113.212.0.0/18
+113.212.64.0/22
+113.212.88.0/22
+113.212.100.0/22
+113.212.184.0/21
+113.213.0.0/17
+113.214.0.0/15
+113.218.0.0/15
+113.220.0.0/14
+113.224.0.0/12
+113.240.0.0/13
+113.248.0.0/14
+114.28.0.0/16
+114.31.64.0/22
+114.31.68.0/22
+114.54.0.0/15
+114.60.0.0/14
+114.64.0.0/14
+114.68.0.0/16
+114.79.64.0/18
+114.80.0.0/12
+114.96.0.0/13
+114.104.0.0/14
+114.110.0.0/20
+114.110.64.0/18
+114.111.0.0/19
+114.111.160.0/19
+114.112.0.0/14
+114.116.0.0/16
+114.117.0.0/16
+114.118.0.0/16
+114.119.0.0/17
+114.119.192.0/21
+114.119.200.0/22
+114.119.204.0/22
+114.119.208.0/20
+114.119.224.0/19
+114.132.0.0/16
+114.135.0.0/16
+114.138.0.0/15
+114.141.64.0/21
+114.141.80.0/22
+114.141.84.0/22
+114.141.128.0/18
+114.196.0.0/15
+114.198.248.0/21
+114.208.0.0/14
+114.212.0.0/15
+114.214.0.0/16
+114.215.0.0/16
+114.216.0.0/13
+114.224.0.0/12
+114.240.0.0/12
+115.24.0.0/14
+115.28.0.0/15
+115.31.64.0/22
+115.31.68.0/22
+115.31.72.0/22
+115.31.76.0/22
+115.32.0.0/14
+115.42.56.0/22
+115.44.0.0/15
+115.46.0.0/16
+115.47.0.0/16
+115.48.0.0/12
+115.69.64.0/20
+115.84.0.0/18
+115.84.192.0/19
+115.85.192.0/18
+115.100.0.0/14
+115.104.0.0/14
+115.120.0.0/14
+115.124.16.0/20
+115.148.0.0/14
+115.152.0.0/15
+115.154.0.0/15
+115.156.0.0/15
+115.158.0.0/16
+115.159.0.0/16
+115.166.64.0/19
+115.168.0.0/14
+115.172.0.0/14
+115.180.0.0/15
+115.182.0.0/16
+115.183.0.0/16
+115.187.0.0/22
+115.187.4.0/22
+115.187.8.0/22
+115.187.12.0/22
+115.190.0.0/15
+115.192.0.0/11
+115.224.0.0/12
+116.0.8.0/21
+116.0.24.0/21
+116.1.0.0/16
+116.2.0.0/15
+116.4.0.0/14
+116.8.0.0/14
+116.13.0.0/16
+116.16.0.0/12
+116.50.0.0/20
+116.52.0.0/14
+116.56.0.0/15
+116.58.128.0/20
+116.58.208.0/20
+116.60.0.0/14
+116.66.0.0/17
+116.66.176.0/22
+116.68.136.0/22
+116.68.140.0/22
+116.68.176.0/22
+116.68.180.0/22
+116.69.0.0/16
+116.70.0.0/17
+116.76.0.0/15
+116.78.0.0/15
+116.85.0.0/16
+116.89.144.0/20
+116.89.240.0/22
+116.90.80.0/20
+116.90.184.0/21
+116.95.0.0/16
+116.112.0.0/14
+116.116.0.0/15
+116.128.0.0/10
+116.192.0.0/16
+116.193.16.0/20
+116.193.32.0/19
+116.193.152.0/22
+116.193.164.0/22
+116.193.176.0/21
+116.194.0.0/15
+116.196.0.0/16
+116.197.160.0/22
+116.197.164.0/22
+116.198.0.0/16
+116.199.0.0/17
+116.199.128.0/19
+116.204.0.0/17
+116.204.132.0/22
+116.204.168.0/22
+116.204.216.0/22
+116.204.232.0/22
+116.204.236.0/22
+116.204.244.0/22
+116.205.0.0/16
+116.206.92.0/22
+116.206.176.0/22
+116.207.0.0/16
+116.208.0.0/14
+116.212.160.0/20
+116.213.44.0/22
+116.213.64.0/18
+116.213.128.0/17
+116.214.32.0/19
+116.214.64.0/20
+116.214.128.0/17
+116.215.0.0/16
+116.216.0.0/14
+116.224.0.0/12
+116.242.0.0/15
+116.244.0.0/15
+116.246.0.0/15
+116.248.0.0/15
+116.251.64.0/18
+116.252.0.0/15
+116.254.104.0/22
+116.254.108.0/22
+116.254.128.0/17
+116.255.128.0/17
+117.8.0.0/13
+117.21.0.0/16
+117.22.0.0/15
+117.24.0.0/13
+117.32.0.0/13
+117.40.0.0/14
+117.44.0.0/15
+117.48.0.0/17
+117.48.128.0/17
+117.49.0.0/16
+117.50.0.0/15
+117.53.48.0/20
+117.53.176.0/20
+117.57.0.0/16
+117.58.0.0/17
+117.59.0.0/16
+117.60.0.0/14
+117.64.0.0/13
+117.72.0.0/15
+117.74.64.0/20
+117.74.80.0/20
+117.74.128.0/17
+117.75.0.0/16
+117.76.0.0/14
+117.80.0.0/12
+117.100.0.0/15
+117.103.16.0/20
+117.103.40.0/21
+117.103.72.0/21
+117.103.128.0/20
+117.104.168.0/21
+117.106.0.0/15
+117.112.0.0/13
+117.120.64.0/18
+117.120.128.0/17
+117.121.0.0/17
+117.121.128.0/18
+117.121.192.0/21
+117.122.128.0/17
+117.124.0.0/14
+117.128.0.0/10
+118.24.0.0/15
+118.26.0.0/19
+118.26.32.0/22
+118.26.36.0/22
+118.26.40.0/21
+118.26.48.0/21
+118.26.56.0/21
+118.26.64.0/19
+118.26.96.0/21
+118.26.104.0/21
+118.26.112.0/21
+118.26.120.0/21
+118.26.128.0/17
+118.28.0.0/15
+118.30.0.0/16
+118.31.0.0/16
+118.64.0.0/15
+118.66.0.0/16
+118.67.112.0/20
+118.72.0.0/13
+118.80.0.0/15
+118.84.0.0/15
+118.88.32.0/19
+118.88.64.0/18
+118.88.128.0/17
+118.89.0.0/16
+118.91.240.0/20
+118.102.16.0/20
+118.102.32.0/21
+118.103.164.0/22
+118.103.168.0/22
+118.103.172.0/22
+118.103.176.0/22
+118.107.180.0/22
+118.112.0.0/13
+118.120.0.0/14
+118.124.0.0/15
+118.126.0.0/16
+118.127.128.0/19
+118.132.0.0/14
+118.144.0.0/14
+118.178.0.0/16
+118.180.0.0/14
+118.184.0.0/17
+118.184.128.0/17
+118.186.0.0/15
+118.188.0.0/16
+118.190.0.0/16
+118.191.0.0/21
+118.191.8.0/22
+118.191.12.0/24
+118.191.16.0/21
+118.191.64.0/20
+118.191.80.0/22
+118.191.128.0/19
+118.191.176.0/20
+118.191.192.0/20
+118.191.208.0/24
+118.191.216.0/22
+118.191.223.0/24
+118.191.224.0/24
+118.191.240.0/20
+118.192.0.0/16
+118.193.0.0/21
+118.193.8.0/21
+118.193.32.0/19
+118.193.64.0/20
+118.193.96.0/19
+118.193.128.0/17
+118.194.0.0/17
+118.194.128.0/17
+118.195.0.0/17
+118.195.128.0/17
+118.196.0.0/14
+118.202.0.0/15
+118.204.0.0/14
+118.212.0.0/16
+118.213.0.0/16
+118.215.192.0/18
+118.224.0.0/14
+118.228.0.0/15
+118.230.0.0/16
+118.239.0.0/16
+118.242.0.0/16
+118.244.0.0/14
+118.248.0.0/13
+119.0.0.0/15
+119.2.0.0/19
+119.2.128.0/17
+119.3.0.0/16
+119.4.0.0/14
+119.10.0.0/17
+119.15.136.0/21
+119.16.0.0/16
+119.18.192.0/20
+119.18.208.0/21
+119.18.224.0/20
+119.18.240.0/20
+119.19.0.0/16
+119.20.0.0/14
+119.27.64.0/18
+119.27.128.0/19
+119.27.160.0/19
+119.27.192.0/18
+119.28.0.0/15
+119.30.48.0/20
+119.31.192.0/19
+119.32.0.0/14
+119.36.0.0/16
+119.37.0.0/17
+119.37.128.0/18
+119.37.192.0/18
+119.38.0.0/17
+119.38.128.0/18
+119.38.192.0/20
+119.38.208.0/20
+119.38.224.0/19
+119.39.0.0/16
+119.40.0.0/18
+119.40.64.0/20
+119.40.128.0/17
+119.41.0.0/16
+119.42.0.0/19
+119.42.52.0/22
+119.42.128.0/21
+119.42.136.0/21
+119.42.224.0/19
+119.44.0.0/15
+119.48.0.0/13
+119.57.0.0/16
+119.58.0.0/16
+119.59.128.0/17
+119.60.0.0/16
+119.61.0.0/16
+119.62.0.0/16
+119.63.32.0/19
+119.75.208.0/20
+119.78.0.0/15
+119.80.0.0/16
+119.82.208.0/20
+119.84.0.0/14
+119.88.0.0/14
+119.96.0.0/13
+119.108.0.0/15
+119.112.0.0/13
+119.120.0.0/13
+119.128.0.0/12
+119.144.0.0/14
+119.148.160.0/20
+119.148.176.0/20
+119.151.192.0/18
+119.160.200.0/21
+119.161.120.0/22
+119.161.124.0/22
+119.161.128.0/17
+119.162.0.0/15
+119.164.0.0/14
+119.176.0.0/12
+119.232.0.0/15
+119.235.128.0/18
+119.248.0.0/14
+119.252.96.0/21
+119.252.240.0/20
+119.253.0.0/16
+119.254.0.0/15
+120.0.0.0/12
+120.24.0.0/14
+120.30.0.0/16
+120.31.0.0/16
+120.32.0.0/13
+120.40.0.0/14
+120.44.0.0/14
+120.48.0.0/15
+120.52.0.0/16
+120.53.0.0/16
+120.54.0.0/15
+120.64.0.0/14
+120.68.0.0/14
+120.72.32.0/19
+120.72.128.0/17
+120.76.0.0/14
+120.80.0.0/13
+120.88.8.0/21
+120.90.0.0/15
+120.92.0.0/16
+120.94.0.0/16
+120.95.0.0/16
+120.128.0.0/14
+120.132.0.0/17
+120.132.128.0/17
+120.133.0.0/16
+120.134.0.0/15
+120.136.16.0/22
+120.136.20.0/22
+120.136.128.0/18
+120.137.0.0/17
+120.143.128.0/19
+120.192.0.0/10
+121.0.8.0/21
+121.0.16.0/20
+121.4.0.0/15
+121.8.0.0/13
+121.16.0.0/13
+121.24.0.0/14
+121.28.0.0/15
+121.30.0.0/16
+121.31.0.0/16
+121.32.0.0/14
+121.36.0.0/16
+121.37.0.0/16
+121.38.0.0/15
+121.40.0.0/14
+121.46.0.0/18
+121.46.76.0/22
+121.46.128.0/17
+121.47.0.0/16
+121.48.0.0/15
+121.50.8.0/21
+121.51.0.0/16
+121.52.160.0/19
+121.52.208.0/20
+121.52.224.0/19
+121.54.176.0/21
+121.54.188.0/22
+121.55.0.0/18
+121.56.0.0/15
+121.58.0.0/17
+121.58.136.0/21
+121.58.144.0/20
+121.58.160.0/21
+121.59.0.0/16
+121.60.0.0/14
+121.68.0.0/14
+121.76.0.0/15
+121.79.128.0/18
+121.89.0.0/16
+121.100.128.0/17
+121.101.0.0/18
+121.101.208.0/20
+121.192.0.0/16
+121.193.0.0/16
+121.194.0.0/15
+121.196.0.0/14
+121.200.192.0/21
+121.201.0.0/16
+121.204.0.0/14
+121.224.0.0/12
+121.248.0.0/14
+121.255.0.0/16
+122.0.64.0/18
+122.0.128.0/17
+122.4.0.0/14
+122.8.0.0/16
+122.9.0.0/16
+122.10.128.0/22
+122.10.132.0/23
+122.10.136.0/23
+122.10.164.0/22
+122.10.168.0/21
+122.10.176.0/20
+122.10.192.0/22
+122.10.200.0/21
+122.10.208.0/21
+122.10.216.0/22
+122.10.228.0/22
+122.10.232.0/21
+122.10.240.0/22
+122.11.0.0/17
+122.12.0.0/16
+122.13.0.0/16
+122.14.0.0/17
+122.14.128.0/18
+122.14.192.0/18
+122.48.0.0/16
+122.49.0.0/18
+122.51.0.0/16
+122.64.0.0/11
+122.96.0.0/15
+122.102.0.0/20
+122.102.64.0/20
+122.102.80.0/20
+122.112.0.0/18
+122.112.64.0/18
+122.112.128.0/17
+122.113.0.0/16
+122.114.0.0/16
+122.115.0.0/17
+122.115.128.0/19
+122.115.160.0/19
+122.115.192.0/19
+122.115.224.0/19
+122.119.0.0/16
+122.128.100.0/22
+122.128.120.0/21
+122.136.0.0/13
+122.144.128.0/17
+122.152.192.0/18
+122.156.0.0/14
+122.188.0.0/14
+122.192.0.0/14
+122.198.0.0/16
+122.200.40.0/22
+122.200.44.0/22
+122.200.64.0/18
+122.201.48.0/20
+122.204.0.0/14
+122.224.0.0/12
+122.240.0.0/13
+122.248.24.0/21
+122.248.48.0/20
+122.255.64.0/21
+123.0.128.0/18
+123.4.0.0/14
+123.8.0.0/13
+123.49.128.0/17
+123.50.160.0/19
+123.52.0.0/14
+123.56.0.0/15
+123.58.0.0/20
+123.58.16.0/20
+123.58.32.0/19
+123.58.64.0/19
+123.58.96.0/19
+123.58.128.0/18
+123.58.192.0/19
+123.58.224.0/20
+123.58.240.0/20
+123.59.0.0/16
+123.60.0.0/16
+123.61.0.0/16
+123.62.0.0/16
+123.64.0.0/11
+123.96.0.0/15
+123.98.0.0/17
+123.99.128.0/17
+123.100.0.0/19
+123.101.0.0/16
+123.103.0.0/17
+123.108.128.0/20
+123.108.208.0/20
+123.112.0.0/12
+123.128.0.0/13
+123.136.80.0/20
+123.137.0.0/16
+123.138.0.0/15
+123.144.0.0/14
+123.148.0.0/16
+123.149.0.0/16
+123.150.0.0/15
+123.152.0.0/13
+123.160.0.0/14
+123.164.0.0/14
+123.168.0.0/14
+123.172.0.0/15
+123.174.0.0/15
+123.176.60.0/22
+123.176.80.0/20
+123.177.0.0/16
+123.178.0.0/15
+123.180.0.0/14
+123.184.0.0/14
+123.188.0.0/14
+123.196.0.0/15
+123.199.128.0/17
+123.206.0.0/15
+123.232.0.0/14
+123.242.0.0/17
+123.242.192.0/22
+123.242.196.0/22
+123.244.0.0/14
+123.249.0.0/16
+123.253.108.0/22
+123.253.240.0/22
+123.254.96.0/22
+123.254.100.0/22
+124.6.64.0/18
+124.14.0.0/15
+124.16.0.0/15
+124.20.0.0/16
+124.21.0.0/20
+124.21.16.0/20
+124.21.32.0/19
+124.21.64.0/18
+124.21.128.0/17
+124.22.0.0/15
+124.28.192.0/18
+124.29.0.0/17
+124.31.0.0/16
+124.40.112.0/20
+124.40.128.0/18
+124.40.192.0/19
+124.40.240.0/22
+124.42.0.0/17
+124.42.128.0/17
+124.47.0.0/18
+124.64.0.0/15
+124.66.0.0/17
+124.67.0.0/16
+124.68.0.0/14
+124.72.0.0/16
+124.73.0.0/16
+124.74.0.0/15
+124.76.0.0/14
+124.88.0.0/16
+124.89.0.0/17
+124.89.128.0/17
+124.90.0.0/15
+124.92.0.0/14
+124.108.8.0/21
+124.108.40.0/21
+124.109.96.0/21
+124.112.0.0/15
+124.114.0.0/15
+124.116.0.0/16
+124.117.0.0/16
+124.118.0.0/15
+124.126.0.0/15
+124.128.0.0/13
+124.147.128.0/17
+124.150.137.0/24
+124.151.0.0/16
+124.152.0.0/16
+124.160.0.0/16
+124.161.0.0/16
+124.162.0.0/16
+124.163.0.0/16
+124.164.0.0/14
+124.172.0.0/15
+124.174.0.0/15
+124.192.0.0/15
+124.196.0.0/16
+124.200.0.0/13
+124.220.0.0/14
+124.224.0.0/16
+124.225.0.0/16
+124.226.0.0/15
+124.228.0.0/14
+124.232.0.0/15
+124.234.0.0/15
+124.236.0.0/14
+124.240.0.0/17
+124.240.128.0/18
+124.242.0.0/16
+124.243.192.0/18
+124.248.0.0/17
+124.249.0.0/16
+124.250.0.0/15
+124.254.0.0/18
+125.31.192.0/18
+125.32.0.0/16
+125.33.0.0/16
+125.34.0.0/16
+125.35.0.0/17
+125.35.128.0/17
+125.36.0.0/14
+125.40.0.0/13
+125.58.128.0/17
+125.61.128.0/17
+125.62.0.0/18
+125.64.0.0/13
+125.72.0.0/16
+125.73.0.0/16
+125.74.0.0/15
+125.76.0.0/17
+125.76.128.0/17
+125.77.0.0/16
+125.78.0.0/15
+125.80.0.0/13
+125.88.0.0/13
+125.96.0.0/15
+125.98.0.0/16
+125.104.0.0/13
+125.112.0.0/12
+125.169.0.0/16
+125.171.0.0/16
+125.208.0.0/18
+125.210.0.0/16
+125.211.0.0/16
+125.213.0.0/17
+125.214.96.0/19
+125.215.0.0/18
+125.216.0.0/15
+125.218.0.0/16
+125.219.0.0/16
+125.220.0.0/15
+125.222.0.0/15
+125.254.128.0/18
+125.254.192.0/18
+128.108.0.0/16
+129.28.0.0/16
+129.204.0.0/16
+129.211.0.0/16
+132.232.0.0/16
+134.175.0.0/16
+137.59.59.0/24
+137.59.88.0/22
+139.5.56.0/22
+139.5.60.0/22
+139.5.80.0/22
+139.5.92.0/22
+139.5.108.0/22
+139.5.128.0/22
+139.5.160.0/22
+139.5.192.0/22
+139.5.204.0/22
+139.5.208.0/22
+139.5.212.0/22
+139.5.244.0/22
+139.9.0.0/16
+139.129.0.0/16
+139.148.0.0/16
+139.155.0.0/16
+139.159.0.0/16
+139.170.0.0/16
+139.176.0.0/16
+139.183.0.0/16
+139.186.0.0/16
+139.189.0.0/16
+139.196.0.0/14
+139.200.0.0/13
+139.208.0.0/13
+139.217.0.0/16
+139.219.0.0/16
+139.220.0.0/15
+139.224.0.0/16
+139.226.0.0/15
+140.75.0.0/16
+140.143.0.0/16
+140.179.0.0/16
+140.205.0.0/16
+140.206.0.0/15
+140.210.0.0/16
+140.224.0.0/16
+140.237.0.0/16
+140.240.0.0/16
+140.243.0.0/16
+140.246.0.0/16
+140.249.0.0/16
+140.250.0.0/16
+140.255.0.0/16
+144.0.0.0/16
+144.7.0.0/16
+144.12.0.0/16
+144.48.8.0/22
+144.48.64.0/22
+144.48.88.0/22
+144.48.156.0/22
+144.48.180.0/22
+144.48.184.0/22
+144.48.204.0/22
+144.48.208.0/22
+144.48.212.0/22
+144.48.220.0/22
+144.48.252.0/22
+144.52.0.0/16
+144.123.0.0/16
+144.255.0.0/16
+146.56.192.0/18
+146.196.56.0/22
+146.196.68.0/22
+146.196.72.0/22
+146.196.92.0/22
+146.196.112.0/22
+146.196.116.0/22
+146.196.124.0/22
+148.70.0.0/16
+150.0.0.0/16
+150.115.0.0/16
+150.121.0.0/16
+150.122.0.0/16
+150.129.136.0/22
+150.129.192.0/22
+150.129.216.0/22
+150.129.252.0/22
+150.138.0.0/15
+150.158.0.0/16
+150.223.0.0/16
+150.242.0.0/22
+150.242.4.0/22
+150.242.8.0/22
+150.242.28.0/22
+150.242.44.0/22
+150.242.48.0/22
+150.242.52.0/22
+150.242.56.0/22
+150.242.76.0/22
+150.242.80.0/22
+150.242.92.0/22
+150.242.96.0/22
+150.242.112.0/22
+150.242.116.0/22
+150.242.120.0/22
+150.242.152.0/22
+150.242.156.0/22
+150.242.160.0/22
+150.242.164.0/22
+150.242.168.0/22
+150.242.184.0/22
+150.242.188.0/22
+150.242.192.0/22
+150.242.212.0/22
+150.242.224.0/22
+150.242.228.0/22
+150.242.232.0/22
+150.242.236.0/22
+150.242.240.0/22
+150.242.244.0/22
+150.242.248.0/22
+150.255.0.0/16
+152.104.128.0/17
+152.136.0.0/16
+153.0.0.0/16
+153.3.0.0/16
+153.34.0.0/15
+153.36.0.0/15
+153.99.0.0/16
+153.101.0.0/16
+153.118.0.0/15
+154.8.128.0/17
+157.0.0.0/16
+157.18.0.0/16
+157.61.0.0/16
+157.119.0.0/22
+157.119.8.0/22
+157.119.12.0/22
+157.119.16.0/22
+157.119.28.0/22
+157.119.68.0/22
+157.119.112.0/22
+157.119.132.0/22
+157.119.136.0/22
+157.119.140.0/22
+157.119.144.0/22
+157.119.148.0/22
+157.119.152.0/22
+157.119.156.0/22
+157.119.160.0/22
+157.119.164.0/22
+157.119.172.0/22
+157.119.192.0/22
+157.119.196.0/22
+157.119.240.0/22
+157.119.252.0/22
+157.122.0.0/16
+157.148.0.0/16
+157.156.0.0/16
+157.255.0.0/16
+159.75.0.0/16
+159.226.0.0/16
+160.19.208.0/22
+160.19.212.0/22
+160.19.216.0/22
+160.20.48.0/22
+160.202.60.0/22
+160.202.148.0/22
+160.202.152.0/22
+160.202.168.0/22
+160.202.212.0/22
+160.202.216.0/22
+160.202.220.0/22
+160.202.224.0/22
+160.202.228.0/22
+160.202.232.0/22
+160.202.236.0/22
+160.202.240.0/22
+160.202.244.0/22
+160.202.248.0/22
+160.202.252.0/22
+160.238.64.0/22
+161.189.0.0/16
+161.207.0.0/16
+162.14.0.0/16
+162.105.0.0/16
+163.0.0.0/16
+163.47.4.0/22
+163.53.0.0/22
+163.53.4.0/22
+163.53.8.0/22
+163.53.12.0/22
+163.53.36.0/22
+163.53.40.0/22
+163.53.44.0/22
+163.53.48.0/22
+163.53.52.0/22
+163.53.56.0/22
+163.53.60.0/22
+163.53.64.0/22
+163.53.88.0/22
+163.53.92.0/22
+163.53.96.0/22
+163.53.100.0/22
+163.53.104.0/22
+163.53.108.0/22
+163.53.112.0/22
+163.53.116.0/22
+163.53.120.0/22
+163.53.124.0/22
+163.53.128.0/22
+163.53.132.0/22
+163.53.136.0/22
+163.53.160.0/22
+163.53.164.0/22
+163.53.168.0/22
+163.53.172.0/22
+163.53.188.0/22
+163.53.220.0/22
+163.53.240.0/22
+163.125.0.0/16
+163.142.0.0/16
+163.177.0.0/16
+163.179.0.0/16
+163.204.0.0/16
+164.52.0.0/17
+166.111.0.0/16
+167.139.0.0/16
+167.189.0.0/16
+167.220.244.0/22
+168.160.0.0/16
+170.179.0.0/16
+171.8.0.0/13
+171.34.0.0/15
+171.36.0.0/14
+171.40.0.0/13
+171.80.0.0/14
+171.84.0.0/14
+171.88.0.0/13
+171.104.0.0/13
+171.112.0.0/14
+171.116.0.0/14
+171.120.0.0/13
+171.208.0.0/12
+172.81.192.0/18
+175.0.0.0/12
+175.16.0.0/13
+175.24.0.0/14
+175.30.0.0/15
+175.42.0.0/15
+175.44.0.0/16
+175.46.0.0/15
+175.48.0.0/12
+175.64.0.0/11
+175.102.0.0/16
+175.106.128.0/17
+175.111.144.0/22
+175.111.148.0/22
+175.111.152.0/22
+175.111.156.0/22
+175.111.160.0/22
+175.111.164.0/22
+175.111.168.0/22
+175.111.172.0/22
+175.111.184.0/22
+175.146.0.0/15
+175.148.0.0/14
+175.152.0.0/14
+175.158.96.0/22
+175.160.0.0/12
+175.176.156.0/22
+175.176.176.0/22
+175.176.188.0/22
+175.176.192.0/22
+175.178.0.0/16
+175.184.128.0/18
+175.185.0.0/16
+175.186.0.0/15
+175.188.0.0/14
+180.76.0.0/16
+180.77.0.0/16
+180.78.0.0/15
+180.84.0.0/15
+180.86.0.0/16
+180.88.0.0/14
+180.94.56.0/21
+180.94.96.0/20
+180.94.120.0/22
+180.94.124.0/22
+180.95.128.0/17
+180.96.0.0/11
+180.129.128.0/17
+180.130.0.0/16
+180.136.0.0/13
+180.148.16.0/21
+180.148.152.0/21
+180.148.216.0/21
+180.148.224.0/19
+180.149.128.0/19
+180.149.236.0/22
+180.150.160.0/19
+180.152.0.0/13
+180.160.0.0/12
+180.178.112.0/22
+180.178.116.0/22
+180.178.192.0/18
+180.184.0.0/14
+180.188.0.0/17
+180.189.148.0/22
+180.200.252.0/22
+180.201.0.0/16
+180.202.0.0/15
+180.208.0.0/15
+180.210.212.0/22
+180.210.224.0/19
+180.212.0.0/15
+180.222.224.0/19
+180.223.0.0/16
+180.233.0.0/18
+180.233.64.0/19
+180.233.144.0/22
+180.235.64.0/19
+180.235.112.0/22
+180.235.136.0/22
+182.16.144.0/22
+182.16.148.0/22
+182.16.192.0/19
+182.18.0.0/17
+182.23.184.0/21
+182.23.200.0/21
+182.32.0.0/12
+182.48.96.0/19
+182.49.0.0/16
+182.50.0.0/20
+182.50.112.0/20
+182.51.0.0/16
+182.54.0.0/17
+182.54.244.0/22
+182.61.0.0/16
+182.80.0.0/14
+182.84.0.0/14
+182.88.0.0/14
+182.92.0.0/16
+182.96.0.0/12
+182.112.0.0/12
+182.128.0.0/12
+182.144.0.0/13
+182.157.0.0/16
+182.160.64.0/19
+182.174.0.0/15
+182.200.0.0/13
+182.236.128.0/17
+182.237.24.0/22
+182.237.28.0/22
+182.238.0.0/16
+182.239.0.0/19
+182.240.0.0/13
+182.254.0.0/16
+182.255.32.0/22
+182.255.36.0/22
+182.255.60.0/22
+183.0.0.0/10
+183.64.0.0/13
+183.78.160.0/22
+183.78.164.0/22
+183.78.180.0/22
+183.81.172.0/22
+183.81.180.0/22
+183.84.0.0/15
+183.91.128.0/22
+183.91.136.0/21
+183.91.144.0/20
+183.92.0.0/14
+183.128.0.0/11
+183.160.0.0/13
+183.168.0.0/15
+183.170.0.0/16
+183.172.0.0/14
+183.182.0.0/19
+183.184.0.0/13
+183.192.0.0/10
+185.203.36.0/22
+188.131.128.0/17
+192.51.188.0/24
+192.55.46.0/24
+192.55.68.0/22
+192.102.204.0/23
+192.124.154.0/24
+192.140.128.0/22
+192.140.132.0/22
+192.140.136.0/22
+192.140.156.0/22
+192.140.160.0/22
+192.140.164.0/22
+192.140.168.0/22
+192.140.172.0/22
+192.140.176.0/22
+192.140.180.0/22
+192.140.184.0/22
+192.140.188.0/22
+192.140.192.0/22
+192.140.196.0/22
+192.140.200.0/22
+192.140.204.0/22
+192.140.208.0/22
+192.140.212.0/22
+192.144.128.0/17
+192.197.113.0/24
+193.112.0.0/16
+198.175.100.0/22
+199.212.57.0/24
+202.0.100.0/23
+202.0.122.0/23
+202.0.176.0/22
+202.3.128.0/23
+202.3.134.0/24
+202.4.128.0/19
+202.4.252.0/22
+202.5.208.0/22
+202.5.212.0/22
+202.5.216.0/22
+202.6.6.0/23
+202.6.66.0/23
+202.6.72.0/23
+202.6.87.0/24
+202.6.88.0/23
+202.6.92.0/23
+202.6.103.0/24
+202.6.108.0/24
+202.6.110.0/23
+202.6.114.0/24
+202.6.176.0/20
+202.8.0.0/24
+202.8.2.0/23
+202.8.4.0/23
+202.8.12.0/24
+202.8.24.0/24
+202.8.77.0/24
+202.8.120.0/22
+202.8.128.0/19
+202.8.192.0/20
+202.9.32.0/24
+202.9.34.0/23
+202.9.48.0/23
+202.9.51.0/24
+202.9.52.0/23
+202.9.54.0/24
+202.9.57.0/24
+202.9.58.0/23
+202.10.64.0/20
+202.10.112.0/22
+202.10.116.0/22
+202.10.120.0/22
+202.10.124.0/22
+202.12.1.0/24
+202.12.2.0/24
+202.12.17.0/24
+202.12.18.0/24
+202.12.19.0/24
+202.12.72.0/24
+202.12.84.0/23
+202.12.96.0/24
+202.12.98.0/23
+202.12.106.0/24
+202.12.111.0/24
+202.12.116.0/24
+202.14.64.0/23
+202.14.69.0/24
+202.14.73.0/24
+202.14.74.0/23
+202.14.76.0/24
+202.14.78.0/23
+202.14.88.0/24
+202.14.97.0/24
+202.14.104.0/23
+202.14.108.0/23
+202.14.111.0/24
+202.14.114.0/23
+202.14.118.0/23
+202.14.124.0/23
+202.14.127.0/24
+202.14.129.0/24
+202.14.135.0/24
+202.14.136.0/24
+202.14.149.0/24
+202.14.151.0/24
+202.14.157.0/24
+202.14.158.0/23
+202.14.169.0/24
+202.14.170.0/23
+202.14.172.0/22
+202.14.176.0/24
+202.14.184.0/23
+202.14.208.0/23
+202.14.213.0/24
+202.14.219.0/24
+202.14.220.0/24
+202.14.222.0/23
+202.14.225.0/24
+202.14.226.0/23
+202.14.231.0/24
+202.14.235.0/24
+202.14.236.0/23
+202.14.238.0/24
+202.14.239.0/24
+202.14.246.0/24
+202.14.251.0/24
+202.20.66.0/24
+202.20.79.0/24
+202.20.87.0/24
+202.20.88.0/23
+202.20.90.0/24
+202.20.94.0/23
+202.20.114.0/24
+202.20.117.0/24
+202.20.120.0/24
+202.20.125.0/24
+202.20.126.0/24
+202.20.127.0/24
+202.21.48.0/22
+202.21.52.0/22
+202.21.56.0/22
+202.21.60.0/22
+202.21.131.0/24
+202.21.132.0/24
+202.21.141.0/24
+202.21.142.0/24
+202.21.147.0/24
+202.21.148.0/24
+202.21.150.0/23
+202.21.152.0/23
+202.21.154.0/24
+202.21.156.0/24
+202.22.248.0/22
+202.22.252.0/22
+202.27.12.0/24
+202.27.14.0/24
+202.27.136.0/23
+202.36.226.0/24
+202.38.0.0/23
+202.38.2.0/23
+202.38.8.0/21
+202.38.48.0/20
+202.38.64.0/19
+202.38.96.0/19
+202.38.128.0/23
+202.38.130.0/23
+202.38.132.0/23
+202.38.134.0/24
+202.38.135.0/24
+202.38.136.0/23
+202.38.138.0/24
+202.38.140.0/23
+202.38.142.0/23
+202.38.146.0/23
+202.38.149.0/24
+202.38.150.0/23
+202.38.152.0/23
+202.38.154.0/23
+202.38.156.0/24
+202.38.158.0/23
+202.38.160.0/23
+202.38.164.0/22
+202.38.168.0/23
+202.38.170.0/24
+202.38.171.0/24
+202.38.176.0/23
+202.38.184.0/21
+202.38.192.0/18
+202.40.4.0/23
+202.40.7.0/24
+202.40.15.0/24
+202.40.135.0/24
+202.40.136.0/24
+202.40.140.0/24
+202.40.143.0/24
+202.40.144.0/23
+202.40.150.0/24
+202.40.155.0/24
+202.40.156.0/24
+202.40.158.0/23
+202.40.162.0/24
+202.41.8.0/23
+202.41.11.0/24
+202.41.12.0/23
+202.41.128.0/24
+202.41.130.0/23
+202.41.152.0/21
+202.41.192.0/24
+202.41.196.0/22
+202.41.200.0/22
+202.41.240.0/20
+202.43.76.0/22
+202.43.144.0/20
+202.44.16.0/20
+202.44.48.0/22
+202.44.67.0/24
+202.44.74.0/24
+202.44.97.0/24
+202.44.129.0/24
+202.44.132.0/23
+202.44.146.0/23
+202.45.0.0/23
+202.45.2.0/24
+202.45.15.0/24
+202.45.16.0/20
+202.46.16.0/23
+202.46.18.0/24
+202.46.20.0/23
+202.46.32.0/19
+202.46.128.0/24
+202.46.224.0/20
+202.47.82.0/23
+202.47.96.0/22
+202.47.100.0/22
+202.47.104.0/22
+202.47.108.0/22
+202.47.126.0/24
+202.47.128.0/24
+202.47.130.0/23
+202.52.33.0/24
+202.52.34.0/24
+202.52.47.0/24
+202.52.143.0/24
+202.52.144.0/24
+202.53.140.0/24
+202.53.143.0/24
+202.57.192.0/22
+202.57.196.0/22
+202.57.200.0/22
+202.57.204.0/22
+202.57.212.0/22
+202.57.216.0/22
+202.57.240.0/20
+202.58.0.0/24
+202.58.101.0/24
+202.58.104.0/22
+202.58.112.0/22
+202.59.0.0/24
+202.59.1.0/24
+202.59.212.0/22
+202.59.236.0/24
+202.59.240.0/24
+202.60.48.0/21
+202.60.96.0/21
+202.60.112.0/20
+202.60.132.0/22
+202.60.136.0/21
+202.60.144.0/20
+202.61.68.0/22
+202.61.76.0/22
+202.61.88.0/22
+202.61.123.0/24
+202.61.127.0/24
+202.62.112.0/22
+202.62.248.0/22
+202.62.252.0/24
+202.62.255.0/24
+202.63.80.0/24
+202.63.81.0/24
+202.63.82.0/23
+202.63.84.0/22
+202.63.88.0/21
+202.63.160.0/19
+202.63.248.0/22
+202.63.253.0/24
+202.65.0.0/21
+202.65.8.0/23
+202.65.96.0/22
+202.65.100.0/22
+202.65.104.0/22
+202.65.108.0/22
+202.66.168.0/22
+202.67.0.0/22
+202.69.4.0/22
+202.69.16.0/20
+202.70.0.0/19
+202.70.96.0/20
+202.70.192.0/20
+202.71.32.0/22
+202.71.36.0/22
+202.71.40.0/22
+202.71.44.0/22
+202.72.40.0/21
+202.72.80.0/20
+202.72.112.0/22
+202.72.116.0/22
+202.72.120.0/22
+202.72.124.0/22
+202.73.128.0/22
+202.73.240.0/22
+202.73.244.0/22
+202.73.248.0/22
+202.73.252.0/22
+202.74.8.0/21
+202.74.36.0/24
+202.74.42.0/24
+202.74.52.0/24
+202.74.80.0/20
+202.74.232.0/22
+202.74.254.0/23
+202.75.208.0/20
+202.75.252.0/22
+202.76.252.0/22
+202.77.80.0/21
+202.77.92.0/22
+202.78.8.0/21
+202.79.224.0/21
+202.79.248.0/22
+202.80.192.0/21
+202.80.200.0/21
+202.81.0.0/22
+202.81.176.0/22
+202.81.180.0/22
+202.81.184.0/22
+202.81.188.0/22
+202.83.252.0/22
+202.84.0.0/22
+202.84.4.0/22
+202.84.8.0/21
+202.84.16.0/23
+202.84.22.0/24
+202.84.24.0/21
+202.85.208.0/20
+202.86.249.0/24
+202.86.252.0/22
+202.87.80.0/20
+202.88.32.0/22
+202.89.8.0/21
+202.89.96.0/22
+202.89.108.0/22
+202.89.119.0/24
+202.89.232.0/21
+202.90.0.0/22
+202.90.16.0/22
+202.90.20.0/22
+202.90.24.0/22
+202.90.28.0/22
+202.90.37.0/24
+202.90.96.0/22
+202.90.100.0/22
+202.90.104.0/22
+202.90.108.0/22
+202.90.112.0/20
+202.90.193.0/24
+202.90.196.0/24
+202.90.205.0/24
+202.90.224.0/20
+202.91.0.0/22
+202.91.36.0/22
+202.91.96.0/20
+202.91.128.0/22
+202.91.176.0/20
+202.91.224.0/19
+202.92.0.0/22
+202.92.8.0/21
+202.92.48.0/20
+202.92.252.0/22
+202.93.0.0/22
+202.93.252.0/22
+202.94.68.0/24
+202.94.74.0/24
+202.94.81.0/24
+202.94.92.0/22
+202.95.240.0/21
+202.95.252.0/22
+202.96.0.0/18
+202.96.64.0/21
+202.96.72.0/21
+202.96.80.0/20
+202.96.96.0/21
+202.96.104.0/21
+202.96.112.0/20
+202.96.128.0/21
+202.96.136.0/21
+202.96.144.0/20
+202.96.160.0/21
+202.96.168.0/21
+202.96.176.0/20
+202.96.192.0/21
+202.96.200.0/21
+202.96.208.0/20
+202.96.224.0/21
+202.96.232.0/21
+202.96.240.0/20
+202.97.0.0/21
+202.97.8.0/21
+202.97.16.0/20
+202.97.32.0/19
+202.97.64.0/19
+202.97.96.0/20
+202.97.112.0/20
+202.97.128.0/18
+202.97.192.0/19
+202.97.224.0/21
+202.97.232.0/21
+202.97.240.0/20
+202.98.0.0/21
+202.98.8.0/21
+202.98.16.0/20
+202.98.32.0/21
+202.98.40.0/21
+202.98.48.0/20
+202.98.64.0/19
+202.98.96.0/21
+202.98.104.0/21
+202.98.112.0/20
+202.98.128.0/19
+202.98.160.0/21
+202.98.168.0/21
+202.98.176.0/20
+202.98.192.0/21
+202.98.200.0/21
+202.98.208.0/20
+202.98.224.0/21
+202.98.232.0/21
+202.98.240.0/20
+202.99.0.0/18
+202.99.64.0/19
+202.99.96.0/21
+202.99.104.0/21
+202.99.112.0/20
+202.99.128.0/19
+202.99.160.0/21
+202.99.168.0/21
+202.99.176.0/20
+202.99.192.0/21
+202.99.200.0/21
+202.99.208.0/20
+202.99.224.0/21
+202.99.232.0/21
+202.99.240.0/20
+202.100.0.0/21
+202.100.8.0/21
+202.100.16.0/20
+202.100.32.0/19
+202.100.64.0/21
+202.100.72.0/21
+202.100.80.0/20
+202.100.96.0/21
+202.100.104.0/21
+202.100.112.0/20
+202.100.128.0/21
+202.100.136.0/21
+202.100.144.0/20
+202.100.160.0/21
+202.100.168.0/21
+202.100.176.0/20
+202.100.192.0/21
+202.100.200.0/21
+202.100.208.0/20
+202.100.224.0/19
+202.101.0.0/18
+202.101.64.0/19
+202.101.96.0/19
+202.101.128.0/18
+202.101.192.0/19
+202.101.224.0/21
+202.101.232.0/21
+202.101.240.0/20
+202.102.0.0/19
+202.102.32.0/19
+202.102.64.0/18
+202.102.128.0/21
+202.102.136.0/21
+202.102.144.0/20
+202.102.160.0/19
+202.102.192.0/21
+202.102.200.0/21
+202.102.208.0/20
+202.102.224.0/21
+202.102.232.0/21
+202.102.240.0/20
+202.103.0.0/21
+202.103.8.0/21
+202.103.16.0/20
+202.103.32.0/19
+202.103.64.0/19
+202.103.96.0/21
+202.103.104.0/21
+202.103.112.0/20
+202.103.128.0/18
+202.103.192.0/19
+202.103.224.0/21
+202.103.232.0/21
+202.103.240.0/20
+202.104.0.0/15
+202.106.0.0/16
+202.107.0.0/17
+202.107.128.0/17
+202.108.0.0/16
+202.109.0.0/16
+202.110.0.0/18
+202.110.64.0/18
+202.110.128.0/18
+202.110.192.0/18
+202.111.0.0/17
+202.111.128.0/19
+202.111.160.0/19
+202.111.192.0/18
+202.112.0.0/16
+202.113.0.0/20
+202.113.16.0/20
+202.113.32.0/19
+202.113.64.0/18
+202.113.128.0/18
+202.113.192.0/19
+202.113.224.0/20
+202.113.240.0/20
+202.114.0.0/19
+202.114.32.0/19
+202.114.64.0/18
+202.114.128.0/17
+202.115.0.0/19
+202.115.32.0/19
+202.115.64.0/18
+202.115.128.0/17
+202.116.0.0/19
+202.116.32.0/20
+202.116.48.0/20
+202.116.64.0/19
+202.116.96.0/19
+202.116.128.0/17
+202.117.0.0/18
+202.117.64.0/18
+202.117.128.0/17
+202.118.0.0/19
+202.118.32.0/19
+202.118.64.0/18
+202.118.128.0/17
+202.119.0.0/19
+202.119.32.0/19
+202.119.64.0/20
+202.119.80.0/20
+202.119.96.0/19
+202.119.128.0/17
+202.120.0.0/18
+202.120.64.0/18
+202.120.128.0/17
+202.121.0.0/16
+202.122.0.0/21
+202.122.32.0/21
+202.122.64.0/19
+202.122.112.0/21
+202.122.120.0/21
+202.122.128.0/24
+202.122.132.0/24
+202.123.96.0/20
+202.123.116.0/22
+202.123.120.0/22
+202.124.16.0/21
+202.124.24.0/22
+202.125.107.0/24
+202.125.109.0/24
+202.125.112.0/20
+202.125.176.0/20
+202.127.0.0/23
+202.127.2.0/24
+202.127.3.0/24
+202.127.4.0/24
+202.127.5.0/24
+202.127.6.0/23
+202.127.12.0/22
+202.127.16.0/20
+202.127.40.0/21
+202.127.48.0/20
+202.127.112.0/20
+202.127.128.0/20
+202.127.144.0/20
+202.127.160.0/21
+202.127.192.0/23
+202.127.194.0/23
+202.127.196.0/22
+202.127.200.0/21
+202.127.208.0/24
+202.127.209.0/24
+202.127.212.0/22
+202.127.216.0/21
+202.127.224.0/19
+202.129.208.0/24
+202.130.0.0/19
+202.130.39.0/24
+202.130.224.0/19
+202.131.16.0/21
+202.131.48.0/20
+202.131.208.0/20
+202.133.32.0/20
+202.134.58.0/24
+202.134.128.0/20
+202.134.208.0/22
+202.134.212.0/22
+202.134.216.0/22
+202.134.220.0/22
+202.136.48.0/20
+202.136.208.0/20
+202.136.224.0/20
+202.136.248.0/22
+202.137.231.0/24
+202.140.140.0/22
+202.140.144.0/22
+202.140.148.0/22
+202.140.152.0/22
+202.140.156.0/22
+202.141.160.0/19
+202.142.16.0/20
+202.143.4.0/22
+202.143.16.0/20
+202.143.32.0/20
+202.143.56.0/21
+202.143.100.0/22
+202.143.104.0/22
+202.144.196.0/22
+202.146.160.0/20
+202.146.186.0/24
+202.146.188.0/22
+202.146.196.0/22
+202.146.200.0/21
+202.147.144.0/20
+202.148.32.0/20
+202.148.64.0/19
+202.148.96.0/19
+202.149.32.0/19
+202.149.160.0/19
+202.149.224.0/19
+202.150.16.0/20
+202.150.32.0/20
+202.150.56.0/22
+202.150.192.0/20
+202.150.224.0/19
+202.151.0.0/22
+202.151.33.0/24
+202.151.128.0/19
+202.152.176.0/20
+202.153.0.0/22
+202.153.7.0/24
+202.153.48.0/20
+202.157.192.0/19
+202.158.160.0/19
+202.158.242.0/24
+202.160.140.0/22
+202.160.156.0/22
+202.160.176.0/20
+202.162.67.0/24
+202.162.75.0/24
+202.164.0.0/20
+202.164.96.0/19
+202.165.176.0/20
+202.165.208.0/20
+202.165.239.0/24
+202.165.240.0/23
+202.165.243.0/24
+202.165.245.0/24
+202.165.251.0/24
+202.165.252.0/22
+202.166.224.0/19
+202.168.80.0/22
+202.168.128.0/22
+202.168.132.0/22
+202.168.136.0/22
+202.168.140.0/22
+202.168.160.0/20
+202.168.176.0/20
+202.170.128.0/19
+202.170.216.0/21
+202.170.224.0/19
+202.171.216.0/21
+202.171.232.0/24
+202.171.235.0/24
+202.172.0.0/22
+202.172.7.0/24
+202.173.0.0/22
+202.173.6.0/24
+202.173.8.0/21
+202.173.112.0/22
+202.173.224.0/19
+202.174.64.0/20
+202.174.124.0/22
+202.176.224.0/19
+202.179.160.0/22
+202.179.164.0/22
+202.179.168.0/22
+202.179.172.0/22
+202.179.240.0/20
+202.180.128.0/19
+202.180.208.0/21
+202.181.8.0/22
+202.181.28.0/22
+202.181.112.0/20
+202.182.32.0/20
+202.182.192.0/19
+202.189.0.0/18
+202.189.80.0/20
+202.189.184.0/21
+202.191.0.0/24
+202.191.68.0/22
+202.191.72.0/21
+202.191.80.0/20
+202.192.0.0/13
+202.200.0.0/14
+202.204.0.0/14
+203.0.4.0/22
+203.0.10.0/23
+203.0.18.0/24
+203.0.24.0/24
+203.0.42.0/23
+203.0.45.0/24
+203.0.46.0/23
+203.0.81.0/24
+203.0.82.0/23
+203.0.90.0/23
+203.0.96.0/23
+203.0.104.0/21
+203.0.114.0/23
+203.0.122.0/24
+203.0.128.0/24
+203.0.130.0/23
+203.0.132.0/22
+203.0.137.0/24
+203.0.142.0/24
+203.0.144.0/24
+203.0.146.0/24
+203.0.148.0/24
+203.0.150.0/23
+203.0.152.0/24
+203.0.177.0/24
+203.0.224.0/24
+203.1.4.0/22
+203.1.18.0/24
+203.1.26.0/23
+203.1.65.0/24
+203.1.66.0/23
+203.1.70.0/23
+203.1.76.0/23
+203.1.90.0/24
+203.1.97.0/24
+203.1.98.0/23
+203.1.100.0/22
+203.1.108.0/24
+203.1.253.0/24
+203.1.254.0/24
+203.2.64.0/21
+203.2.73.0/24
+203.2.112.0/21
+203.2.126.0/23
+203.2.140.0/24
+203.2.150.0/24
+203.2.152.0/22
+203.2.156.0/23
+203.2.160.0/21
+203.2.180.0/23
+203.2.196.0/23
+203.2.209.0/24
+203.2.214.0/23
+203.2.226.0/23
+203.2.229.0/24
+203.2.236.0/23
+203.3.68.0/24
+203.3.72.0/23
+203.3.75.0/24
+203.3.80.0/21
+203.3.96.0/22
+203.3.105.0/24
+203.3.112.0/21
+203.3.120.0/24
+203.3.123.0/24
+203.3.135.0/24
+203.3.139.0/24
+203.3.143.0/24
+203.4.132.0/23
+203.4.134.0/24
+203.4.151.0/24
+203.4.152.0/22
+203.4.174.0/23
+203.4.180.0/24
+203.4.186.0/24
+203.4.205.0/24
+203.4.208.0/22
+203.4.227.0/24
+203.4.230.0/23
+203.5.4.0/23
+203.5.7.0/24
+203.5.8.0/23
+203.5.11.0/24
+203.5.21.0/24
+203.5.22.0/24
+203.5.44.0/24
+203.5.46.0/23
+203.5.52.0/22
+203.5.56.0/23
+203.5.60.0/23
+203.5.114.0/23
+203.5.118.0/24
+203.5.120.0/24
+203.5.172.0/24
+203.5.180.0/23
+203.5.182.0/24
+203.5.185.0/24
+203.5.186.0/24
+203.5.188.0/23
+203.5.190.0/24
+203.5.195.0/24
+203.5.214.0/23
+203.5.218.0/23
+203.6.131.0/24
+203.6.136.0/24
+203.6.138.0/23
+203.6.142.0/24
+203.6.150.0/23
+203.6.157.0/24
+203.6.159.0/24
+203.6.224.0/20
+203.6.248.0/23
+203.7.129.0/24
+203.7.138.0/23
+203.7.147.0/24
+203.7.150.0/23
+203.7.158.0/24
+203.7.192.0/23
+203.7.200.0/24
+203.8.0.0/24
+203.8.8.0/24
+203.8.23.0/24
+203.8.70.0/24
+203.8.82.0/24
+203.8.86.0/23
+203.8.91.0/24
+203.8.110.0/23
+203.8.115.0/24
+203.8.166.0/23
+203.8.169.0/24
+203.8.173.0/24
+203.8.184.0/24
+203.8.186.0/23
+203.8.190.0/23
+203.8.192.0/24
+203.8.197.0/24
+203.8.198.0/23
+203.8.203.0/24
+203.8.209.0/24
+203.8.210.0/23
+203.8.212.0/22
+203.8.217.0/24
+203.8.220.0/24
+203.9.32.0/24
+203.9.36.0/23
+203.9.57.0/24
+203.9.63.0/24
+203.9.65.0/24
+203.9.70.0/23
+203.9.72.0/24
+203.9.75.0/24
+203.9.76.0/23
+203.9.96.0/22
+203.9.100.0/23
+203.9.108.0/24
+203.9.158.0/24
+203.10.34.0/24
+203.10.56.0/24
+203.10.74.0/23
+203.10.84.0/22
+203.10.88.0/24
+203.10.95.0/24
+203.10.125.0/24
+203.11.70.0/24
+203.11.76.0/22
+203.11.82.0/24
+203.11.84.0/22
+203.11.100.0/22
+203.11.109.0/24
+203.11.117.0/24
+203.11.122.0/24
+203.11.126.0/24
+203.11.136.0/22
+203.11.141.0/24
+203.11.142.0/23
+203.11.180.0/22
+203.11.208.0/22
+203.12.16.0/24
+203.12.19.0/24
+203.12.24.0/24
+203.12.57.0/24
+203.12.65.0/24
+203.12.66.0/24
+203.12.70.0/23
+203.12.87.0/24
+203.12.100.0/23
+203.12.103.0/24
+203.12.114.0/24
+203.12.118.0/24
+203.12.130.0/24
+203.12.137.0/24
+203.12.196.0/22
+203.12.211.0/24
+203.12.219.0/24
+203.12.226.0/24
+203.12.240.0/22
+203.13.18.0/24
+203.13.24.0/24
+203.13.44.0/23
+203.13.88.0/23
+203.13.92.0/22
+203.13.173.0/24
+203.13.224.0/23
+203.13.227.0/24
+203.13.233.0/24
+203.14.24.0/22
+203.14.33.0/24
+203.14.56.0/24
+203.14.61.0/24
+203.14.62.0/24
+203.14.104.0/24
+203.14.114.0/23
+203.14.118.0/24
+203.14.162.0/24
+203.14.192.0/24
+203.14.194.0/23
+203.14.214.0/24
+203.14.231.0/24
+203.14.246.0/24
+203.15.0.0/20
+203.15.20.0/23
+203.15.22.0/24
+203.15.87.0/24
+203.15.88.0/23
+203.15.105.0/24
+203.15.112.0/21
+203.15.130.0/23
+203.15.149.0/24
+203.15.151.0/24
+203.15.156.0/22
+203.15.174.0/24
+203.15.227.0/24
+203.15.232.0/21
+203.15.240.0/23
+203.15.246.0/24
+203.16.10.0/24
+203.16.12.0/23
+203.16.16.0/21
+203.16.27.0/24
+203.16.38.0/24
+203.16.49.0/24
+203.16.50.0/23
+203.16.58.0/24
+203.16.63.0/24
+203.16.133.0/24
+203.16.161.0/24
+203.16.162.0/24
+203.16.186.0/23
+203.16.228.0/24
+203.16.238.0/24
+203.16.240.0/24
+203.16.245.0/24
+203.17.2.0/24
+203.17.18.0/24
+203.17.28.0/24
+203.17.39.0/24
+203.17.56.0/24
+203.17.74.0/23
+203.17.88.0/23
+203.17.136.0/24
+203.17.164.0/24
+203.17.187.0/24
+203.17.190.0/23
+203.17.231.0/24
+203.17.233.0/24
+203.17.248.0/24
+203.17.249.0/24
+203.17.255.0/24
+203.18.2.0/23
+203.18.4.0/24
+203.18.7.0/24
+203.18.31.0/24
+203.18.37.0/24
+203.18.48.0/23
+203.18.52.0/24
+203.18.72.0/22
+203.18.80.0/23
+203.18.87.0/24
+203.18.100.0/23
+203.18.105.0/24
+203.18.107.0/24
+203.18.110.0/24
+203.18.129.0/24
+203.18.131.0/24
+203.18.132.0/23
+203.18.144.0/24
+203.18.153.0/24
+203.18.199.0/24
+203.18.208.0/24
+203.18.211.0/24
+203.18.215.0/24
+203.19.1.0/24
+203.19.18.0/24
+203.19.24.0/24
+203.19.30.0/24
+203.19.32.0/21
+203.19.41.0/24
+203.19.44.0/23
+203.19.46.0/24
+203.19.58.0/24
+203.19.60.0/23
+203.19.64.0/24
+203.19.68.0/24
+203.19.72.0/24
+203.19.101.0/24
+203.19.111.0/24
+203.19.131.0/24
+203.19.133.0/24
+203.19.144.0/24
+203.19.147.0/24
+203.19.149.0/24
+203.19.156.0/24
+203.19.176.0/24
+203.19.178.0/23
+203.19.208.0/24
+203.19.228.0/22
+203.19.233.0/24
+203.19.242.0/24
+203.19.248.0/23
+203.19.255.0/24
+203.20.17.0/24
+203.20.40.0/23
+203.20.44.0/24
+203.20.48.0/24
+203.20.61.0/24
+203.20.65.0/24
+203.20.84.0/23
+203.20.89.0/24
+203.20.106.0/23
+203.20.115.0/24
+203.20.117.0/24
+203.20.118.0/23
+203.20.122.0/24
+203.20.126.0/23
+203.20.135.0/24
+203.20.136.0/21
+203.20.150.0/24
+203.20.230.0/24
+203.20.232.0/24
+203.20.236.0/24
+203.21.0.0/23
+203.21.2.0/24
+203.21.8.0/24
+203.21.10.0/24
+203.21.18.0/24
+203.21.33.0/24
+203.21.34.0/24
+203.21.41.0/24
+203.21.44.0/24
+203.21.68.0/24
+203.21.82.0/24
+203.21.96.0/22
+203.21.124.0/24
+203.21.136.0/23
+203.21.145.0/24
+203.21.206.0/24
+203.22.24.0/24
+203.22.28.0/23
+203.22.31.0/24
+203.22.68.0/24
+203.22.76.0/24
+203.22.78.0/24
+203.22.84.0/24
+203.22.87.0/24
+203.22.92.0/22
+203.22.99.0/24
+203.22.106.0/24
+203.22.122.0/23
+203.22.131.0/24
+203.22.163.0/24
+203.22.166.0/24
+203.22.170.0/24
+203.22.176.0/21
+203.22.194.0/24
+203.22.242.0/23
+203.22.245.0/24
+203.22.246.0/24
+203.22.252.0/23
+203.23.0.0/24
+203.23.47.0/24
+203.23.61.0/24
+203.23.62.0/23
+203.23.73.0/24
+203.23.85.0/24
+203.23.92.0/22
+203.23.98.0/24
+203.23.107.0/24
+203.23.112.0/24
+203.23.130.0/24
+203.23.140.0/23
+203.23.172.0/24
+203.23.182.0/24
+203.23.186.0/23
+203.23.192.0/24
+203.23.197.0/24
+203.23.198.0/24
+203.23.204.0/22
+203.23.224.0/24
+203.23.226.0/23
+203.23.228.0/22
+203.23.249.0/24
+203.23.251.0/24
+203.24.13.0/24
+203.24.18.0/24
+203.24.27.0/24
+203.24.43.0/24
+203.24.56.0/24
+203.24.58.0/24
+203.24.67.0/24
+203.24.74.0/24
+203.24.79.0/24
+203.24.80.0/23
+203.24.84.0/23
+203.24.86.0/24
+203.24.90.0/24
+203.24.111.0/24
+203.24.112.0/24
+203.24.116.0/24
+203.24.122.0/23
+203.24.145.0/24
+203.24.152.0/23
+203.24.157.0/24
+203.24.161.0/24
+203.24.167.0/24
+203.24.186.0/23
+203.24.199.0/24
+203.24.202.0/24
+203.24.212.0/23
+203.24.217.0/24
+203.24.219.0/24
+203.24.244.0/24
+203.25.19.0/24
+203.25.20.0/23
+203.25.46.0/24
+203.25.48.0/21
+203.25.64.0/23
+203.25.91.0/24
+203.25.99.0/24
+203.25.100.0/24
+203.25.106.0/24
+203.25.131.0/24
+203.25.135.0/24
+203.25.138.0/24
+203.25.147.0/24
+203.25.153.0/24
+203.25.154.0/23
+203.25.164.0/24
+203.25.166.0/24
+203.25.174.0/23
+203.25.180.0/24
+203.25.182.0/24
+203.25.191.0/24
+203.25.199.0/24
+203.25.200.0/24
+203.25.202.0/23
+203.25.208.0/20
+203.25.229.0/24
+203.25.235.0/24
+203.25.236.0/24
+203.25.242.0/24
+203.26.12.0/24
+203.26.34.0/24
+203.26.49.0/24
+203.26.50.0/24
+203.26.55.0/24
+203.26.56.0/23
+203.26.60.0/24
+203.26.65.0/24
+203.26.68.0/24
+203.26.76.0/24
+203.26.80.0/24
+203.26.84.0/24
+203.26.97.0/24
+203.26.102.0/23
+203.26.115.0/24
+203.26.116.0/24
+203.26.129.0/24
+203.26.143.0/24
+203.26.144.0/24
+203.26.148.0/23
+203.26.154.0/24
+203.26.158.0/23
+203.26.170.0/24
+203.26.173.0/24
+203.26.176.0/24
+203.26.185.0/24
+203.26.202.0/23
+203.26.210.0/24
+203.26.214.0/24
+203.26.222.0/24
+203.26.224.0/24
+203.26.228.0/24
+203.26.232.0/24
+203.27.0.0/24
+203.27.10.0/24
+203.27.15.0/24
+203.27.16.0/24
+203.27.20.0/24
+203.27.22.0/23
+203.27.40.0/24
+203.27.45.0/24
+203.27.53.0/24
+203.27.65.0/24
+203.27.66.0/24
+203.27.81.0/24
+203.27.88.0/24
+203.27.102.0/24
+203.27.109.0/24
+203.27.117.0/24
+203.27.121.0/24
+203.27.122.0/23
+203.27.125.0/24
+203.27.200.0/24
+203.27.202.0/24
+203.27.233.0/24
+203.27.241.0/24
+203.27.250.0/24
+203.28.10.0/24
+203.28.12.0/24
+203.28.33.0/24
+203.28.34.0/23
+203.28.43.0/24
+203.28.44.0/24
+203.28.54.0/24
+203.28.56.0/24
+203.28.73.0/24
+203.28.74.0/24
+203.28.76.0/24
+203.28.86.0/24
+203.28.88.0/24
+203.28.112.0/24
+203.28.131.0/24
+203.28.136.0/24
+203.28.140.0/24
+203.28.145.0/24
+203.28.165.0/24
+203.28.169.0/24
+203.28.170.0/24
+203.28.178.0/23
+203.28.185.0/24
+203.28.187.0/24
+203.28.196.0/24
+203.28.226.0/23
+203.28.239.0/24
+203.29.2.0/24
+203.29.8.0/23
+203.29.13.0/24
+203.29.14.0/24
+203.29.28.0/24
+203.29.46.0/24
+203.29.57.0/24
+203.29.61.0/24
+203.29.63.0/24
+203.29.69.0/24
+203.29.73.0/24
+203.29.81.0/24
+203.29.90.0/24
+203.29.95.0/24
+203.29.100.0/24
+203.29.103.0/24
+203.29.112.0/24
+203.29.120.0/22
+203.29.182.0/23
+203.29.187.0/24
+203.29.189.0/24
+203.29.190.0/24
+203.29.205.0/24
+203.29.210.0/24
+203.29.217.0/24
+203.29.227.0/24
+203.29.231.0/24
+203.29.233.0/24
+203.29.234.0/24
+203.29.248.0/24
+203.29.254.0/23
+203.30.16.0/23
+203.30.25.0/24
+203.30.27.0/24
+203.30.29.0/24
+203.30.66.0/24
+203.30.81.0/24
+203.30.87.0/24
+203.30.111.0/24
+203.30.121.0/24
+203.30.123.0/24
+203.30.152.0/24
+203.30.156.0/24
+203.30.162.0/24
+203.30.173.0/24
+203.30.175.0/24
+203.30.187.0/24
+203.30.194.0/24
+203.30.217.0/24
+203.30.220.0/24
+203.30.222.0/24
+203.30.232.0/23
+203.30.235.0/24
+203.30.240.0/23
+203.30.246.0/24
+203.30.250.0/23
+203.31.45.0/24
+203.31.46.0/24
+203.31.49.0/24
+203.31.51.0/24
+203.31.54.0/23
+203.31.69.0/24
+203.31.72.0/24
+203.31.80.0/24
+203.31.85.0/24
+203.31.97.0/24
+203.31.105.0/24
+203.31.106.0/24
+203.31.108.0/23
+203.31.124.0/24
+203.31.162.0/24
+203.31.174.0/24
+203.31.177.0/24
+203.31.181.0/24
+203.31.187.0/24
+203.31.189.0/24
+203.31.204.0/24
+203.31.220.0/24
+203.31.222.0/23
+203.31.225.0/24
+203.31.229.0/24
+203.31.248.0/23
+203.31.253.0/24
+203.32.20.0/24
+203.32.48.0/23
+203.32.56.0/24
+203.32.60.0/24
+203.32.62.0/24
+203.32.68.0/23
+203.32.76.0/24
+203.32.81.0/24
+203.32.84.0/23
+203.32.95.0/24
+203.32.102.0/24
+203.32.105.0/24
+203.32.130.0/24
+203.32.133.0/24
+203.32.140.0/24
+203.32.152.0/24
+203.32.186.0/23
+203.32.192.0/24
+203.32.196.0/24
+203.32.203.0/24
+203.32.204.0/23
+203.32.212.0/24
+203.33.4.0/24
+203.33.7.0/24
+203.33.8.0/21
+203.33.21.0/24
+203.33.26.0/24
+203.33.32.0/24
+203.33.63.0/24
+203.33.64.0/24
+203.33.67.0/24
+203.33.68.0/24
+203.33.73.0/24
+203.33.79.0/24
+203.33.100.0/24
+203.33.122.0/24
+203.33.129.0/24
+203.33.131.0/24
+203.33.145.0/24
+203.33.156.0/24
+203.33.158.0/23
+203.33.174.0/24
+203.33.185.0/24
+203.33.200.0/24
+203.33.202.0/23
+203.33.204.0/24
+203.33.206.0/23
+203.33.214.0/23
+203.33.224.0/23
+203.33.226.0/24
+203.33.233.0/24
+203.33.243.0/24
+203.33.250.0/24
+203.34.4.0/24
+203.34.21.0/24
+203.34.27.0/24
+203.34.39.0/24
+203.34.48.0/23
+203.34.54.0/24
+203.34.56.0/23
+203.34.67.0/24
+203.34.69.0/24
+203.34.76.0/24
+203.34.92.0/24
+203.34.106.0/24
+203.34.113.0/24
+203.34.147.0/24
+203.34.150.0/24
+203.34.152.0/23
+203.34.161.0/24
+203.34.162.0/24
+203.34.187.0/24
+203.34.192.0/21
+203.34.204.0/22
+203.34.232.0/24
+203.34.240.0/24
+203.34.242.0/24
+203.34.245.0/24
+203.34.251.0/24
+203.55.2.0/23
+203.55.4.0/24
+203.55.10.0/24
+203.55.13.0/24
+203.55.22.0/24
+203.55.30.0/24
+203.55.93.0/24
+203.55.101.0/24
+203.55.109.0/24
+203.55.110.0/24
+203.55.116.0/23
+203.55.119.0/24
+203.55.128.0/23
+203.55.146.0/23
+203.55.192.0/24
+203.55.196.0/24
+203.55.218.0/23
+203.55.221.0/24
+203.55.224.0/24
+203.56.1.0/24
+203.56.4.0/24
+203.56.12.0/24
+203.56.24.0/24
+203.56.38.0/24
+203.56.40.0/24
+203.56.46.0/24
+203.56.48.0/21
+203.56.68.0/23
+203.56.82.0/23
+203.56.84.0/23
+203.56.95.0/24
+203.56.110.0/24
+203.56.121.0/24
+203.56.161.0/24
+203.56.169.0/24
+203.56.172.0/23
+203.56.175.0/24
+203.56.183.0/24
+203.56.185.0/24
+203.56.187.0/24
+203.56.192.0/24
+203.56.198.0/24
+203.56.201.0/24
+203.56.208.0/23
+203.56.210.0/24
+203.56.214.0/24
+203.56.216.0/24
+203.56.227.0/24
+203.56.228.0/24
+203.56.231.0/24
+203.56.232.0/24
+203.56.240.0/24
+203.56.252.0/24
+203.56.254.0/24
+203.57.5.0/24
+203.57.6.0/24
+203.57.12.0/23
+203.57.28.0/24
+203.57.39.0/24
+203.57.46.0/24
+203.57.58.0/24
+203.57.61.0/24
+203.57.66.0/24
+203.57.69.0/24
+203.57.70.0/23
+203.57.73.0/24
+203.57.90.0/24
+203.57.101.0/24
+203.57.109.0/24
+203.57.123.0/24
+203.57.157.0/24
+203.57.200.0/24
+203.57.202.0/24
+203.57.206.0/24
+203.57.222.0/24
+203.57.224.0/20
+203.57.246.0/23
+203.57.249.0/24
+203.57.253.0/24
+203.57.254.0/23
+203.62.2.0/24
+203.62.131.0/24
+203.62.139.0/24
+203.62.161.0/24
+203.62.197.0/24
+203.62.228.0/22
+203.62.234.0/24
+203.62.246.0/24
+203.76.160.0/22
+203.76.168.0/22
+203.76.208.0/22
+203.76.212.0/22
+203.76.216.0/22
+203.76.240.0/22
+203.76.244.0/22
+203.77.180.0/22
+203.78.48.0/20
+203.78.156.0/22
+203.79.0.0/20
+203.79.32.0/20
+203.80.4.0/23
+203.80.32.0/20
+203.80.57.0/24
+203.80.129.0/24
+203.80.132.0/22
+203.80.136.0/21
+203.80.144.0/20
+203.81.0.0/21
+203.81.16.0/20
+203.81.244.0/22
+203.82.0.0/23
+203.82.16.0/21
+203.82.112.0/22
+203.82.116.0/22
+203.82.120.0/22
+203.82.124.0/22
+203.82.224.0/22
+203.82.228.0/22
+203.82.232.0/22
+203.82.236.0/22
+203.83.0.0/22
+203.83.8.0/22
+203.83.12.0/22
+203.83.56.0/21
+203.83.224.0/20
+203.86.0.0/19
+203.86.32.0/19
+203.86.64.0/20
+203.86.80.0/20
+203.86.96.0/19
+203.86.250.0/24
+203.86.254.0/23
+203.88.32.0/19
+203.88.100.0/22
+203.88.192.0/19
+203.89.0.0/22
+203.89.8.0/21
+203.89.100.0/22
+203.89.133.0/24
+203.89.136.0/22
+203.89.144.0/24
+203.90.0.0/22
+203.90.8.0/22
+203.90.12.0/22
+203.90.128.0/19
+203.90.160.0/19
+203.90.192.0/19
+203.91.32.0/19
+203.91.96.0/20
+203.91.120.0/21
+203.92.0.0/22
+203.92.6.0/24
+203.92.160.0/19
+203.93.0.0/22
+203.93.4.0/22
+203.93.8.0/24
+203.93.9.0/24
+203.93.10.0/23
+203.93.12.0/22
+203.93.16.0/20
+203.93.32.0/19
+203.93.64.0/18
+203.93.128.0/21
+203.93.136.0/22
+203.93.140.0/24
+203.93.141.0/24
+203.93.142.0/23
+203.93.144.0/20
+203.93.160.0/19
+203.93.192.0/18
+203.94.0.0/22
+203.94.4.0/22
+203.94.8.0/21
+203.94.16.0/20
+203.95.0.0/21
+203.95.96.0/20
+203.95.112.0/20
+203.95.128.0/18
+203.95.200.0/22
+203.95.204.0/22
+203.95.208.0/22
+203.95.224.0/19
+203.99.8.0/21
+203.99.16.0/20
+203.99.80.0/20
+203.100.32.0/20
+203.100.48.0/21
+203.100.58.0/24
+203.100.60.0/24
+203.100.63.0/24
+203.100.80.0/20
+203.100.96.0/19
+203.100.192.0/20
+203.104.32.0/20
+203.105.96.0/19
+203.105.128.0/19
+203.107.0.0/17
+203.110.160.0/19
+203.110.208.0/20
+203.110.232.0/23
+203.110.234.0/24
+203.114.80.0/22
+203.114.84.0/22
+203.114.88.0/22
+203.114.92.0/22
+203.114.244.0/22
+203.118.192.0/19
+203.118.241.0/24
+203.118.248.0/22
+203.119.24.0/21
+203.119.32.0/22
+203.119.80.0/22
+203.119.85.0/24
+203.119.113.0/24
+203.119.114.0/23
+203.119.116.0/22
+203.119.120.0/21
+203.119.128.0/17
+203.123.58.0/24
+203.128.32.0/19
+203.128.96.0/19
+203.128.224.0/21
+203.129.8.0/21
+203.130.32.0/19
+203.132.32.0/19
+203.134.240.0/21
+203.135.96.0/20
+203.135.112.0/20
+203.135.160.0/20
+203.142.219.0/24
+203.142.224.0/19
+203.144.96.0/19
+203.145.0.0/19
+203.148.0.0/18
+203.148.64.0/20
+203.148.80.0/22
+203.148.86.0/23
+203.149.92.0/22
+203.152.64.0/19
+203.152.128.0/19
+203.153.0.0/22
+203.156.192.0/18
+203.158.16.0/21
+203.160.52.0/22
+203.160.104.0/21
+203.160.129.0/24
+203.160.192.0/19
+203.161.0.0/22
+203.161.180.0/24
+203.161.183.0/24
+203.161.192.0/19
+203.166.160.0/19
+203.167.28.0/22
+203.168.0.0/19
+203.170.58.0/23
+203.171.0.0/22
+203.171.208.0/24
+203.171.224.0/20
+203.174.4.0/24
+203.174.6.0/24
+203.174.7.0/24
+203.174.96.0/19
+203.175.128.0/19
+203.175.192.0/18
+203.176.0.0/18
+203.176.64.0/19
+203.176.168.0/21
+203.184.80.0/20
+203.185.189.0/24
+203.187.160.0/19
+203.189.0.0/23
+203.189.6.0/23
+203.189.112.0/22
+203.189.192.0/19
+203.189.232.0/22
+203.189.240.0/22
+203.190.96.0/20
+203.190.249.0/24
+203.191.0.0/23
+203.191.2.0/24
+203.191.5.0/24
+203.191.7.0/24
+203.191.16.0/20
+203.191.64.0/18
+203.191.133.0/24
+203.191.144.0/21
+203.191.152.0/21
+203.192.0.0/19
+203.193.224.0/19
+203.194.120.0/21
+203.195.64.0/19
+203.195.112.0/21
+203.195.128.0/17
+203.196.0.0/21
+203.196.8.0/21
+203.196.28.0/22
+203.201.181.0/24
+203.201.182.0/24
+203.202.236.0/22
+203.205.64.0/19
+203.205.128.0/17
+203.207.64.0/20
+203.207.80.0/21
+203.207.88.0/22
+203.207.92.0/22
+203.207.96.0/20
+203.207.112.0/20
+203.207.128.0/18
+203.207.192.0/21
+203.207.200.0/21
+203.207.208.0/20
+203.207.224.0/19
+203.208.0.0/20
+203.208.16.0/22
+203.208.32.0/19
+203.209.224.0/19
+203.212.0.0/20
+203.212.80.0/20
+203.215.232.0/21
+203.217.164.0/22
+203.223.0.0/20
+203.223.16.0/21
+204.52.191.0/24
+210.2.0.0/20
+210.2.16.0/20
+210.5.0.0/19
+210.5.56.0/21
+210.5.128.0/20
+210.5.144.0/20
+210.7.56.0/22
+210.7.60.0/22
+210.12.0.0/18
+210.12.64.0/18
+210.12.128.0/18
+210.12.192.0/18
+210.13.0.0/18
+210.13.64.0/18
+210.13.128.0/17
+210.14.64.0/19
+210.14.112.0/20
+210.14.128.0/19
+210.14.160.0/19
+210.14.192.0/19
+210.14.224.0/19
+210.15.0.0/19
+210.15.32.0/19
+210.15.64.0/19
+210.15.96.0/19
+210.15.128.0/18
+210.16.104.0/22
+210.16.128.0/18
+210.21.0.0/17
+210.21.128.0/17
+210.22.0.0/16
+210.23.32.0/19
+210.25.0.0/16
+210.26.0.0/15
+210.28.0.0/14
+210.32.0.0/14
+210.36.0.0/14
+210.40.0.0/13
+210.51.0.0/16
+210.52.0.0/18
+210.52.64.0/18
+210.52.128.0/17
+210.53.0.0/17
+210.53.128.0/17
+210.56.192.0/19
+210.72.0.0/17
+210.72.128.0/19
+210.72.160.0/19
+210.72.192.0/18
+210.73.0.0/19
+210.73.32.0/19
+210.73.64.0/18
+210.73.128.0/17
+210.74.0.0/19
+210.74.32.0/19
+210.74.64.0/19
+210.74.96.0/19
+210.74.128.0/19
+210.74.160.0/19
+210.74.192.0/18
+210.75.0.0/16
+210.76.0.0/19
+210.76.32.0/19
+210.76.64.0/18
+210.76.128.0/17
+210.77.0.0/16
+210.78.0.0/19
+210.78.32.0/19
+210.78.64.0/18
+210.78.128.0/19
+210.78.160.0/19
+210.78.192.0/18
+210.79.64.0/18
+210.79.224.0/19
+210.82.0.0/15
+210.87.128.0/20
+210.87.144.0/20
+210.87.160.0/19
+210.185.192.0/18
+210.192.96.0/19
+211.64.0.0/14
+211.68.0.0/15
+211.70.0.0/15
+211.80.0.0/16
+211.81.0.0/16
+211.82.0.0/16
+211.83.0.0/16
+211.84.0.0/15
+211.86.0.0/15
+211.88.0.0/16
+211.89.0.0/16
+211.90.0.0/15
+211.92.0.0/15
+211.94.0.0/15
+211.96.0.0/15
+211.98.0.0/16
+211.99.0.0/18
+211.99.64.0/19
+211.99.96.0/19
+211.99.128.0/17
+211.100.0.0/16
+211.101.0.0/18
+211.101.64.0/18
+211.101.128.0/17
+211.102.0.0/16
+211.103.0.0/17
+211.103.128.0/17
+211.136.0.0/14
+211.140.0.0/15
+211.142.0.0/17
+211.142.128.0/17
+211.143.0.0/16
+211.144.0.0/15
+211.146.0.0/16
+211.147.0.0/16
+211.148.0.0/14
+211.152.0.0/15
+211.154.0.0/16
+211.155.0.0/18
+211.155.64.0/19
+211.155.96.0/19
+211.155.128.0/17
+211.156.0.0/14
+211.160.0.0/14
+211.164.0.0/14
+212.64.0.0/17
+212.129.128.0/17
+218.0.0.0/16
+218.1.0.0/16
+218.2.0.0/15
+218.4.0.0/15
+218.6.0.0/16
+218.7.0.0/16
+218.8.0.0/15
+218.10.0.0/16
+218.11.0.0/16
+218.12.0.0/16
+218.13.0.0/16
+218.14.0.0/15
+218.16.0.0/14
+218.20.0.0/16
+218.21.0.0/17
+218.21.128.0/17
+218.22.0.0/15
+218.24.0.0/15
+218.26.0.0/16
+218.27.0.0/16
+218.28.0.0/15
+218.30.0.0/15
+218.56.0.0/14
+218.60.0.0/15
+218.62.0.0/17
+218.62.128.0/17
+218.63.0.0/16
+218.64.0.0/15
+218.66.0.0/16
+218.67.0.0/17
+218.67.128.0/17
+218.68.0.0/15
+218.70.0.0/15
+218.72.0.0/14
+218.76.0.0/15
+218.78.0.0/15
+218.80.0.0/14
+218.84.0.0/14
+218.88.0.0/13
+218.96.0.0/15
+218.98.0.0/17
+218.98.128.0/18
+218.98.192.0/19
+218.98.224.0/19
+218.99.0.0/16
+218.100.88.0/21
+218.100.96.0/19
+218.100.128.0/17
+218.104.0.0/17
+218.104.128.0/19
+218.104.160.0/19
+218.104.192.0/21
+218.104.200.0/21
+218.104.208.0/20
+218.104.224.0/19
+218.105.0.0/16
+218.106.0.0/15
+218.108.0.0/16
+218.109.0.0/16
+218.185.192.0/19
+218.185.240.0/21
+218.192.0.0/16
+218.193.0.0/16
+218.194.0.0/16
+218.195.0.0/16
+218.196.0.0/14
+218.200.0.0/14
+218.204.0.0/15
+218.206.0.0/15
+218.240.0.0/14
+218.244.0.0/15
+218.246.0.0/15
+218.249.0.0/16
+219.72.0.0/16
+219.82.0.0/16
+219.83.128.0/17
+219.90.68.0/22
+219.90.72.0/22
+219.90.76.0/22
+219.128.0.0/12
+219.144.0.0/14
+219.148.0.0/16
+219.149.0.0/17
+219.149.128.0/18
+219.149.192.0/18
+219.150.0.0/19
+219.150.32.0/19
+219.150.64.0/19
+219.150.96.0/20
+219.150.112.0/20
+219.150.128.0/17
+219.151.0.0/19
+219.151.32.0/19
+219.151.64.0/18
+219.151.128.0/17
+219.152.0.0/15
+219.154.0.0/15
+219.156.0.0/15
+219.158.0.0/17
+219.158.128.0/17
+219.159.0.0/18
+219.159.64.0/18
+219.159.128.0/17
+219.216.0.0/15
+219.218.0.0/15
+219.220.0.0/16
+219.221.0.0/16
+219.222.0.0/15
+219.224.0.0/15
+219.226.0.0/16
+219.227.0.0/16
+219.228.0.0/15
+219.230.0.0/15
+219.232.0.0/14
+219.236.0.0/15
+219.238.0.0/15
+219.242.0.0/15
+219.244.0.0/14
+220.101.192.0/18
+220.112.0.0/14
+220.152.128.0/17
+220.154.0.0/15
+220.158.240.0/22
+220.160.0.0/11
+220.192.0.0/15
+220.194.0.0/15
+220.196.0.0/14
+220.200.0.0/13
+220.231.0.0/18
+220.231.128.0/17
+220.232.64.0/18
+220.234.0.0/16
+220.242.0.0/15
+220.247.136.0/21
+220.248.0.0/14
+220.252.0.0/16
+221.0.0.0/15
+221.2.0.0/16
+221.3.0.0/17
+221.3.128.0/17
+221.4.0.0/16
+221.5.0.0/17
+221.5.128.0/17
+221.6.0.0/16
+221.7.0.0/19
+221.7.32.0/19
+221.7.64.0/19
+221.7.96.0/19
+221.7.128.0/17
+221.8.0.0/15
+221.10.0.0/16
+221.11.0.0/17
+221.11.128.0/18
+221.11.192.0/19
+221.11.224.0/19
+221.12.0.0/17
+221.12.128.0/18
+221.13.0.0/18
+221.13.64.0/19
+221.13.96.0/19
+221.13.128.0/17
+221.14.0.0/15
+221.122.0.0/15
+221.128.128.0/17
+221.129.0.0/16
+221.130.0.0/15
+221.133.224.0/19
+221.136.0.0/16
+221.137.0.0/16
+221.172.0.0/14
+221.176.0.0/13
+221.192.0.0/15
+221.194.0.0/16
+221.195.0.0/16
+221.196.0.0/15
+221.198.0.0/16
+221.199.0.0/19
+221.199.32.0/20
+221.199.48.0/20
+221.199.64.0/18
+221.199.128.0/18
+221.199.192.0/20
+221.199.224.0/19
+221.200.0.0/14
+221.204.0.0/15
+221.206.0.0/16
+221.207.0.0/18
+221.207.64.0/18
+221.207.128.0/17
+221.208.0.0/14
+221.212.0.0/16
+221.213.0.0/16
+221.214.0.0/15
+221.216.0.0/13
+221.224.0.0/13
+221.232.0.0/14
+221.236.0.0/15
+221.238.0.0/16
+221.239.0.0/17
+221.239.128.0/17
+222.16.0.0/15
+222.18.0.0/15
+222.20.0.0/15
+222.22.0.0/16
+222.23.0.0/16
+222.24.0.0/15
+222.26.0.0/15
+222.28.0.0/14
+222.32.0.0/11
+222.64.0.0/13
+222.72.0.0/15
+222.74.0.0/16
+222.75.0.0/16
+222.76.0.0/14
+222.80.0.0/15
+222.82.0.0/16
+222.83.0.0/17
+222.83.128.0/17
+222.84.0.0/16
+222.85.0.0/17
+222.85.128.0/17
+222.86.0.0/15
+222.88.0.0/15
+222.90.0.0/15
+222.92.0.0/14
+222.125.0.0/16
+222.126.128.0/17
+222.128.0.0/14
+222.132.0.0/14
+222.136.0.0/13
+222.160.0.0/15
+222.162.0.0/16
+222.163.0.0/19
+222.163.32.0/19
+222.163.64.0/18
+222.163.128.0/17
+222.168.0.0/15
+222.170.0.0/15
+222.172.0.0/17
+222.172.128.0/17
+222.173.0.0/16
+222.174.0.0/15
+222.176.0.0/13
+222.184.0.0/13
+222.192.0.0/14
+222.196.0.0/15
+222.198.0.0/16
+222.199.0.0/16
+222.200.0.0/14
+222.204.0.0/15
+222.206.0.0/15
+222.208.0.0/13
+222.216.0.0/15
+222.218.0.0/16
+222.219.0.0/16
+222.220.0.0/15
+222.222.0.0/15
+222.240.0.0/13
+222.248.0.0/16
+222.249.0.0/17
+222.249.128.0/19
+222.249.160.0/20
+222.249.176.0/20
+222.249.192.0/18
+223.0.0.0/15
+223.2.0.0/15
+223.4.0.0/14
+223.8.0.0/13
+223.20.0.0/15
+223.27.184.0/22
+223.29.208.0/22
+223.29.252.0/22
+223.64.0.0/11
+223.96.0.0/12
+223.112.0.0/14
+223.116.0.0/15
+223.120.128.0/17
+223.121.128.0/17
+223.122.0.0/15
+223.124.0.0/14
+223.128.0.0/15
+223.144.0.0/12
+223.160.0.0/14
+223.166.0.0/15
+223.192.0.0/15
+223.198.0.0/15
+223.201.0.0/16
+223.202.0.0/15
+223.208.0.0/14
+223.212.0.0/15
+223.214.0.0/15
+223.220.0.0/15
+223.223.176.0/20
+223.223.192.0/20
+223.240.0.0/13
+223.248.0.0/14
+223.252.128.0/17
+223.254.0.0/16
+223.255.0.0/17
+223.255.236.0/22
+223.255.252.0/23

+ 28 - 0
app/Providers/AppServiceProvider.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\ServiceProvider;
+
+class AppServiceProvider extends ServiceProvider
+{
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        //
+    }
+
+    /**
+     * Bootstrap any application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        //
+    }
+}

+ 30 - 0
app/Providers/AuthServiceProvider.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
+use Illuminate\Support\Facades\Gate;
+
+class AuthServiceProvider extends ServiceProvider
+{
+    /**
+     * The policy mappings for the application.
+     *
+     * @var array
+     */
+    protected $policies = [
+        // 'App\Model' => 'App\Policies\ModelPolicy',
+    ];
+
+    /**
+     * Register any authentication / authorization services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        $this->registerPolicies();
+
+        //
+    }
+}

+ 21 - 0
app/Providers/BroadcastServiceProvider.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Support\Facades\Broadcast;
+use Illuminate\Support\ServiceProvider;
+
+class BroadcastServiceProvider extends ServiceProvider
+{
+    /**
+     * Bootstrap any application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        Broadcast::routes();
+
+        require base_path('routes/channels.php');
+    }
+}

+ 34 - 0
app/Providers/EventServiceProvider.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Auth\Events\Registered;
+use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
+use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
+use Illuminate\Support\Facades\Event;
+
+class EventServiceProvider extends ServiceProvider
+{
+    /**
+     * The event listener mappings for the application.
+     *
+     * @var array
+     */
+    protected $listen = [
+        Registered::class => [
+            SendEmailVerificationNotification::class,
+        ],
+    ];
+
+    /**
+     * Register any events for your application.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        parent::boot();
+
+        //
+    }
+}

+ 80 - 0
app/Providers/RouteServiceProvider.php

@@ -0,0 +1,80 @@
+<?php
+
+namespace App\Providers;
+
+use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
+use Illuminate\Support\Facades\Route;
+
+class RouteServiceProvider extends ServiceProvider
+{
+    /**
+     * This namespace is applied to your controller routes.
+     *
+     * In addition, it is set as the URL generator's root namespace.
+     *
+     * @var string
+     */
+    protected $namespace = 'App\Http\Controllers';
+
+    /**
+     * The path to the "home" route for your application.
+     *
+     * @var string
+     */
+    public const HOME = '/home';
+
+    /**
+     * Define your route model bindings, pattern filters, etc.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        //
+
+        parent::boot();
+    }
+
+    /**
+     * Define the routes for the application.
+     *
+     * @return void
+     */
+    public function map()
+    {
+        $this->mapApiRoutes();
+
+        $this->mapWebRoutes();
+
+        //
+    }
+
+    /**
+     * Define the "web" routes for the application.
+     *
+     * These routes all receive session state, CSRF protection, etc.
+     *
+     * @return void
+     */
+    protected function mapWebRoutes()
+    {
+        Route::middleware('web')
+            ->namespace($this->namespace)
+            ->group(base_path('routes/web.php'));
+    }
+
+    /**
+     * Define the "api" routes for the application.
+     *
+     * These routes are typically stateless.
+     *
+     * @return void
+     */
+    protected function mapApiRoutes()
+    {
+        Route::prefix('api')
+            ->middleware('api')
+            ->namespace($this->namespace)
+            ->group(base_path('routes/api.php'));
+    }
+}

+ 468 - 0
app/Services/WebSocketService.php

@@ -0,0 +1,468 @@
+<?php
+
+namespace App\Services;
+
+@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
+
+use App\Module\Base;
+use App\Module\Chat;
+use App\Module\Users;
+use App\Tasks\ChromeExtendTask;
+use App\Tasks\NotificationTask;
+use App\Tasks\PushTask;
+use Cache;
+use DB;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+use Hhxsv5\LaravelS\Swoole\WebSocketHandlerInterface;
+use Swoole\Http\Request;
+use Swoole\WebSocket\Frame;
+use Swoole\WebSocket\Server;
+
+/**
+ * @see https://wiki.swoole.com/#/start/start_ws_server
+ */
+class WebSocketService implements WebSocketHandlerInterface
+{
+    /**
+     * 声明没有参数的构造函数
+     * WebSocketService constructor.
+     */
+    public function __construct()
+    {
+
+    }
+
+    /**
+     * 连接建立时触发
+     * @param Server $server
+     * @param Request $request
+     */
+    public function onOpen(Server $server, Request $request)
+    {
+        global $_A;
+        $_A = [
+            '__static_langdata' => [],
+        ];
+        //判断参数
+        $fd = $request->fd;
+        if (!isset($request->get['token'])) {
+            $server->push($fd, Chat::formatMsgSend([
+                'messageType' => 'error',
+                'body' => [
+                    'error' => '参数错误'
+                ],
+            ]));
+            $server->close($fd);
+            $this->deleteUser($fd);
+            return;
+        }
+        //判断token
+        $token = $request->get['token'];
+        $channel = $request->get['channel'] ?: '';
+        $cacheKey = "ws::token:" . md5($token);
+        $username = Cache::remember($cacheKey, now()->addSeconds(1), function () use ($token) {
+            list($id, $username, $encrypt, $timestamp) = explode("@", base64_decode($token) . "@@@@");
+            if (intval($id) > 0 && intval($timestamp) + 2592000 > time()) {
+                if (DB::table('users')->where(['id' => $id, 'username' => $username, 'encrypt' => $encrypt])->exists()) {
+                    return $username;
+                }
+            }
+            return null;
+        });
+        if (empty($username)) {
+            Cache::forget($cacheKey);
+            $server->push($fd, Chat::formatMsgSend([
+                'messageType' => 'error',
+                'channel' => $channel,
+                'body' => [
+                    'error' => '会员不存在',
+                ],
+            ]));
+            $server->close($fd);
+            $this->deleteUser($fd);
+            return;
+        }
+        //踢下线
+        if (in_array($channel, ['ios', 'android'])) {
+            $userLists = $this->getUser('', $channel, $username);
+            foreach ($userLists AS $user) {
+                $server->push($user['fd'], Chat::formatMsgSend([
+                    'messageType' => 'kick',
+                    'channel' => $channel,
+                    'body' => [
+                        'ip' => Base::getIp(),
+                        'time' => time(),
+                        'newfd' => $fd,
+                    ],
+                ]));
+                $this->deleteUser($user['fd']);
+            }
+        }
+        //保存用户、发送open事件
+        Cache::forever("ws::immediatelyNotify-" . $username, "no");
+        $this->saveUser($fd, $channel, $username);
+        $server->push($fd, Chat::formatMsgSend([
+            'messageType' => 'open',
+            'channel' => $channel,
+            'body' => [
+                'fd' => $fd,
+            ],
+        ]));
+        //发送最后一条未发送的信息
+        $lastMsg = Base::DBC2A(DB::table('chat_msg')->where('receive', $username)->orderByDesc('indate')->first());
+        if ($lastMsg && $lastMsg['roger'] === 0) {
+            $dialog = Chat::openDialog($lastMsg['username'], $lastMsg['receive']);
+            if (!Base::isError($dialog)) {
+                $dialog = $dialog['data'];
+                $unread = intval(DB::table('chat_dialog')->where('id', $dialog['id'])->value(($dialog['recField'] == 1 ? 'unread1' : 'unread2')));
+                $body = Base::string2array($lastMsg['message']);
+                $body['id'] = $lastMsg['id'];
+                $body['resend'] = 1;
+                $body['unread'] = $unread;
+                $body['username'] = $lastMsg['username'];
+                $body['userimg'] = Users::userimg($lastMsg['username']);
+                $body['indate'] = $lastMsg['indate'];
+                //
+                $basic = Users::username2basic($lastMsg['username']);
+                $body['userid'] = $basic ? $basic['userid'] : 0;
+                $body['nickname'] = $basic ? $basic['nickname'] : ($body['nickname'] || '');
+                $body['userimg'] = $basic ? $basic['userimg'] : ($body['userimg'] || '');
+                //
+                $server->push($fd, Chat::formatMsgSend([
+                    'messageType' => 'user',
+                    'contentId' => $lastMsg['id'],
+                    'channel' => $channel,
+                    'username' => $lastMsg['username'],
+                    'target' => $lastMsg['receive'],
+                    'body' => $body,
+                    'time' => $lastMsg['indate'],
+                ]));
+            }
+        }
+    }
+
+    /**
+     * 收到消息时触发
+     * @param Server $server
+     * @param Frame $frame
+     */
+    public function onMessage(Server $server, Frame $frame)
+    {
+        global $_A;
+        $_A = [
+            '__static_langdata' => [],
+        ];
+        //
+        $data = Chat::formatMsgReceive($frame->data);
+        $back = [
+            'status' => 1,
+            'message' => '',
+        ];
+        //
+        switch ($data['messageType']) {
+            /**
+             * APP激活进入前台
+             */
+            case 'appActivity':
+                Cache::forever("ws::immediatelyNotify-" . $data['username'], "no");
+                break;
+
+            /**
+             * 刷新
+             */
+            case 'refresh':
+                DB::table('ws')->where([
+                    'fd' => $frame->fd,
+                    'channel' => $data['channel'],
+                ])->update(['update' => time()]);
+                break;
+
+            /**
+             * 总未读消息数
+             */
+            case 'unread':
+                $username = $this->getUsername($frame->fd, $data['channel']);
+                if ($username) {
+                    $num = intval(DB::table('chat_dialog')->where('user1', $username)->sum('unread1'));
+                    $num+= intval(DB::table('chat_dialog')->where('user2', $username)->sum('unread2'));
+                    $back['message'] = $num;
+                } else {
+                    $back['message'] = 0;
+                }
+                break;
+
+            /**
+             * 已读会员消息
+             */
+            case 'read':
+                $username = $this->getUsername($frame->fd, $data['channel']);
+                $dialog = Chat::openDialog($username, $data['target']);
+                if (!Base::isError($dialog)) {
+                    $dialog = $dialog['data'];
+                    $upArray = [];
+                    if ($dialog['user1'] == $dialog['user2']) {
+                        $upArray['unread1'] = 0;
+                        $upArray['unread2'] = 0;
+                    } else {
+                        $upArray[($dialog['recField'] == 1 ? 'unread2' : 'unread1')] = 0;
+                    }
+                    DB::table('chat_dialog')->where('id', $dialog['id'])->update($upArray);
+                }
+                $chromeExtendTask = new ChromeExtendTask($username);
+                Task::deliver($chromeExtendTask);
+                break;
+
+            /**
+             * 收到信息回执
+             */
+            case 'roger':
+                $contentIds = Base::explodeInt(',', $data['contentId']);
+                if ($contentIds) {
+                    $username = $this->getUsername($frame->fd, $data['channel']);
+                    if ($username) {
+                        DB::table('chat_msg')->where('receive', $username)->whereIn('id', $contentIds)->update([
+                            'roger' => 1,
+                        ]);
+                    }
+                }
+                break;
+
+            /**
+             * 发给用户
+             */
+            case 'user':
+                $username = $this->getUsername($frame->fd, $data['channel']);
+                $res = Chat::saveMessage($username, $data['target'], $data['body']);
+                if (Base::isError($res)) {
+                    $back = [
+                        'status' => 0,
+                        'message' => $res['msg'],
+                    ];
+                } else {
+                    $resData = $res['data'];
+                    $back['message'] = $resData['id'];
+                    $data['contentId'] = $resData['id'];
+                    $data['body']['id'] = $resData['id'];
+                    $data['body']['unread'] = $resData['unread'];
+                    //
+                    $basic = Users::username2basic($username);
+                    $data['body']['userid'] = $basic ? $basic['userid'] : 0;
+                    $data['body']['nickname'] = $basic ? $basic['nickname'] : ($data['body']['nickname'] || '');
+                    $data['body']['userimg'] = $basic ? $basic['userimg'] : ($data['body']['userimg'] || '');
+                    //
+                    $pushLists = [];
+                    foreach ($this->getUserOfName($data['target']) AS $item) {
+                        $pushLists[] = [
+                            'fd' => $item['fd'],
+                            'msg' => $data
+                        ];
+                    }
+                    $pushTask = new PushTask($pushLists);
+                    Task::deliver($pushTask);
+                    //
+                    $notificationTask = new NotificationTask($resData['id']);
+                    $notificationTask->delay(Cache::get("ws::immediatelyNotify-" . $data['target']) == "yes" ? 2 : 10);
+                    Task::deliver($notificationTask);
+                }
+                break;
+
+            /**
+             * 发给用户(不保存记录)
+             */
+            case 'info':
+                $pushLists = [];
+                foreach ($this->getUserOfName($data['target']) AS $item) {
+                    $pushLists[] = [
+                        'fd' => $item['fd'],
+                        'msg' => $data
+                    ];
+                }
+                $pushTask = new PushTask($pushLists);
+                Task::deliver($pushTask);
+                break;
+
+            /**
+             * 发给整个团队
+             */
+            case 'team':
+                if ($data['body']['type'] === 'taskA') {
+                    $taskId = intval(Base::val($data['body'], 'taskDetail.id'));
+                    if ($taskId > 0) {
+                        $userLists = Chat::getTaskUsers($taskId);
+                    } else {
+                        $userLists = $this->getTeamUsers();
+                    }
+                    //
+                    $pushLists = [];
+                    foreach ($userLists as $user) {
+                        $data['messageType'] = 'user';
+                        $data['target'] = $user['username'];
+                        $pushLists[] = [
+                            'fd' => $user['fd'],
+                            'msg' => $data
+                        ];
+                    }
+                    $pushTask = new PushTask($pushLists);
+                    Task::deliver($pushTask);
+                }
+                break;
+
+            /**
+             * 知识库协作
+             */
+            case 'docs':
+                $back['message'] = [];
+                $body = $data['body'];
+                $type = $body['type'];
+                $sid = intval($body['sid']);
+                if ($sid <= 0) {
+                    return;
+                }
+                $array = Base::json2array(Cache::get("docs::" . $sid));
+                if ($array) {
+                    foreach ($array as $uname => $vbody) {
+                        if (intval($vbody['indate']) + 20 < time()) {
+                            unset($array[$uname]);
+                        }
+                    }
+                }
+                if ($type == 'enter' || $type == 'refresh') {
+                    $array[$body['username']] = $body;
+                } elseif ($type == 'quit') {
+                    unset($array[$body['username']]);
+                }
+                //
+                Cache::put("docs::" . $sid, Base::array2json($array), 30);
+                if ($array) {
+                    ksort($array);
+                }
+                $back['message'] = array_values($array);
+                //
+                if ($type == 'enter' || $type == 'quit') {
+                    $pushLists = [];
+                    foreach ($back['message'] AS $tuser) {
+                        foreach ($this->getUserOfName($tuser['username']) AS $item) {
+                            $pushLists[] = [
+                                'fd' => $item['fd'],
+                                'msg' => [
+                                    'messageType' => 'docs',
+                                    'body' => [
+                                        'type' => 'users',
+                                        'sid' => $sid,
+                                        'lists' => $back['message']
+                                    ]
+                                ]
+                            ];
+                        }
+                    }
+                    $pushTask = new PushTask($pushLists);
+                    Task::deliver($pushTask);
+                }
+                break;
+        }
+        if ($data['messageId']) {
+            $pushLists = [];
+            $pushLists[] = [
+                'fd' => $frame->fd,
+                'msg' => [
+                    'messageType' => 'back',
+                    'messageId' => $data['messageId'],
+                    'body' => $back,
+                ]
+            ];
+            $pushTask = new PushTask($pushLists);
+            Task::deliver($pushTask);
+        }
+    }
+
+    /**
+     * 关闭连接时触发
+     * @param Server $server
+     * @param $fd
+     * @param $reactorId
+     */
+    public function onClose(Server $server, $fd, $reactorId)
+    {
+        $this->deleteUser($fd);
+    }
+
+    /** ****************************************************************************** */
+    /** ****************************************************************************** */
+    /** ****************************************************************************** */
+
+    /**
+     * 保存用户
+     * @param $fd
+     * @param $channel
+     * @param $username
+     */
+    private function saveUser($fd, $channel, $username)
+    {
+        try {
+            DB::transaction(function () use ($username, $channel, $fd) {
+                $this->deleteUser($fd);
+                DB::table('ws')->updateOrInsert([
+                    'key' => md5($fd . '@' . $channel . '@' . $username)
+                ], [
+                    'fd' => $fd,
+                    'username' => $username,
+                    'channel' => $channel,
+                    'update' => time()
+                ]);
+            });
+        } catch (\Throwable $e) {
+
+        }
+    }
+
+    /**
+     * 清除用户
+     * @param $fd
+     */
+    private function deleteUser($fd)
+    {
+        DB::table('ws')->where('fd', $fd)->delete();
+    }
+
+    /**
+     * 获取用户
+     * @param string $fd
+     * @param string $channel
+     * @param string $username
+     * @return array
+     */
+    private function getUser($fd  = '', $channel = '', $username = '')
+    {
+        $array = [];
+        if ($fd) $array['fd'] = $fd;
+        if ($channel) $array['channel'] = $channel;
+        if ($username) $array['username'] = $username;
+        if (empty($array)) {
+            return [];
+        }
+        return Base::DBC2A(DB::table('ws')->select(['fd', 'username', 'channel'])->where($array)->get());
+    }
+
+    private function getUserOfFd($fd, $channel = '') {
+        return $this->getUser($fd, $channel);
+    }
+
+    private function getUserOfName($username, $channel = '') {
+        return $this->getUser('', $channel, $username);
+    }
+
+    private function getUsername($fd, $channel) {
+        return DB::table('ws')->where(['fd' => $fd, 'channel' => $channel ])->value('username');
+    }
+
+    /**
+     * 获取团队所有在线用户
+     * @return array|string
+     */
+    private function getTeamUsers()
+    {
+        return Base::DBC2A(DB::table('ws')->select(['fd', 'username', 'channel'])->where([
+            ['update', '>', time() - 600],
+        ])->get());
+    }
+}

+ 30 - 0
app/SubTask.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+class SubTask extends Model
+{
+    /**
+     * 与模型关联的数据表.
+     *
+     * @var string
+     */
+    protected $table = 'project_sub_task';
+
+    /**
+     * 指示模型是否主动维护时间戳。
+     *
+     * @var bool
+     */
+    public $timestamps = false;
+
+    /**
+     * 获取这条子任务所属的任务。
+     */
+    public function task()
+    {
+        return $this->belongsTo(Task::class);
+    }
+}

+ 30 - 0
app/Task.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Task extends Model
+{
+    /**
+     * 与模型关联的数据表.
+     *
+     * @var string
+     */
+    protected $table = 'project_task';
+
+    /**
+     * 指示模型是否主动维护时间戳。
+     *
+     * @var bool
+     */
+    public $timestamps = false;
+
+    /**
+     * 获取当前任务的子任务
+     */
+    public function subtask()
+    {
+        return $this->hasMany(SubTask::class,'taskid');
+    }
+}

+ 102 - 0
app/Tasks/AutoArchivedTask.php

@@ -0,0 +1,102 @@
+<?php
+namespace App\Tasks;
+
+@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
+
+use App\Module\Base;
+use App\Module\Chat;
+use DB;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+
+/**
+ * 完成的任务自动归档
+ * Class AutoArchivedTask
+ * @package App\Tasks
+ */
+class AutoArchivedTask extends Task
+{
+
+    public function __construct()
+    {
+        //
+    }
+
+    public function handle()
+    {
+        $setting = Base::setting('system');
+        if ($setting['autoArchived'] === 'open') {
+            $archivedDay = intval($setting['archivedDay']);
+            if ($archivedDay > 0) {
+                $time = time();
+                $archivedDay = min(100, $archivedDay);
+                $archivedTime = $time - ($archivedDay * 86400);
+                //获取已完成未归档的任务
+                DB::transaction(function () use ($time, $archivedTime) {
+                    $taskLists = Base::DBC2A(DB::table('project_task')->where([
+                        ['delete', '=', 0],
+                        ['archiveddate', '=', 0],
+                        ['complete', '=', 1],
+                        ['completedate', '<=', $archivedTime],
+                    ])->take(100)->get());
+                    if ($taskLists) {
+                        $idArray = [];
+                        $logArray = [];
+                        $pushLists = [];
+                        $upArray = [
+                            'archived' => 1,
+                            'archiveddate' => $time,
+                        ];
+                        foreach ($taskLists AS $taskDetail) {
+                            $idArray[] = $taskDetail['id'];
+                            $logArray[] = [
+                                'type' => '日志',
+                                'projectid' => $taskDetail['projectid'],
+                                'taskid' => $taskDetail['id'],
+                                'username' => $taskDetail['username'],
+                                'detail' => '任务归档【自动】',
+                                'indate' => $time,
+                                'other' => Base::array2string([
+                                    'type' => 'task',
+                                    'id' => $taskDetail['id'],
+                                    'title' => $taskDetail['title'],
+                                ])
+                            ];
+                            $userLists = Chat::getTaskUsers($taskDetail['id']);
+                            if ($userLists) {
+                                foreach ($userLists as $user) {
+                                    $pushLists[] = [
+                                        'fd' => $user['fd'],
+                                        'msg' => [
+                                            'messageType' => 'user',
+                                            'username' => '::system',
+                                            'target' => $user['username'],
+                                            'time' => $time,
+                                            'body' => [
+                                                'act' => 'archived',
+                                                'type' => 'taskA',
+                                                'taskDetail' => array_merge($taskDetail, $upArray),
+                                            ]
+                                        ]
+                                    ];
+                                }
+                            }
+                        }
+                        if ($idArray) {
+                            DB::table('project_task')->whereIn('id', $idArray)->where([
+                                ['archiveddate', '=', 0],
+                                ['complete', '=', 1],
+                            ])->update($upArray);
+                        }
+                        if ($logArray) {
+                            DB::table('project_log')->insert($logArray);
+                        }
+                        if ($pushLists) {
+                            $pushTask = new PushTask($pushLists);
+                            Task::deliver($pushTask);
+                        }
+                    }
+                });
+            }
+        }
+    }
+}

+ 47 - 0
app/Tasks/ChromeExtendTask.php

@@ -0,0 +1,47 @@
+<?php
+namespace App\Tasks;
+
+@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
+
+use App\Module\Base;
+use App\Module\Chat;
+use DB;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+
+class ChromeExtendTask extends Task
+{
+    private $username;
+
+    /**
+     * ChromeExtendTask constructor.
+     * @param $username
+     */
+    public function __construct($username)
+    {
+        $this->username = $username;
+    }
+
+    public function handle()
+    {
+        $lists = Base::DBC2A(DB::table('ws')->select(['fd', 'username', 'channel'])->where([
+            'username' => $this->username,
+            'channel' => 'chromeExtend',
+        ])->where([
+            ['update', '>', time() - 600],
+        ])->get());
+        if (count($lists) > 0) {
+            $unread = intval(DB::table('chat_dialog')->where('user1', $this->username)->sum('unread1'));
+            $unread+= intval(DB::table('chat_dialog')->where('user2', $this->username)->sum('unread2'));
+            //
+            $swoole = app('swoole');
+            foreach ($lists AS $item) {
+                $swoole->push($item['fd'], Chat::formatMsgSend([
+                    'messageType' => 'unread',
+                    'body' => [
+                        'unread' => $unread
+                    ],
+                ]));
+            }
+        }
+    }
+}

+ 50 - 0
app/Tasks/NotificationTask.php

@@ -0,0 +1,50 @@
+<?php
+namespace App\Tasks;
+
+@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
+
+use App\Module\Base;
+use App\Module\Chat;
+use App\Module\Umeng;
+use App\Module\Users;
+use Cache;
+use DB;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+
+class NotificationTask extends Task
+{
+    private $contentId;
+
+    /**
+     * NotificationTask constructor.
+     * @param int $contentId
+     */
+    public function __construct($contentId)
+    {
+        $this->contentId = intval($contentId);
+    }
+
+    public function handle()
+    {
+        $row = Base::DBC2A(DB::table('chat_msg')->where('id', $this->contentId)->first());
+        if (empty($row)) {
+            return;
+        }
+        if ($row['roger']) {
+            return;
+        }
+        //
+        $receive = $row['receive'];
+        $username = $row['username'];
+        $message = Base::string2array($row['message']);
+        $lists = Base::DBC2A(DB::table('umeng')->where('username', $receive)->get());
+        foreach ($lists AS $item) {
+            Umeng::notification($item['platform'], $item['token'], Users::nickname($username), Chat::messageDesc($message), [
+                'notifyType' => 'userMsg',
+                'contentId' => $this->contentId,
+                'username' => $username,
+            ]);
+            Cache::forever("ws::immediatelyNotify-" . $receive, "yes");
+        }
+    }
+}

+ 27 - 0
app/Tasks/PushTask.php

@@ -0,0 +1,27 @@
+<?php
+namespace App\Tasks;
+
+use App\Module\Chat;
+use Hhxsv5\LaravelS\Swoole\Task\Task;
+
+class PushTask extends Task
+{
+    private $lists;
+
+    /**
+     * PushTask constructor.
+     * @param array $lists      [fd, msg]
+     */
+    public function __construct($lists)
+    {
+        $this->lists = $lists;
+    }
+
+    public function handle()
+    {
+        $swoole = app('swoole');
+        foreach ($this->lists AS $item) {
+            $swoole->push($item['fd'], Chat::formatMsgSend($item['msg']));
+        }
+    }
+}

+ 39 - 0
app/User.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App;
+
+use Illuminate\Contracts\Auth\MustVerifyEmail;
+use Illuminate\Foundation\Auth\User as Authenticatable;
+use Illuminate\Notifications\Notifiable;
+
+class User extends Authenticatable
+{
+    use Notifiable;
+
+    /**
+     * The attributes that are mass assignable.
+     *
+     * @var array
+     */
+    protected $fillable = [
+        'name', 'email', 'password',
+    ];
+
+    /**
+     * The attributes that should be hidden for arrays.
+     *
+     * @var array
+     */
+    protected $hidden = [
+        'password', 'remember_token',
+    ];
+
+    /**
+     * The attributes that should be cast to native types.
+     *
+     * @var array
+     */
+    protected $casts = [
+        'email_verified_at' => 'datetime',
+    ];
+}

+ 53 - 0
artisan

@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+<?php
+
+define('LARAVEL_START', microtime(true));
+
+/*
+|--------------------------------------------------------------------------
+| Register The Auto Loader
+|--------------------------------------------------------------------------
+|
+| Composer provides a convenient, automatically generated class loader
+| for our application. We just need to utilize it! We'll require it
+| into the script here so that we do not have to worry about the
+| loading of any our classes "manually". Feels great to relax.
+|
+*/
+
+require __DIR__.'/vendor/autoload.php';
+
+$app = require_once __DIR__.'/bootstrap/app.php';
+
+/*
+|--------------------------------------------------------------------------
+| Run The Artisan Application
+|--------------------------------------------------------------------------
+|
+| When we run the console application, the current CLI command will be
+| executed in this console and the response sent back to a terminal
+| or another output device for the developers. Here goes nothing!
+|
+*/
+
+$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
+
+$status = $kernel->handle(
+    $input = new Symfony\Component\Console\Input\ArgvInput,
+    new Symfony\Component\Console\Output\ConsoleOutput
+);
+
+/*
+|--------------------------------------------------------------------------
+| Shutdown The Application
+|--------------------------------------------------------------------------
+|
+| Once Artisan has finished running, we will fire off the shutdown events
+| so that any final work may be done by the application before we shut
+| down the process. This is the last thing to happen to the request.
+|
+*/
+
+$kernel->terminate($input, $status);
+
+exit($status);

+ 97 - 0
assets/js/_components/ScrollerY.vue

@@ -0,0 +1,97 @@
+<template>
+    <div ref="scrollerView" class="app-scroller" :class="[static ? 'app-scroller-static' : '']">
+        <slot/>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+    .app-scroller {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        overflow-x: hidden;
+        overflow-y: auto;
+        -webkit-overflow-scrolling: touch;
+    }
+
+    .app-scroller-static {
+        position: static;
+        flex: 1;
+    }
+</style>
+<script>
+    export default {
+        name: 'ScrollerY',
+        props: {
+            static: {
+                type: Boolean,
+                default: false
+            },
+        },
+        data() {
+            return {
+                scrollY: 0,
+                scrollDiff: 0,
+                scrollInfo: {},
+            }
+        },
+        mounted() {
+            this.$nextTick(() => {
+                let scrollListener = typeof this.$listeners['on-scroll'] === "function";
+                let scrollerView = $A(this.$refs.scrollerView);
+                scrollerView.scroll(() => {
+                    let wInnerH = Math.round(scrollerView.innerHeight());
+                    let wScrollY = scrollerView.scrollTop();
+                    let bScrollH = this.$refs.scrollerView.scrollHeight;
+                    this.scrollY = wScrollY;
+                    if (scrollListener) {
+                        let direction = 'static';
+                        let directionreal = 'static';
+                        if (this.scrollDiff - wScrollY > 50) {
+                            this.scrollDiff = wScrollY;
+                            direction = 'down';
+                        } else if (this.scrollDiff - wScrollY < -100) {
+                            this.scrollDiff = wScrollY;
+                            direction = 'up';
+                        }
+                        if (this.scrollDiff - wScrollY > 1) {
+                            this.scrollDiff = wScrollY;
+                            directionreal = 'down';
+                        } else if (this.scrollDiff - wScrollY < -1) {
+                            this.scrollDiff = wScrollY;
+                            directionreal = 'up';
+                        }
+                        this.$emit('on-scroll', {
+                            scale: wScrollY / (bScrollH - wInnerH),     //已滚动比例
+                            scrollY: wScrollY,                          //滚动的距离
+                            scrollE: bScrollH - wInnerH - wScrollY,     //与底部距离
+                            direction: direction,                       //滚动方向
+                            directionreal: directionreal,               //滚动方向(即时)
+                        });
+                    }
+                });
+            });
+        },
+        activated() {
+            if (this.scrollY > 0) {
+                this.$nextTick(() => {
+                    this.scrollTo(this.scrollY);
+                });
+            }
+        },
+        methods: {
+            scrollTo(top, animate) {
+                if (animate === false) {
+                    $A(this.$refs.scrollerView).stop().scrollTop(top);
+                } else {
+                    $A(this.$refs.scrollerView).stop().animate({"scrollTop": top});
+                }
+            },
+            scrollToBottom(animate) {
+                this.scrollTo(this.$refs.scrollerView.scrollHeight, animate);
+            }
+        }
+    }
+</script>

+ 49 - 0
assets/js/_components/Title.vue

@@ -0,0 +1,49 @@
+<template>
+    <h1 v-if="false"><slot> </slot></h1>
+</template>
+
+<script>
+    export default {
+        name: 'v-title',
+        data() {
+            return {
+            }
+        },
+        mounted () {
+            this.updateTitle()
+        },
+        beforeUpdate () {
+            this.updateTitle()
+        },
+        activated() {
+            this.updateTitle()
+        },
+        methods: {
+            updateTitle () {
+                let slots = this.$slots.default;
+                if (typeof slots === 'undefined' || slots.length < 1 || typeof slots[0].text !== 'string') {
+                    return;
+                }
+                let {text} = slots[0];
+                let {title} = document;
+                if (text !== title) this.setTile(text);
+            },
+            setTile(title) {
+                document.title = title;
+                let mobile = navigator.userAgent.toLowerCase();
+                if (/iphone|ipad|ipod/.test(mobile)) {
+                    let iframe = document.createElement('iframe');
+                    iframe.style.display = 'none';
+                    let iframeCallback = function () {
+                        setTimeout(function () {
+                            iframe.removeEventListener('load', iframeCallback);
+                            document.body.removeChild(iframe)
+                        }, 0)
+                    };
+                    iframe.addEventListener('load', iframeCallback);
+                    document.body.appendChild(iframe)
+                }
+            }
+        }
+    }
+</script>

+ 114 - 0
assets/js/_components/scrollerX.vue

@@ -0,0 +1,114 @@
+<template>
+    <div class="scroller-main" :class="['scroller-' + status, (effect === false ? 'scroller-uneffect' : '')]">
+        <div class="scroller-x" ref="scrollerx">
+            <slot></slot>
+        </div>
+    </div>
+</template>
+
+<script>
+    export default {
+        name: 'ScrollerX',
+
+        props: ['effect'],
+
+        data() {
+            return {
+                scrollX: 0,
+
+                status: 'start',
+
+                box: null,
+            };
+        },
+
+        activated() {
+            if (this.scrollX > 0) {
+                this.$nextTick(() => {
+                    $A(this.$refs.scrollerx).scrollLeft(this.scrollX);
+                });
+            }
+        },
+
+        mounted() {
+            this.$nextTick(() => {
+                this.box = this.$refs.scrollerx;
+                this.box.addEventListener('scroll', () => {
+                    this.scrollX = this.box.scrollLeft;
+                    if (this.box.scrollLeft > 0) {
+                        if (this.box.scrollWidth == this.box.clientWidth + this.box.scrollLeft) {
+                            this.status = 'end';
+                        } else {
+                            this.status = 'center';
+                        }
+                    } else {
+                        if (this.box.scrollWidth > this.box.clientWidth) {
+                            this.status = 'start';
+                        } else {
+                            this.status = '';
+                        }
+                    }
+                }, false);
+            });
+        }
+    }
+</script>
+
+<style lang="scss" scoped>
+    .scroller-main {
+        position: relative;
+
+        .scroller-x {
+            display: flex;
+            width: 100%;
+            flex-wrap: nowrap;
+            justify-content: flex-start;
+            align-items: center;
+            overflow-x: auto;
+            overflow-y: hidden;
+            position: relative;
+            -webkit-overflow-scrolling: touch;
+
+            > div,
+            > span {
+                display: block;
+                flex-grow: 1;
+                flex-shrink: 0;
+                flex-basis: auto;
+            }
+        }
+    }
+
+    .scroller-center:before,
+    .scroller-end:before {
+        position: absolute;
+        left: 0;
+        top: 0;
+        bottom: 0;
+        width: 64px;
+        content: "";
+        z-index: 1;
+        background: linear-gradient(to right, #ffffff, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0));
+        pointer-events: none
+    }
+
+    .scroller-start:after,
+    .scroller-center:after {
+        position: absolute;
+        right: 0;
+        top: 0;
+        bottom: 0;
+        width: 64px;
+        content: "";
+        z-index: 1;
+        background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.8), #ffffff);
+        pointer-events: none
+    }
+
+    .scroller-uneffect {
+        &:before,
+        &:after {
+            display: none;
+        }
+    }
+</style>

+ 42 - 0
assets/js/_components/sreachTitle.vue

@@ -0,0 +1,42 @@
+<template>
+    <div :class="[count(val) > 0 ? 'item-title-active' : 'item-title']"><slot> </slot></div>
+</template>
+
+<script>
+    export default {
+        name: 'sreach-title',
+        props: {
+            val: { },
+        },
+        methods: {
+            count(obj) {
+                try {
+                    if (typeof obj === "undefined") {
+                        return 0;
+                    }
+                    if (typeof obj === "number" || obj instanceof Date) {
+                        obj+= "";
+                    }
+                    if (typeof obj.length === 'number') {
+                        if (typeof obj === 'object') {
+                            let i = 0
+                            $A.each(obj, (key, val) => {
+                                if (this.count(val) > 0) i++;
+                            });
+                            return i;
+                        }
+                        return obj.length;
+                    } else {
+                        let i = 0, key;
+                        for (key in obj) {
+                            if (this.count(obj) > 0) i++;
+                        }
+                        return i;
+                    }
+                }catch (e) {
+                    return 0;
+                }
+            },
+        }
+    }
+</script>

+ 21 - 0
assets/js/_modules/directives/clickoutside.js

@@ -0,0 +1,21 @@
+export default {
+    bind (el, binding, vnode) {
+        function documentHandler (e) {
+            if (el.contains(e.target)) {
+                return false;
+            }
+            if (binding.expression) {
+                binding.value(e);
+            }
+        }
+        el.__vueClickOutside__ = documentHandler;
+        document.addEventListener('click', documentHandler);
+    },
+    update () {
+
+    },
+    unbind (el, binding) {
+        document.removeEventListener('click', el.__vueClickOutside__);
+        delete el.__vueClickOutside__;
+    }
+};

+ 108 - 0
assets/js/_modules/directives/popper-novalue.js

@@ -0,0 +1,108 @@
+/**
+ * https://github.com/freeze-component/vue-popper
+ * */
+import Vue from 'vue';
+const isServer = Vue.prototype.$isServer;
+const Popper = isServer ? function() {} : require('popper.js/dist/umd/popper.js');  // eslint-disable-line
+
+export default {
+    props: {
+        placement: {
+            type: String,
+            default: 'bottom'
+        },
+        boundariesPadding: {
+            type: Number,
+            default: 5
+        },
+        reference: Object,
+        popper: Object,
+        offset: {
+            default: 0
+        },
+        transition: String,
+        options: {
+            type: Object,
+            default () {
+                return {
+                    modifiers: {
+                        computeStyle:{
+                            gpuAcceleration: false,
+                        },
+                        preventOverflow :{
+                            boundariesElement: 'window'
+                        }
+                    }
+                };
+            }
+        }
+    },
+    data () {
+        return {
+            visible: false
+        };
+    },
+    watch: {
+        visible(val) {
+            if (val) {
+                if (this.handleIndexIncrease) this.handleIndexIncrease();  // just use for Poptip
+                this.updatePopper();
+                this.$emit('on-popper-show');
+            } else {
+                this.$emit('on-popper-hide');
+            }
+        }
+    },
+    methods: {
+        createPopper() {
+            if (isServer) return;
+            if (!/^(top|bottom|left|right)(-start|-end)?$/g.test(this.placement)) {
+                return;
+            }
+
+            const options = this.options;
+            const popper = this.popper || this.$refs.popper;
+            const reference = this.reference || this.$refs.reference;
+
+            if (!popper || !reference) return;
+
+            if (this.popperJS && this.popperJS.hasOwnProperty('destroy')) {
+                this.popperJS.destroy();
+            }
+
+            options.placement = this.placement;
+
+            if (!options.modifiers.offset) {
+                options.modifiers.offset = {};
+            }
+            options.modifiers.offset.offset = this.offset;
+            options.onCreate =()=>{
+                this.$nextTick(this.updatePopper);
+                this.$emit('created', this);
+            };
+
+            this.popperJS = new Popper(reference, popper, options);
+
+        },
+        updatePopper() {
+            if (isServer) return;
+            this.popperJS ? this.popperJS.update() : this.createPopper();
+        },
+        doDestroy() {
+            if (isServer) return;
+            if (this.visible) return;
+            this.popperJS.destroy();
+            this.popperJS = null;
+        }
+    },
+    updated (){
+        this.$nextTick(()=>this.updatePopper());
+
+    },
+    beforeDestroy() {
+        if (isServer) return;
+        if (this.popperJS) {
+            this.popperJS.destroy();
+        }
+    }
+};

+ 77 - 0
assets/js/_modules/directives/transfer-dom.js

@@ -0,0 +1,77 @@
+// Thanks to: https://github.com/airyland/vux/blob/v2/src/directives/transfer-dom/index.js
+// Thanks to: https://github.com/calebroseland/vue-dom-portal
+
+/**
+ * Get target DOM Node
+ * @param {(Node|string|Boolean)} [node=document.body] DOM Node, CSS selector, or Boolean
+ * @return {Node} The target that the el will be appended to
+ */
+function getTarget (node) {
+    if (node === void 0) {
+        node = document.body
+    }
+    if (node === true) { return document.body }
+    return node instanceof window.Node ? node : document.querySelector(node)
+}
+
+const directive = {
+    inserted (el, { value }, vnode) {
+        if ( el.dataset && el.dataset.transfer !== 'true') return false;
+        el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom';
+        const parentNode = el.parentNode;
+        if (!parentNode) return;
+        const home = document.createComment('');
+        let hasMovedOut = false;
+
+        if (value !== false) {
+            parentNode.replaceChild(home, el); // moving out, el is no longer in the document
+            getTarget(value).appendChild(el); // moving into new place
+            hasMovedOut = true
+        }
+        if (!el.__transferDomData) {
+            el.__transferDomData = {
+                parentNode: parentNode,
+                home: home,
+                target: getTarget(value),
+                hasMovedOut: hasMovedOut
+            }
+        }
+    },
+    componentUpdated (el, { value }) {
+        if ( el.dataset && el.dataset.transfer !== 'true') return false;
+        // need to make sure children are done updating (vs. `update`)
+        const ref$1 = el.__transferDomData;
+        if (!ref$1) return;
+        // homes.get(el)
+        const parentNode = ref$1.parentNode;
+        const home = ref$1.home;
+        const hasMovedOut = ref$1.hasMovedOut; // recall where home is
+
+        if (!hasMovedOut && value) {
+            // remove from document and leave placeholder
+            parentNode.replaceChild(home, el);
+            // append to target
+            getTarget(value).appendChild(el);
+            el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: true, target: getTarget(value) });
+        } else if (hasMovedOut && value === false) {
+            // previously moved, coming back home
+            parentNode.replaceChild(el, home);
+            el.__transferDomData = Object.assign({}, el.__transferDomData, { hasMovedOut: false, target: getTarget(value) });
+        } else if (value) {
+            // already moved, going somewhere else
+            getTarget(value).appendChild(el);
+        }
+    },
+    unbind (el) {
+        if (el.dataset && el.dataset.transfer !== 'true') return false;
+        el.className = el.className.replace('v-transfer-dom', '');
+        const ref$1 = el.__transferDomData;
+        if (!ref$1) return;
+        if (el.__transferDomData.hasMovedOut === true) {
+            el.__transferDomData.parentNode && el.__transferDomData.parentNode.appendChild(el)
+        }
+        el.__transferDomData = null
+    }
+};
+
+export default directive;

+ 179 - 0
assets/js/_modules/language/index.js

@@ -0,0 +1,179 @@
+const languageListenerObjects = [];
+
+export default {
+    install(Vue) {
+        Vue.mixin({
+            data() {
+                return {
+                    languageInit: false,
+                    languageData: {},
+                    languageType: window.localStorage['__language:type__'] || 'zh',
+                }
+            },
+
+            watch: {
+                languageType: {
+                    handler(type) {
+                        if (type && typeof this.initLanguage === "function") {
+                            this.initLanguage();
+                        }
+                    },
+                    immediate: true
+                },
+            },
+
+            methods: {
+                /**
+                 * 初始化语言数据
+                 * @private
+                 */
+                __initLanguageData() {
+                    if (this.languageInit === false) {
+                        this.languageInit = true;
+                        //
+                        this.addLanguageData({
+                            en: require("../../../../lang/en/general.js").default,
+                            zh: require("../../../../lang/zh/general.js").default
+                        });
+                        //
+                        languageListenerObjects.push((lang) => {
+                            this.languageType = lang;
+                        });
+                    }
+                },
+
+                /**
+                 * 监听语言变化
+                 * @param callback
+                 */
+                setLanguageListener(callback) {
+                    if (typeof callback === 'function') {
+                        languageListenerObjects.push((lang) => {
+                            callback(lang);
+                        });
+                    }
+                },
+
+                /**
+                 * 语言包数据
+                 * @param language
+                 * @param data
+                 */
+                addLanguageData(language, data) {
+                    if (typeof language === 'object') {
+                        Object.keys(language).forEach((key) => {
+                            this.addLanguageData(key, language[key]);
+                        });
+                        return;
+                    }
+                    if (!language || typeof data !== "object") {
+                        return;
+                    }
+                    this.__initLanguageData();
+                    if (typeof this.languageData[language] === "undefined") {
+                        this.languageData[language] = {};
+                    }
+                    Object.assign(this.languageData[language], data);
+                    //
+                    if (language === 'en') {
+                        if (typeof this.languageData['zh'] === "undefined") {
+                            this.languageData['zh'] = {};
+                        }
+                        let cnData = {};
+                        for(let key in data) {
+                            if (data.hasOwnProperty(key) && typeof this.languageData['zh'][data[key]] === 'undefined') {
+                                cnData[data[key]] = key;
+                            }
+                        }
+                        Object.assign(this.languageData['zh'], cnData);
+                    }else if (language === 'zh') {
+                        if (typeof this.languageData['en'] === "undefined") {
+                            this.languageData['en'] = {};
+                        }
+                        let enData = {};
+                        for(let key in data) {
+                            if (data.hasOwnProperty(key) && typeof this.languageData['en'][data[key]] === 'undefined') {
+                                enData[data[key]] = key;
+                            }
+                        }
+                        Object.assign(this.languageData['en'], enData);
+                    }
+                },
+
+                /**
+                 * 变化语言
+                 * @param language
+                 */
+                setLanguage(language) {
+                    this.__initLanguageData();
+                    window.localStorage['__language:type__'] = language;
+                    languageListenerObjects.forEach((call) => {
+                        if (typeof call === 'function') {
+                            call(language);
+                        }
+                    });
+                },
+
+                /**
+                 * 获取语言
+                 * @returns {*}
+                 */
+                getLanguage() {
+                    this.__initLanguageData();
+                    return this.languageType;
+                },
+
+                /**
+                 * 替换%遍历
+                 * @param text
+                 * @param objects
+                 */
+                replaceArgumentsLanguage(text, objects) {
+                    let j = 1;
+                    while (text.indexOf("%") !== -1) {
+                        if (typeof objects[j] === "object") {
+                            text = text.replace("%", "");
+                        } else {
+                            text = text.replace("%", objects[j]);
+                        }
+                        j++;
+                    }
+                    return text;
+                },
+
+                /**
+                 * 显示语言
+                 * @return {string}
+                 */
+                $L(text) {
+                    if (text) {
+                        this.__initLanguageData();
+                        //
+                        if (typeof this.languageData[this.languageType] === "object") {
+                            let temp = this.languageData[this.languageType][text];
+                            if (temp === null) {
+                                return this.replaceArgumentsLanguage(text, arguments);
+                            }
+                            if (typeof temp !== 'undefined') {
+                                return this.replaceArgumentsLanguage(temp, arguments);
+                            }
+                        }
+                        //
+                        try {
+                            let key = '__language:Undefined__';
+                            let tmpData = JSON.parse(window.localStorage[key] || '{}');
+                            if (typeof tmpData[this.languageType] !== "object") {
+                                tmpData[this.languageType] = {};
+                            }
+                            tmpData[this.languageType][text] = "";
+                            window.localStorage[key] = JSON.stringify(tmpData);
+                        }catch (e) {
+                            //
+                        }
+                    }
+                    return this.replaceArgumentsLanguage(text, arguments);
+                }
+            }
+        });
+    }
+}

+ 52 - 0
assets/js/_modules/mixins/index.js

@@ -0,0 +1,52 @@
+export default {
+    install(Vue) {
+        Vue.mixin({
+            data() {
+                return {
+                    mixinId: 0,
+                    //用户信息
+                    usrLogin: false,
+                    usrInfo: {},
+                    usrName: '',
+                    //浏览器宽度≤768返回true
+                    windowMax768: window.innerWidth <= 768,
+                }
+            },
+
+            mounted() {
+                if (typeof window.__mixinId != "number") window.__mixinId = 0;
+                this.mixinId = window.__mixinId++;
+                //
+                this.usrLogin = $A.getToken() !== false;
+                this.usrInfo = $A.getUserInfo();
+                this.usrName = this.usrInfo.username || '';
+                $A.setOnUserInfoListener('mixins_' + this.mixinId, (data, isLogin) => {
+                    this.usrLogin = isLogin;
+                    this.usrInfo = data;
+                    this.usrName = this.usrInfo.username || '';
+                });
+                //
+                window.addEventListener('resize', this.windowMax768Listener);
+            },
+
+            beforeDestroy() {
+                $A.removeUserInfoListener('mixins_' + this.mixinId);
+                window.removeEventListener('resize', this.windowMax768Listener);
+            },
+
+            methods: {
+                isArray(obj) {
+                    return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == '[object array]' && typeof obj.length == "number";
+                },
+
+                isJson(obj) {
+                    return typeof (obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]" && typeof obj.length == "undefined";
+                },
+
+                windowMax768Listener() {
+                    this.windowMax768 = window.innerWidth <= 768
+                }
+            }
+        });
+    }
+}

+ 1562 - 0
assets/js/common.js

@@ -0,0 +1,1562 @@
+/**
+ * 基础函数
+ */
+(function (window, $, undefined) {
+
+    let serverUrl = window.location.origin + '/';
+
+    /**
+     * =============================================================================
+     * **************************   基础函数类   **************************
+     * =============================================================================
+     */
+    $.extend({
+
+        /**
+         * 身份识别码
+         * @param text
+         * @returns {*|string}
+         */
+        token: function (text) {
+            let token = this.storage('token') || '';
+            if (typeof text === 'string') {
+                this.storage('token', text);
+                token = text;
+            }
+            return token;
+        },
+
+        /**
+         * 随机获取范围
+         * @param Min
+         * @param Max
+         * @returns {*}
+         */
+        randNum(Min,Max){
+            let Range = Max - Min;
+            let Rand = Math.random();
+            return Min + Math.round(Rand * Range); //四舍五入
+        },
+
+        /**
+         * 获取数组最后一个值
+         * @param array
+         * @returns {boolean}
+         */
+        last: function (array) {
+            let str = false;
+            if (typeof array === 'object' && array.length > 0) {
+                str = array[array.length - 1];
+            }
+            return str;
+        },
+
+
+        /**
+         * 字符串是否包含
+         * @param string
+         * @param find
+         * @param lower
+         * @returns {boolean}
+         */
+        strExists: function (string, find, lower = false) {
+            string += "";
+            find += "";
+            if (lower !== true) {
+                string = string.toLowerCase();
+                find = find.toLowerCase();
+            }
+            return (string.indexOf(find) !== -1);
+        },
+
+        /**
+         * 字符串是否左边包含
+         * @param string
+         * @param find
+         * @param lower
+         * @returns {boolean}
+         */
+        leftExists: function (string, find, lower = false) {
+            string += "";
+            find += "";
+            if (lower !== true) {
+                string = string.toLowerCase();
+                find = find.toLowerCase();
+            }
+            return (string.substring(0, find.length) === find);
+        },
+
+        /**
+         * 删除左边字符串
+         * @param string
+         * @param find
+         * @param lower
+         * @returns {string}
+         */
+        leftDelete: function (string, find, lower = false) {
+            string += "";
+            find += "";
+            if (this.leftExists(string, find, lower)) {
+                string = string.substring(find.length)
+            }
+            return string ? string : '';
+        },
+
+        /**
+         * 字符串是否右边包含
+         * @param string
+         * @param find
+         * @param lower
+         * @returns {boolean}
+         */
+        rightExists: function (string, find, lower = false) {
+            string += "";
+            find += "";
+            if (lower !== true) {
+                string = string.toLowerCase();
+                find = find.toLowerCase();
+            }
+            return (string.substring(string.length - find.length) === find);
+        },
+
+        /**
+         * 取字符串中间
+         * @param string
+         * @param start
+         * @param end
+         * @returns {*}
+         */
+        getMiddle: function (string, start, end) {
+            string = string.toString();
+            if (this.ishave(start) && this.strExists(string, start)) {
+                string = string.substring(string.indexOf(start) + start.length);
+            }
+            if (this.ishave(end) && this.strExists(string, end)) {
+                string = string.substring(0, string.indexOf(end));
+            }
+            return string;
+        },
+
+        /**
+         * 截取字符串
+         * @param string
+         * @param start
+         * @param end
+         * @returns {string}
+         */
+        subString: function(string, start, end) {
+            string += "";
+            if (!this.ishave(end)) {
+                end = string.length;
+            }
+            return string.substring(start, end);
+        },
+
+        /**
+         * 随机字符
+         * @param len
+         * @returns {string}
+         */
+        randomString: function (len) {
+            len = len || 32;
+            let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678oOLl9gqVvUuI1';
+            let maxPos = $chars.length;
+            let pwd = '';
+            for (let i = 0; i < len; i++) {
+                pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
+            }
+            return pwd;
+        },
+
+        /**
+         * 判断是否有
+         * @param set
+         * @returns {boolean}
+         */
+        ishave: function (set) {
+            return !!(set !== null && set !== "null" && set !== undefined && set !== "undefined" && set);
+        },
+
+        /**
+         * 相当于 intval
+         * @param str
+         * @param fixed
+         * @returns {number}
+         */
+        runNum: function (str, fixed) {
+            let _s = Number(str);
+            if (_s + "" === "NaN") {
+                _s = 0;
+            }
+            if (/^[0-9]*[1-9][0-9]*$/.test(fixed)) {
+                _s = _s.toFixed(fixed);
+                let rs = _s.indexOf('.');
+                if (rs < 0) {
+                    _s += ".";
+                    for (let i = 0; i < fixed; i++) {
+                        _s += "0";
+                    }
+                }
+            }
+            return _s;
+        },
+
+        /**
+         * 服务器地址
+         * @param str
+         * @returns {string}
+         */
+        serverUrl: function (str) {
+            if (str.substring(0, 2) === "//" ||
+                str.substring(0, 7) === "http://" ||
+                str.substring(0, 8) === "https://" ||
+                str.substring(0, 6) === "ftp://" ||
+                str.substring(0, 1) === "/") {
+                return str;
+            }
+            return serverUrl + str;
+        },
+
+        /**
+         * 获取IP地址详情
+         * @param ip
+         * @param callback
+         */
+        getIpInfo: function(ip, callback) {
+            if (!this.strExists(ip, ".")) {
+                return;
+            }
+            let keyName = '__ip' + ip.substring(0, 1) + '__';
+            let key = this.getMiddle(ip, '', '.');
+            let res = this.loadFromlLocal(key, ip, '', keyName);
+            if (typeof res == "object") {
+                if (typeof callback == "function") {
+                    callback(res);
+                }
+                return;
+            }
+            $A.ajax({
+                url: $A.serverUrl('api/system/get/ipinfo'),
+                data: { ip: ip },
+                timeout: 8000,
+                success: (res) => {
+                    this.savaToLocal(key, ip, res, keyName);
+                    if (typeof callback == "function") {
+                        callback(res);
+                    }
+                }
+            });
+        },
+
+        /**
+         * 新增&&获取缓存数据
+         * @param key
+         * @param value
+         * @returns {*}
+         */
+        storage: function(key, value) {
+            let keyName = 'app';
+            switch (window.location.pathname) {
+                case "/admin":
+                    keyName+= ":" + window.location.pathname.substr(1);
+                    break;
+            }
+            if (typeof value === 'undefined') {
+                return this.loadFromlLocal('__::', key, '', '__' + keyName + '__');
+            }else{
+                this.savaToLocal('__::', key, value, '__' + keyName + '__');
+            }
+        },
+
+        /**
+         *  新增&&修改本地缓存
+         *  @param {string} id 唯一id
+         *  @param {string} key 标示
+         *  @param value 新增&修改的值
+         *  @param keyName 主键名称
+         */
+        savaToLocal: function(id, key, value, keyName) {
+            try {
+                if (typeof keyName === 'undefined') keyName = '__seller__';
+                let seller = window.localStorage[keyName];
+                if (!seller) {
+                    seller = {};
+                    seller[id] = {};
+                } else {
+                    seller = JSON.parse(seller);
+                    if (!seller[id]) {
+                        seller[id] = {};
+                    }
+                }
+                seller[id][key] = value;
+                window.localStorage[keyName] = JSON.stringify(seller);
+            } catch(e) { }
+        },
+
+        /**
+         *  查询本地缓存
+         *  @param {string} id 唯一id
+         *  @param {string} key 标示
+         *  @param def 如果查询不到显示的值
+         *  @param keyName 主键名称
+         */
+        loadFromlLocal: function(id, key, def, keyName) {
+            if (typeof keyName === 'undefined') keyName = '__seller__';
+            let seller = window.localStorage[keyName];
+            if (!seller) {
+                return def;
+            }
+            seller = JSON.parse(seller)[id];
+            if (!seller) {
+                return def;
+            }
+            let ret = seller[key];
+            return ret || def;
+        },
+
+        /**
+         * 补零
+         * @param str
+         * @param length
+         * @param after
+         * @returns {*}
+         */
+        zeroFill: function(str, length, after) {
+            str+= "";
+            if (str.length >= length) {
+                return str;
+            }
+            let _str = '', _ret = '';
+            for (let i = 0; i < length; i++) {
+                _str += '0';
+            }
+            if (after || typeof after === 'undefined') {
+                _ret = (_str + "" + str).substr(length * -1);
+            } else {
+                _ret = (str + "" + _str).substr(0, length);
+            }
+            return _ret;
+        },
+
+        /**
+         * 时间戳转时间格式
+         * @param format
+         * @param v
+         * @returns {string}
+         */
+        formatDate: function(format, v) {
+            if (format === '') {
+                format = 'Y-m-d H:i:s';
+            }
+            let dateObj;
+            if (v instanceof Date) {
+                dateObj = v;
+            }else {
+                if (typeof v === 'undefined') {
+                    v = new Date().getTime();
+                }else if (/^(-)?\d{1,10}$/.test(v)) {
+                    v = v * 1000;
+                } else if (/^(-)?\d{1,13}$/.test(v)) {
+                    v = v * 1000;
+                } else if (/^(-)?\d{1,14}$/.test(v)) {
+                    v = v * 100;
+                } else if (/^(-)?\d{1,15}$/.test(v)) {
+                    v = v * 10;
+                } else if (/^(-)?\d{1,16}$/.test(v)) {
+                    v = v * 1;
+                } else {
+                    return v;
+                }
+                dateObj = new Date(v);
+            }
+            //
+            format = format.replace(/Y/g, dateObj.getFullYear());
+            format = format.replace(/m/g, this.zeroFill(dateObj.getMonth() + 1, 2));
+            format = format.replace(/d/g, this.zeroFill(dateObj.getDate(), 2));
+            format = format.replace(/H/g, this.zeroFill(dateObj.getHours(), 2));
+            format = format.replace(/i/g, this.zeroFill(dateObj.getMinutes(), 2));
+            format = format.replace(/s/g, this.zeroFill(dateObj.getSeconds(), 2));
+            return format;
+        },
+
+        /**
+         * 租用时间差(不够1个小时算一个小时)
+         * @param s
+         * @param e
+         * @returns {*}
+         */
+        timeDiff: function(s, e) {
+            if (typeof e === 'undefined') {
+                e = Math.round(new Date().getTime()/1000);
+            }
+            let d = e - s;
+            if (d > 86400) {
+                let day = Math.floor(d / 86400);
+                let hour = Math.ceil((d - (day * 86400)) / 3600);
+                if (hour > 0) {
+                    return day + '天' + hour + '小时';
+                } else {
+                    return day + '天';
+                }
+            } else if (d > 3600) {
+                return Math.ceil(d / 3600) + '小时';
+            } else if (d > 60) {
+                return Math.ceil(d / 60) + '分钟';
+            } else if (d > 10) {
+                return d + '秒';
+            } else {
+                return '刚刚';
+            }
+        },
+
+        /**
+         * 检测手机号码格式
+         * @param str
+         * @returns {boolean}
+         */
+        isMobile: function(str) {
+            return /^1([3456789])\d{9}$/.test(str);
+        },
+
+        /**
+         * 是否手机号码
+         * @param phone
+         * @returns {boolean}
+         */
+        isPhone: function (phone) {
+            return this.isMobile(phone);
+        },
+
+        /**
+         * 根据两点间的经纬度计算距离
+         * @param lng1
+         * @param lat1
+         * @param lng2
+         * @param lat2
+         * @returns {string|*}
+         */
+        getDistance: function (lng1, lat1, lng2, lat2) {
+            let DEF_PI = 3.14159265359;         // PI
+            let DEF_2PI = 6.28318530712;        // 2*PI
+            let DEF_PI180 = 0.01745329252;      // PI/180.0
+            let DEF_R = 6370693.5;              // radius of earth
+            //
+            let ew1, ns1, ew2, ns2;
+            let dx, dy, dew;
+            let distance;
+            // 角度转换为弧度
+            ew1 = lng1 * DEF_PI180;
+            ns1 = lat1 * DEF_PI180;
+            ew2 = lng2 * DEF_PI180;
+            ns2 = lat2 * DEF_PI180;
+            // 经度差
+            dew = ew1 - ew2;
+            // 若跨东经和西经180 度,进行调整
+            if (dew > DEF_PI)
+                dew = DEF_2PI - dew;
+            else if (dew < -DEF_PI)
+                dew = DEF_2PI + dew;
+            dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度)
+            dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度)
+            // 勾股定理求斜边长
+            distance = Math.sqrt(dx * dx + dy * dy).toFixed(0);
+            return distance;
+        },
+
+        /**
+         * 设置网页标题
+         * @param title
+         */
+        setTile(title) {
+            document.title = title;
+            let mobile = navigator.userAgent.toLowerCase();
+            if (/iphone|ipad|ipod/.test(mobile)) {
+                let iframe = document.createElement('iframe');
+                iframe.style.display = 'none';
+                iframe.setAttribute('src', '/favicon.ico');
+                let iframeCallback = function () {
+                    setTimeout(function () {
+                        iframe.removeEventListener('load', iframeCallback);
+                        document.body.removeChild(iframe)
+                    }, 0)
+                };
+                iframe.addEventListener('load', iframeCallback);
+                document.body.appendChild(iframe)
+            }
+        },
+
+        /**
+         * 克隆对象
+         * @param myObj
+         * @returns {*}
+         */
+        cloneData(myObj) {
+            if(typeof(myObj) !== 'object') return myObj;
+            if(myObj === null) return myObj;
+            //
+            if (typeof myObj.length === 'number') {
+                let [ ...myNewObj ] = myObj;
+                return myNewObj;
+            }else{
+                let { ...myNewObj } = myObj;
+                return myNewObj;
+            }
+        },
+
+        /**
+         * 将一个 JSON 字符串转换为对象(已try)
+         * @param str
+         * @param defaultVal
+         * @returns {*}
+         */
+        jsonParse(str, defaultVal) {
+            if (str === null) {
+                return defaultVal ? defaultVal : {};
+            }
+            if (typeof str === "object") {
+                return str;
+            }
+            try {
+                return JSON.parse(str);
+            } catch (e) {
+                return defaultVal ? defaultVal : {};
+            }
+        },
+
+        /**
+         * 将 JavaScript 值转换为 JSON 字符串(已try)
+         * @param json
+         * @param defaultVal
+         * @returns {string}
+         */
+        jsonStringify(json, defaultVal) {
+            if (typeof json !== 'object') {
+                return json;
+            }
+            try{
+                return JSON.stringify(json);
+            }catch (e) {
+                return defaultVal ? defaultVal : "";
+            }
+        },
+
+        /**
+         * 监听对象尺寸发生改变
+         * @param obj
+         * @param callback
+         */
+        resize(obj, callback) {
+            let myObj = $A(obj);
+            if (myObj.length === 0) return;
+            let height = parseInt(myObj.outerHeight()),
+                width = parseInt(myObj.outerWidth());
+            let inter = setInterval(()=>{
+                if (myObj.length === 0) clearInterval(inter);
+                let tmpHeight = parseInt(myObj.outerHeight()),
+                    tmpWidth = parseInt(myObj.outerWidth());
+                if (height !== tmpHeight || width !== tmpWidth) {
+                    height = tmpHeight;
+                    width = tmpWidth;
+                    console.log(width, height);
+                    if (typeof callback === 'function') callback();
+                }
+            }, 250);
+        },
+
+        /**
+         * 是否IOS
+         * @returns {boolean|string}
+         */
+        isIos() {
+            let ua = typeof window !== 'undefined' && window.navigator.userAgent.toLowerCase();
+            return ua && /iphone|ipad|ipod|ios/.test(ua);
+        },
+
+        /**
+         * 是否安卓
+         * @returns {boolean|string}
+         */
+        isAndroid() {
+            let ua = typeof window !== 'undefined' && window.navigator.userAgent.toLowerCase();
+            return ua && ua.indexOf('android') > 0;
+        },
+
+        /**
+         * 是否微信
+         * @returns {boolean}
+         */
+        isWeixin() {
+            let ua = typeof window !== 'undefined' && window.navigator.userAgent.toLowerCase();
+            return (ua.match(/MicroMessenger/i) + '' === 'micromessenger');
+        },
+
+        /**
+         * 获取对象
+         * @param obj
+         * @param keys
+         * @returns {string|*}
+         */
+        getObject(obj, keys) {
+            let object = obj;
+            if (this.count(obj) === 0 || this.count(keys) === 0) {
+                return "";
+            }
+            let arr = keys.replace(/,/g, "|").replace(/\./g, "|").split("|");
+            $A.each(arr, (index, key) => {
+                object = typeof object[key] === "undefined" ? "" : object[key];
+            });
+            return object;
+        },
+
+        /**
+         * 统计数组或对象长度
+         * @param obj
+         * @returns {number}
+         */
+        count(obj) {
+            try {
+                if (typeof obj === "undefined") {
+                    return 0;
+                }
+                if (typeof obj === "number") {
+                    obj+= "";
+                }
+                if (typeof obj.length === 'number') {
+                    return obj.length;
+                } else {
+                    let i = 0, key;
+                    for (key in obj) {
+                        i++;
+                    }
+                    return i;
+                }
+            }catch (e) {
+                return 0;
+            }
+        },
+
+        /**
+         * 将数组或对象内容部分拼成字符串
+         * @param obj
+         * @returns {string}
+         */
+        objImplode(obj) {
+            if (obj === null) {
+                return "";
+            }
+            let str = "";
+            $A.each(obj, (key, val) => {
+                if (val !== null) {
+                    if (typeof val === "object" && this.count(val) > 0) {
+                        str += this.objImplode(val);
+                    } else {
+                        str += String(val);
+                    }
+                }
+            });
+            return str.replace(/\s/g, "").replace(/undefined/g, "");
+        },
+
+        /**
+         * 指定键获取url参数
+         * @param key
+         * @returns {*}
+         */
+        urlParameter(key) {
+            let params = this.urlParameterAll();
+            return typeof key === "undefined" ? params : params[key];
+        },
+
+        urlParameterAll() {
+            let search = window.location.search || "";
+            let arr = [];
+            if (this.strExists(search, "?")) {
+                arr = this.getMiddle(search, "?").split("&");
+            }
+            let params = {};
+            for (let i = 0; i < arr.length; i++) {
+                let data = arr[i].split("=");
+                if (data.length === 2) {
+                    params[data[0]] = data[1];
+                }
+            }
+            return params;
+        },
+
+        /**
+         * 删除地址中的参数
+         * @param url
+         * @param parameter
+         * @returns {string|*}
+         */
+        removeURLParameter(url, parameter) {
+            if (parameter instanceof Array) {
+                parameter.forEach((key) => {
+                    url = $A.removeURLParameter(url, key)
+                });
+                return url;
+            }
+            var urlparts = url.split('?');
+            if (urlparts.length >= 2) {
+                //参数名前缀
+                var prefix = encodeURIComponent(parameter) + '=';
+                var pars = urlparts[1].split(/[&;]/g);
+
+                //循环查找匹配参数
+                for (var i = pars.length; i-- > 0;) {
+                    if (pars[i].lastIndexOf(prefix, 0) !== -1) {
+                        //存在则删除
+                        pars.splice(i, 1);
+                    }
+                }
+
+                return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
+            }
+            return url;
+        },
+
+        /**
+         * 连接加上参数
+         * @param url
+         * @param params
+         * @returns {*}
+         */
+        urlAddParams(url, params) {
+            if (typeof params === "object" && params !== null) {
+                url+= "";
+                url+= url.indexOf("?") === -1 ? '?' : '';
+                for (var key in params) {
+                    if (!params.hasOwnProperty(key)) {
+                        continue;
+                    }
+                    url+= '&' + key + '=' + params[key];
+                }
+            }
+            return url.replace("?&", "?");
+        },
+
+        /**
+         * 链接字符串
+         * @param value 第一个参数为连接符
+         * @returns {string}
+         */
+        stringConnect(...value) {
+            let s = null;
+            let text = "";
+            value.forEach((val) => {
+                if (s === null) {
+                    s = val;
+                }else if (val){
+                    if (val && text) text+= s;
+                    text+= val;
+                }
+            });
+            return text;
+        },
+
+        /**
+         * 判断两个对象是否相等
+         * @param x
+         * @param y
+         * @returns {boolean}
+         */
+        objEquals(x, y) {
+            let f1 = x instanceof Object;
+            let f2 = y instanceof Object;
+            if (!f1 || !f2) {
+                return x === y
+            }
+            if (Object.keys(x).length !== Object.keys(y).length) {
+                return false
+            }
+            for (let p in x) {
+                if (x.hasOwnProperty(p)) {
+                    let a = x[p] instanceof Object;
+                    let b = y[p] instanceof Object;
+                    if (a && b) {
+                        if (!this.objEquals(x[p], y[p])) {
+                            return false;
+                        }
+                    } else if (x[p] != y[p]) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        },
+
+        /**
+         * 输入框内插入文本
+         * @param object
+         * @param content
+         */
+        insert2Input (object, content) {
+            if (object === null || typeof object !== "object") return;
+            if (typeof object.length === 'number' && object.length > 0) object = object[0];
+
+            let ele = typeof object.$el === "object" ? $A(object.$el) : $A(object);
+            if (ele.length === 0) return;
+            let eleDom = ele[0];
+
+            if (eleDom.tagName != "INPUT" && eleDom.tagName != "TEXTAREA") {
+                if (ele.find("input").length === 0) {
+                    ele = ele.find("textarea");
+                }else{
+                    ele = ele.find("input");
+                }
+            }
+            if (ele.length === 0) return;
+            eleDom = ele[0];
+
+            if (eleDom.tagName != "INPUT" && eleDom.tagName != "TEXTAREA") return;
+
+            let text = ele.val();
+            let { selectionStart, selectionEnd } = eleDom;
+
+            ele.val(`${text.substring(0, selectionStart)}${content}${text.substring(selectionEnd, text.length)}`);
+            eleDom.dispatchEvent(new Event('input'));
+
+            setTimeout(() => {
+                if (eleDom.setSelectionRange) {
+                    let pos = text.substring(0, selectionStart).length + content.length;
+                    eleDom.focus();
+                    eleDom.setSelectionRange(pos, pos);
+                }
+            }, 10);
+        },
+
+        /**
+         * iOS上虚拟键盘引起的触控错位
+         */
+        iOSKeyboardFixer() {
+            if (!this.isIos()) {
+                return;
+            }
+            document.body.scrollTop = document.body.scrollTop + 1;
+            document.body.scrollTop = document.body.scrollTop - 1;
+        },
+
+        autoDevwid(width) {
+            let _width = width || 640;
+            new function () {
+                let _self = this;
+                _self.width = _width;           //设置默认最大宽度
+                _self.fontSize = 30;            //默认字体大小
+                _self.widthProportion = function () {
+                    let p = (document.body && document.body.clientWidth || document.getElementsByTagName("html")[0].offsetWidth) / _self.width;
+                    return p > 1 ? 1 : p < 0.38 ? 0.38 : p;
+                };
+                _self.changePage = function () {
+                    document.getElementsByTagName("html")[0].setAttribute("style", "font-size:" + _self.widthProportion() * _self.fontSize + "px !important");
+                };
+                _self.changePage();
+                window.addEventListener('resize', function () {
+                    _self.changePage();
+                }, false);
+            };
+            //
+            let scale = $A(window).width() / _width;
+            $A(".__auto").each(function () {
+                if ($A(this).attr("data-original") !== "1") {
+                    $A(this).attr("data-original-top", parseInt($A(this).css("top")));
+                    $A(this).attr("data-original-right", parseInt($A(this).css("right")));
+                    $A(this).attr("data-original-bottom", parseInt($A(this).css("bottom")));
+                    $A(this).attr("data-original-left", parseInt($A(this).css("left")));
+                    $A(this).attr("data-original-width", parseInt($A(this).css("width")));
+                    $A(this).attr("data-original-height", parseInt($A(this).css("height")));
+                    $A(this).attr("data-original-line-height", parseInt($A(this).css("line-height")));
+                    $A(this).attr("data-original", "1");
+                }
+                let _t = parseInt($A(this).attr("data-original-top"));
+                let _r = parseInt($A(this).attr("data-original-right"));
+                let _b = parseInt($A(this).attr("data-original-bottom"));
+                let _l = parseInt($A(this).attr("data-original-left"));
+                let _w = parseInt($A(this).attr("data-original-width"));
+                let _h = parseInt($A(this).attr("data-original-height"));
+                let _lh = parseInt($A(this).attr("data-original-line-height"));
+                //
+                let _css = {};
+                if (_t > 0) _css['top'] = _t * scale;
+                if (_r > 0) _css['right'] = _r * scale;
+                if (_b > 0) _css['bottom'] = _b * scale;
+                if (_l > 0) _css['left'] = _l * scale;
+                if (_w > 0) _css['width'] = _w * scale;
+                if (_h > 0) _css['height'] = _h * scale;
+                if (_lh > 0) _css['line-height'] = (_lh * scale) + 'px';
+                $A(this).css(_css);
+            });
+            return scale;
+        }
+
+    });
+
+    /**
+     * =============================================================================
+     * ****************************   ihttp   ****************************
+     * =============================================================================
+     */
+    $.extend({
+
+        serializeObject (obj, parents) {
+            if (typeof obj === 'string') return obj;
+            let resultArray = [];
+            let separator = '&';
+            parents = parents || [];
+            let newParents;
+
+            function var_name(name) {
+                if (parents.length > 0) {
+                    let _parents = '';
+                    for (let j = 0; j < parents.length; j++) {
+                        if (j === 0) _parents += parents[j];
+                        else _parents += '[' + encodeURIComponent(parents[j]) + ']';
+                    }
+                    return _parents + '[' + encodeURIComponent(name) + ']';
+                }
+                else {
+                    return encodeURIComponent(name);
+                }
+            }
+
+            function var_value(value) {
+                return encodeURIComponent(value);
+            }
+
+            for (let prop in obj) {
+                if (obj.hasOwnProperty(prop)) {
+                    let toPush;
+                    if (Array.isArray(obj[prop])) {
+                        toPush = [];
+                        for (let i = 0; i < obj[prop].length; i++) {
+                            if (!Array.isArray(obj[prop][i]) && typeof obj[prop][i] === 'object') {
+                                newParents = parents.slice();
+                                newParents.push(prop);
+                                newParents.push(i + '');
+                                toPush.push($.serializeObject(obj[prop][i], newParents));
+                            }
+                            else {
+                                toPush.push(var_name(prop) + '[]=' + var_value(obj[prop][i]));
+                            }
+
+                        }
+                        if (toPush.length > 0) resultArray.push(toPush.join(separator));
+                    }
+                    else if (obj[prop] === null) {
+                        resultArray.push(var_name(prop) + '=');
+                    }
+                    else if (typeof obj[prop] === 'object') {
+                        // Object, convert to named array
+                        newParents = parents.slice();
+                        newParents.push(prop);
+                        toPush = $.serializeObject(obj[prop], newParents);
+                        if (toPush !== '') resultArray.push(toPush);
+                    }
+                    else if (typeof obj[prop] !== 'undefined' && obj[prop] !== '') {
+                        // Should be string or plain value
+                        resultArray.push(var_name(prop) + '=' + var_value(obj[prop]));
+                    }
+                    else if (obj[prop] === '') resultArray.push(var_name(prop));
+                }
+            }
+            return resultArray.join(separator);
+        },
+
+        // Global Ajax Setup
+        globalAjaxOptions: {},
+        ajaxSetup (options) {
+            if (options.type) options.method = options.type;
+            $.each(options, function (optionName, optionValue) {
+                $.globalAjaxOptions[optionName] = optionValue;
+            });
+        },
+
+        // Ajax
+        _jsonpRequests: 0,
+        ihttp(options) {
+            let defaults = {
+                method: 'GET',
+                data: false,
+                async: true,
+                cache: true,
+                user: '',
+                password: '',
+                headers: {},
+                xhrFields: {},
+                statusCode: {},
+                processData: true,
+                dataType: 'text',
+                contentType: 'application/x-www-form-urlencoded',
+                timeout: 0
+            };
+            let callbacks = ['beforeSend', 'error', 'complete', 'success', 'statusCode'];
+
+
+            //For jQuery guys
+            if (options.type) options.method = options.type;
+
+            // Merge global and defaults
+            $.each($.globalAjaxOptions, function (globalOptionName, globalOptionValue) {
+                if (callbacks.indexOf(globalOptionName) < 0) defaults[globalOptionName] = globalOptionValue;
+            });
+
+            // Function to run XHR callbacks and events
+            function fireAjaxCallback(eventName, eventData, callbackName) {
+                let a = arguments;
+                if (eventName) $(document).trigger(eventName, eventData);
+                if (callbackName) {
+                    // Global callback
+                    if (callbackName in $.globalAjaxOptions) $.globalAjaxOptions[callbackName](a[3], a[4], a[5], a[6]);
+                    // Options callback
+                    if (options[callbackName]) options[callbackName](a[3], a[4], a[5], a[6]);
+                }
+            }
+
+            // Merge options and defaults
+            $.each(defaults, function (prop, defaultValue) {
+                if (!(prop in options)) options[prop] = defaultValue;
+            });
+
+            // Default URL
+            if (!options.url) {
+                options.url = window.location.toString();
+            }
+            // Parameters Prefix
+            let paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';
+
+            // UC method
+            let _method = options.method.toUpperCase();
+            // Data to modify GET URL
+            if ((_method === 'GET' || _method === 'HEAD' || _method === 'OPTIONS' || _method === 'DELETE') && options.data) {
+                let stringData;
+                if (typeof options.data === 'string') {
+                    // Should be key=value string
+                    if (options.data.indexOf('?') >= 0) stringData = options.data.split('?')[1];
+                    else stringData = options.data;
+                }
+                else {
+                    // Should be key=value object
+                    stringData = $.serializeObject(options.data);
+                }
+                if (stringData.length) {
+                    options.url += paramsPrefix + stringData;
+                    if (paramsPrefix === '?') paramsPrefix = '&';
+                }
+            }
+            // JSONP
+            if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {
+
+                let callbackName = 'f7jsonp_' + Date.now() + ($._jsonpRequests++);
+                let abortTimeout;
+                let callbackSplit = options.url.split('callback=');
+                let requestUrl = callbackSplit[0] + 'callback=' + callbackName;
+                if (callbackSplit[1].indexOf('&') >= 0) {
+                    let addVars = callbackSplit[1].split('&').filter(function (el) {
+                        return el.indexOf('=') > 0;
+                    }).join('&');
+                    if (addVars.length > 0) requestUrl += '&' + addVars;
+                }
+
+                // Create script
+                let script = document.createElement('script');
+                script.type = 'text/javascript';
+                script.onerror = function () {
+                    clearTimeout(abortTimeout);
+                    fireAjaxCallback(undefined, undefined, 'error', null, 'scripterror');
+                    fireAjaxCallback('ajaxComplete ajax:complete', {scripterror: true}, 'complete', null, 'scripterror');
+                };
+                script.src = requestUrl;
+
+                // Handler
+                window[callbackName] = function (data) {
+                    clearTimeout(abortTimeout);
+                    fireAjaxCallback(undefined, undefined, 'success', data);
+                    script.parentNode.removeChild(script);
+                    script = null;
+                    delete window[callbackName];
+                };
+                document.querySelector('head').appendChild(script);
+
+                if (options.timeout > 0) {
+                    abortTimeout = setTimeout(function () {
+                        script.parentNode.removeChild(script);
+                        script = null;
+                        fireAjaxCallback(undefined, undefined, 'error', null, 'timeout');
+                    }, options.timeout);
+                }
+
+                return;
+            }
+
+            // Cache for GET/HEAD requests
+            if (_method === 'GET' || _method === 'HEAD' || _method === 'OPTIONS' || _method === 'DELETE') {
+                if (options.cache === false) {
+                    options.url += (paramsPrefix + '_nocache=' + Date.now());
+                }
+            }
+
+            // Create XHR
+            let xhr = new XMLHttpRequest();
+
+            // Save Request URL
+            xhr.requestUrl = options.url;
+            xhr.requestParameters = options;
+
+            // Open XHR
+            xhr.open(_method, options.url, options.async, options.user, options.password);
+
+            // Create POST Data
+            let postData = null;
+
+            if ((_method === 'POST' || _method === 'PUT' || _method === 'PATCH') && options.data) {
+                if (options.processData) {
+                    let postDataInstances = [ArrayBuffer, Blob, Document, FormData];
+                    // Post Data
+                    if (postDataInstances.indexOf(options.data.constructor) >= 0) {
+                        postData = options.data;
+                    }
+                    else {
+                        // POST Headers
+                        let boundary = '---------------------------' + Date.now().toString(16);
+
+                        if (options.contentType === 'multipart\/form-data') {
+                            xhr.setRequestHeader('Content-Type', 'multipart\/form-data; boundary=' + boundary);
+                        }
+                        else {
+                            xhr.setRequestHeader('Content-Type', options.contentType);
+                        }
+                        postData = '';
+                        let _data = $.serializeObject(options.data);
+                        if (options.contentType === 'multipart\/form-data') {
+                            boundary = '---------------------------' + Date.now().toString(16);
+                            _data = _data.split('&');
+                            let _newData = [];
+                            for (let i = 0; i < _data.length; i++) {
+                                _newData.push('Content-Disposition: form-data; name="' + _data[i].split('=')[0] + '"\r\n\r\n' + _data[i].split('=')[1] + '\r\n');
+                            }
+                            postData = '--' + boundary + '\r\n' + _newData.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n';
+                        }
+                        else {
+                            postData = _data;
+                        }
+                    }
+                }
+                else {
+                    postData = options.data;
+                }
+
+            }
+
+            // Additional headers
+            if (options.headers) {
+                $.each(options.headers, function (headerName, headerCallback) {
+                    xhr.setRequestHeader(headerName, headerCallback);
+                });
+            }
+
+            // Check for crossDomain
+            if (typeof options.crossDomain === 'undefined') {
+                options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;
+            }
+
+            if (!options.crossDomain) {
+                xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
+            }
+
+            if (options.xhrFields) {
+                $.each(options.xhrFields, function (fieldName, fieldValue) {
+                    xhr[fieldName] = fieldValue;
+                });
+            }
+
+            let xhrTimeout;
+            // Handle XHR
+            xhr.onload = function (e) {
+                if (xhrTimeout) clearTimeout(xhrTimeout);
+                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
+                    let responseData;
+                    if (options.dataType === 'json') {
+                        try {
+                            responseData = JSON.parse(xhr.responseText);
+                            fireAjaxCallback('ajaxSuccess ajax:success', {xhr: xhr}, 'success', responseData, xhr.status, xhr);
+                        }
+                        catch (err) {
+                            fireAjaxCallback('ajaxError ajax:error', {
+                                xhr: xhr,
+                                parseerror: true
+                            }, 'error', xhr, 'parseerror');
+                        }
+                    }
+                    else {
+                        responseData = xhr.responseType === 'text' || xhr.responseType === '' ? xhr.responseText : xhr.response;
+                        fireAjaxCallback('ajaxSuccess ajax:success', {xhr: xhr}, 'success', responseData, xhr.status, xhr);
+                    }
+                }
+                else {
+                    fireAjaxCallback('ajaxError ajax:error', {xhr: xhr}, 'error', xhr, xhr.status);
+                }
+                if (options.statusCode) {
+                    if ($.globalAjaxOptions.statusCode && $.globalAjaxOptions.statusCode[xhr.status]) $.globalAjaxOptions.statusCode[xhr.status](xhr);
+                    if (options.statusCode[xhr.status]) options.statusCode[xhr.status](xhr);
+                }
+                fireAjaxCallback('ajaxComplete ajax:complete', {xhr: xhr}, 'complete', xhr, xhr.status);
+            };
+
+            xhr.onerror = function (e) {
+                if (xhrTimeout) clearTimeout(xhrTimeout);
+                fireAjaxCallback('ajaxError ajax:error', {xhr: xhr}, 'error', xhr, xhr.status);
+                fireAjaxCallback('ajaxComplete ajax:complete', {xhr: xhr, error: true}, 'complete', xhr, 'error');
+            };
+
+            // Ajax start callback
+            fireAjaxCallback('ajaxStart ajax:start', {xhr: xhr}, 'start', xhr);
+            fireAjaxCallback(undefined, undefined, 'beforeSend', xhr);
+
+            // Timeout
+            if (options.timeout > 0) {
+                xhr.onabort = function () {
+                    if (xhrTimeout) clearTimeout(xhrTimeout);
+                };
+                xhrTimeout = setTimeout(function () {
+                    xhr.abort();
+                    fireAjaxCallback('ajaxError ajax:error', {xhr: xhr, timeout: true}, 'error', xhr, 'timeout');
+                    fireAjaxCallback('ajaxComplete ajax:complete', {
+                        xhr: xhr,
+                        timeout: true
+                    }, 'complete', xhr, 'timeout');
+                }, options.timeout);
+            }
+
+            // Send XHR
+            xhr.send(postData);
+
+            // Return XHR object
+            return xhr;
+        }
+    });
+
+    /**
+     * =============================================================================
+     * *************************   Bootstrap extend   ************************
+     * =============================================================================
+     */
+    $.extend({
+
+        toast(params, timeout, template) {
+            let _bg = function(num) {
+                let container = $A(".__bootstrap_toast_container");
+                if (container.length > 0) {
+                    let bgobj = container.find(".alert-bg");
+                    let bgnum = parseInt(bgobj.attr("data-num"));
+                    bgnum+= num;
+                    bgobj.attr("data-num", bgnum);
+                    if (bgnum > 0) {
+                        bgobj.show();
+                    }else{
+                        bgobj.hide();
+                    }
+                }
+            };
+            if (!params) return false;
+            if (typeof params === 'object' && params.length > 0) {
+                if (params.attr("data-show-bg") === "true") _bg(-1);
+                params.css({width: Math.ceil(params.outerWidth())});
+                params.addClass("leave");
+                setTimeout(()=>{ params.remove() }, 300);
+                return;
+            }
+            if (typeof timeout === 'string') {
+                template = timeout;
+                timeout = 2500;
+            }
+            if (typeof params === 'string') params = { title: params };
+            if (typeof params.timeout === 'undefined') params.timeout = 2500;
+            if (typeof params.template === 'undefined') params.template = 'success';
+            if (typeof params.fixed === 'undefined') params.fixed = false;
+            if (typeof params.close === 'undefined') params.close = true;
+            if (typeof timeout !== 'undefined') params.timeout = timeout;
+            if (typeof template !== 'undefined') params.template = template;
+            //
+            let container = $A(".__bootstrap_toast_container");
+            if (container.length === 0) {
+                $A("<style>")
+                    .attr({type: "text/css"})
+                    .html(
+                        ".__bootstrap_toast_container{position:fixed;z-index:99999;top:5%;right:5%;padding:0;text-align:right;}" +
+                        ".__bootstrap_toast_container .alert-bg{position:fixed;display:none;z-index:1;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.6);}" +
+                        ".__bootstrap_toast_container .alert-body{position:relative;z-index:2;display:block;min-width:180px;text-align:left;opacity:0;transform:translate3d(0,100px,0);-webkit-transform:translate3d(0,100px,0);transition-duration:300ms;-webkit-transition-duration:300ms;}" +
+                        ".__bootstrap_toast_container .alert-body.enter{opacity:1;transform:translate3d(0,0,0);-webkit-transform:translate3d(0,0,0);}" +
+                        ".__bootstrap_toast_container .alert-body.leave{position:absolute;top:0;right:0;z-index:3;opacity:0;transform:translate3d(100%,0,0);-webkit-transform:translate3d(100%,0,0);transition-duration:200ms;-webkit-transition-duration:300ms;}" +
+                        "")
+                    .appendTo("head");
+                $A("body").append("<div class='__bootstrap_toast_container'><div class='alert-bg' data-num='0'></div></div>");
+                container = $A(".__bootstrap_toast_container");
+            }
+            //
+            let $intemp = $A('<div class="alert-body alert alert-' + params.template + ' alert-dismissible" role="alert"><button type="button" class="close"><span aria-hidden="true">&times;</span></button>' + params.title + '</div>');
+            if (params.close === false) {
+                $intemp.removeClass("alert-dismissible");
+                $intemp.find(".close").remove();
+            }else{
+                $intemp.find(".close").click(()=>{ $A.toast($intemp); });
+            }
+            if (params.fixed === true) {
+                _bg(1);
+                $intemp.attr("data-show-bg", "true");
+            }
+            container.append($intemp);
+            //
+            if (typeof params.timeout === 'number') {
+                setTimeout(()=>{ $A.toast($intemp) }, params.timeout)
+            }
+            setTimeout(()=>{ $intemp.addClass("enter") }, 10);
+            //
+            return $intemp;
+        }
+    });
+
+    /**
+     * =============================================================================
+     * *****************************   ajax   ****************************
+     * =============================================================================
+     */
+    $.extend({
+
+        ajax(params) {
+            if (!params) return false;
+            if (typeof params.url === 'undefined') return false;
+            if (typeof params.data === 'undefined') params.data = {};
+            if (typeof params.cache === 'undefined') params.cache = false;
+            if (typeof params.method === 'undefined') params.method = 'GET';
+            if (typeof params.timeout === 'undefined') params.timeout = 30000;
+            if (typeof params.dataType === 'undefined') params.dataType = 'json';
+            if (typeof params.beforeSend === 'undefined') params.beforeSend = () => { };
+            if (typeof params.complete === 'undefined') params.complete = () => { };
+            if (typeof params.afterComplete === 'undefined') params.afterComplete = () => { };
+            if (typeof params.success === 'undefined') params.success = () => { };
+            if (typeof params.error === 'undefined') params.error = () => { };
+            //
+            let loadText = "数据加载中.....";
+            let busyNetwork = "网络繁忙,请稍后再试!";
+            if (typeof $A.app === 'object' && typeof $A.app.$L === 'function') {
+                loadText = $A.app.$L(loadText);
+                busyNetwork = $A.app.$L(busyNetwork);
+            }
+            //
+            let toastID = null, beforeTitle = '', errorTitle = '';
+            if (typeof $A.app === 'object' && typeof $A.app.$Message === 'object') {
+                if (typeof params.beforeSend === 'string')  {
+                    beforeTitle = params.beforeSend;
+                    params.beforeSend = () => { toastID = $A.app.$Message.loading({content:beforeTitle, duration: 0}); };
+                }else if (params.beforeSend === true) {
+                    params.beforeSend = () => { toastID = $A.app.$Message.loading({content:loadText, duration: 0}); };
+                }
+                if (typeof params.error === 'string')  {
+                    errorTitle = params.error;
+                    params.error = () => { $A.app.$Message.error({content:errorTitle, duration: 5}); };
+                }else if (params.error === true) {
+                    params.error = () => { $A.app.$Message.error({content:busyNetwork, duration: 5}); };
+                }
+                if (params.complete === true) {
+                    params.complete = () => { toastID?toastID():'' };
+                }
+            }else{
+                if (typeof params.beforeSend === 'string')  {
+                    beforeTitle = params.beforeSend;
+                    params.beforeSend = () => { toastID = $A.toast({title:beforeTitle, fixed: true, timeout: false}); };
+                }else if (params.beforeSend === true) {
+                    params.beforeSend = () => { toastID = $A.toast({title:loadText, fixed: true, timeout: false}); };
+                }
+                if (typeof params.error === 'string')  {
+                    errorTitle = params.error;
+                    params.error = () => { $A.toast(errorTitle, "danger"); };
+                }else if (params.error === true) {
+                    params.error = () => { $A.toast(busyNetwork, "danger"); };
+                }
+                if (params.complete === true) {
+                    params.complete = () => { toastID?$A.toast(toastID):'' };
+                }
+            }
+            //
+            if (typeof params.header !== 'object') params.header = {};
+            params.header['Content-Type'] = 'application/json';
+            params.header['language'] = window.localStorage['__language:type__'] || 'zh';
+            params.header['token'] = $A.token();
+            //
+            params.data['__Access-Control-Allow-Origin'] = true;
+            params.beforeSend();
+            $A.ihttp({
+                url: params.url,
+                data: params.data,
+                cache: params.cache,
+                headers: params.header,
+                method: params.method.toUpperCase(),
+                contentType: "OPTIONS",
+                crossDomain: true,
+                dataType: params.dataType,
+                timeout: params.timeout,
+                success: function(data, status, xhr) {
+                    params.complete();
+                    params.success(data, status, xhr);
+                    params.afterComplete(true);
+                },
+                error: function(xhr, status) {
+                    params.complete();
+                    params.error(xhr, status);
+                    params.afterComplete(false);
+                }
+            });
+        }
+    });
+
+
+    /**
+     * =============================================================================
+     * *****************************   manage assist   ****************************
+     * =============================================================================
+     */
+    $.extend({
+
+        /**
+         *  对象中有Date格式的转成指定格式
+         * @param myObj
+         * @param format  默认格式:Y-m-d
+         * @returns {*}
+         */
+        date2string(myObj, format) {
+            if (myObj === null) {
+                return myObj;
+            }
+            if (typeof format === "undefined") {
+                format = "Y-m-d";
+            }
+            if (typeof myObj === "object") {
+                if (myObj instanceof Date) {
+                    return $A.formatDate(format, myObj);
+                }
+                $A.each(myObj, (key, val)=>{
+                    myObj[key] = $A.date2string(val, format);
+                });
+                return myObj;
+            }
+            return myObj;
+        },
+
+        /**
+         * 获取一些指定时间
+         * @param str
+         * @param retInt
+         * @returns {*|string}
+         */
+        getData(str, retInt = false) {
+            let now = new Date();                   //当前日期
+            let nowDayOfWeek = now.getDay();        //今天本周的第几天
+            let nowDay = now.getDate();             //当前日
+            let nowMonth = now.getMonth();          //当前月
+            let nowYear = now.getYear();            //当前年
+            nowYear += (nowYear < 2000) ? 1900 : 0;
+            let lastMonthDate = new Date();         //上月日期
+            lastMonthDate.setDate(1);
+            lastMonthDate.setMonth(lastMonthDate.getMonth()-1);
+            let lastMonth = lastMonthDate.getMonth();
+            let getQuarterStartMonth = () => {
+                let quarterStartMonth = 0;
+                if(nowMonth < 3) {
+                    quarterStartMonth = 0;
+                }
+                if (2 < nowMonth && nowMonth < 6) {
+                    quarterStartMonth = 3;
+                }
+                if (5 < nowMonth && nowMonth < 9) {
+                    quarterStartMonth = 6;
+                }
+                if (nowMonth > 8) {
+                    quarterStartMonth = 9;
+                }
+                return quarterStartMonth;
+            };
+            let getMonthDays = (myMonth) => {
+                let monthStartDate = new Date(nowYear, myMonth, 1);
+                let monthEndDate = new Date(nowYear, myMonth + 1, 1);
+                return (monthEndDate - monthStartDate)/(1000 * 60 * 60 * 24);
+            };
+            //
+            let time = now.getTime();
+            switch (str) {
+                case '今天':
+                    time = now;
+                    break;
+                case '昨天':
+                    time = now - 86400000;
+                    break;
+                case '前天':
+                    time = now - 86400000 * 2;
+                    break;
+                case '本周':
+                    time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek);
+                    break;
+                case '本周结束':
+                    time = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek));
+                    break;
+                case '上周':
+                    time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 7);
+                    break;
+                case '上周结束':
+                    time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 1);
+                    break;
+                case '本周2':
+                    time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek + 1);
+                    break;
+                case '本周结束2':
+                    time = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek) + 1);
+                    break;
+                case '上周2':
+                    time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 7 + 1);
+                    break;
+                case '上周结束2':
+                    time = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 1 + 1);
+                    break;
+                case '本月':
+                    time = new Date(nowYear, nowMonth, 1);
+                    break;
+                case '本月结束':
+                    time = new Date(nowYear, nowMonth, getMonthDays(nowMonth));
+                    break;
+                case '上个月':
+                    time = new Date(nowYear, lastMonth, 1);
+                    break;
+                case '上个月结束':
+                    time = new Date(nowYear, lastMonth, getMonthDays(lastMonth));
+                    break;
+                case '本季度':
+                    time = new Date(nowYear, getQuarterStartMonth(), 1);
+                    break;
+                case '本季度结束':
+                    let quarterEndMonth = getQuarterStartMonth() + 2;
+                    time = new Date(nowYear, quarterEndMonth, getMonthDays(quarterEndMonth));
+                    break;
+            }
+            if (retInt === true) {
+                return time;
+            }
+            return $A.formatDate("Y-m-d", parseInt(time / 1000))
+        },
+
+        /**
+         * 字节转换
+         * @param bytes
+         * @returns {string}
+         */
+        bytesToSize(bytes) {
+            if (bytes === 0) return '0 B';
+            let k = 1024;
+            let sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+            let i = Math.floor(Math.log(bytes) / Math.log(k));
+            if (typeof sizes[i] === "undefined") {
+                return '0 B';
+            }
+            return $A.runNum((bytes / Math.pow(k, i)), 2) + ' ' + sizes[i];
+        }
+    });
+
+    window.$A = $;
+})(window, window.jQuery);

+ 272 - 0
assets/js/main/App.vue

@@ -0,0 +1,272 @@
+<template>
+    <div id="app">
+        <w-header></w-header>
+        <transition :name="transitionName">
+            <keep-alive>
+                <router-view class="child-view"></router-view>
+            </keep-alive>
+        </transition>
+        <w-spinner></w-spinner>
+    </div>
+</template>
+
+<script>
+    import WSpinner from "./components/WSpinner";
+    import WHeader from "./components/WHeader";
+    export default {
+        components: {WHeader, WSpinner},
+        data () {
+            return {
+                transitionName: null,
+            }
+        },
+        mounted() {
+            this.checkToken();
+            //
+            let hash = window.location.hash;
+            if (hash.indexOf("#") === 0) {
+                hash = hash.substr(1);
+                if (hash) {
+                    this.$nextTick(() => {
+                        hash = $A.removeURLParameter(hash, 'token');
+                        this.goForward({path: hash});
+                    });
+                }
+            }
+            this.sessionStorage('/', 1);
+            let pathname = window.location.pathname;
+            if (pathname && this.sessionStorage(pathname) === 0) {
+                this.sessionStorage(pathname, this.sessionStorage('::count') + 1);
+            }
+            //
+            setInterval(() => {
+                this.searchEnter();
+            }, 1000);
+            //
+            this.handleWebSocket();
+            $A.setOnUserInfoListener("app", () => { this.handleWebSocket() });
+        },
+        watch: {
+            '$route' (To, From) {
+                if (this.transitionName === null) {
+                    this.transitionName = 'app-slide-no';
+                    return;
+                }
+                if (typeof To.name === 'undefined' || typeof From.name === 'undefined') {
+                    return;
+                }
+                this.slideType(To, From);
+            }
+        },
+        methods: {
+            checkToken() {
+                let token = $A.urlParameter("token");
+                if ($A.count(token) > 10) {
+                    $.setToken(decodeURIComponent(token));
+                    $A.getUserInfo(true);
+                    let path = $A.removeURLParameter(window.location.href, 'token');
+                    let uri = document.createElement('a');
+                    uri.href = path;
+                    if (uri.pathname) {
+                        let query = $A.urlParameterAll();
+                        if (typeof query['token'] !== "undefined") delete query['token'];
+                        this.$nextTick(() => {
+                            this.goForward({path: uri.pathname, query}, true);
+                        });
+                    }
+                }
+            },
+            slideType(To, From) {
+                let isBack = this.$router.isBack;
+                this.$router.isBack = false;
+                //
+                let ToIndex = this.sessionStorage(To.path);
+                let FromIndex = this.sessionStorage(From.path);
+                if (ToIndex && ToIndex < FromIndex) {
+                    isBack = true;      //后退
+                    this.sessionStorage(true, ToIndex);
+                }else{
+                    isBack = false;     //前进
+                    this.sessionStorage(To.path, this.sessionStorage('::count') + 1);
+                }
+                //
+                if (To.meta.slide === false || From.meta.slide === false)
+                {
+                    //取消动画
+                    this.transitionName = 'app-slide-no'
+                }
+                else if (To.meta.slide === 'up' || From.meta.slide === 'up' || To.meta.slide === 'down' || From.meta.slide === 'down')
+                {
+                    //上下动画
+                    if (isBack) {
+                        this.transitionName = 'app-slide-down'
+                    } else {
+                        this.transitionName = 'app-slide-up'
+                    }
+                }
+                else
+                {
+                    //左右动画(默认)
+                    if (isBack) {
+                        this.transitionName = 'app-slide-right'
+                    } else {
+                        this.transitionName = 'app-slide-left'
+                    }
+                }
+            },
+            sessionStorage(path, num) {
+                let conut = 0;
+                let history = JSON.parse(window.sessionStorage['__history__'] || '{}');
+                if (path === true) {
+                    let items = {};
+                    for(let i in history){
+                        if (history.hasOwnProperty(i)) {
+                            if (parseInt(history[i]) <= num) {
+                                items[i] = history[i];
+                                conut++;
+                            }
+                        }
+                    }
+                    history = items;
+                    history['::count'] = Math.max(num, conut);
+                    window.sessionStorage['__history__'] = JSON.stringify(history);
+                    return history;
+                }
+                if (typeof num === 'undefined') {
+                    return parseInt(history[path] || 0);
+                }
+                if (path === "/") num = 1;
+                history[path] = num;
+                for(let key in history){ if (history.hasOwnProperty(key) && key !== '::count') { conut++; } }
+                history['::count'] = Math.max(num, conut);
+                window.sessionStorage['__history__'] = JSON.stringify(history);
+            },
+
+            searchEnter() {
+                let row = $A(".sreachBox");
+                if (row.length === 0) {
+                    return;
+                }
+                if (row.attr("data-enter-init") === "init") {
+                    return;
+                }
+                row.attr("data-enter-init", "init");
+                //
+                let buttons = row.find("button[type='button']");
+                let button = null;
+                if (buttons.length === 0) {
+                    return;
+                }
+                buttons.each((index, item) => {
+                    if ($A(item).text().indexOf("搜索")) {
+                        button = $A(item);
+                    }
+                });
+                if (button === null) {
+                    return;
+                }
+                row.find("input.ivu-input").keydown(function(e) {
+                    if (e.keyCode == 13) {
+                        if (!button.hasClass("ivu-btn-loading") ) {
+                            button.click();
+                        }
+                    }
+                });
+            },
+
+            handleWebSocket() {
+                if ($A.getToken() === false) {
+                    $A.WSOB.close();
+                } else {
+                    $A.WSOB.setOnMsgListener("app", (msgDetail) => {
+                        if (msgDetail.username == this.usrName) {
+                            return;
+                        }
+                        switch (msgDetail.messageType) {
+                            case 'open':
+                                window.localStorage.setItem("__::WookTeam:config", $A.jsonStringify(Object.assign(msgDetail.config, {
+                                    nickname: $A.getNickName(false)
+                                })));
+                                break;
+                            case 'close':
+                                window.localStorage.setItem("__::WookTeam:config", $A.jsonStringify({}));
+                                break;
+                            case 'info':
+                                if (msgDetail.body.type == 'update') {
+                                    $A.getUserInfo(true);
+                                }
+                                break;
+                            case 'user':
+                                if (msgDetail.body.type == 'taskA') {
+                                    $A.triggerTaskInfoListener(msgDetail.body.act, msgDetail.body.taskDetail, false);
+                                }
+                                break;
+                            case 'kick':
+                                $A.token("");
+                                $A.storage("userInfo", {});
+                                $A.triggerUserInfoListener({});
+                                //
+                                let id = 'inip_' + Math.round(Math.random() * 10000);
+                                let ip = msgDetail.body.ip;
+                                let ip2 = ip.substring(0, ip.lastIndexOf('.')) + '.*';
+                                this.$Modal.warning({
+                                    title: this.$L("系统提示"),
+                                    content: this.$L('您的帐号在其他地方(%)登录,您被迫退出,如果这不是您本人的操作,请注意帐号安全!', '<span id="' + id + '">' + ip2 + '</span>'),
+                                    onOk: () => {
+                                        this.goForward({path: '/'}, true);
+                                    }
+                                });
+                                this.$nextTick(() => {
+                                    $A.getIpInfo(ip, (res) => {
+                                        if (res.ret === 1) {
+                                            $A("span#" + id).text(res.data.textSmall);
+                                            $A("span#" + id).attr("title", ip2);
+                                        }
+                                    });
+                                });
+                                break;
+                        }
+                    });
+                }
+            }
+        }
+    }
+</script>
+
+<style>
+    body { overflow-x: hidden; }
+</style>
+<!--suppress CssUnusedSymbol -->
+<style scoped>
+    .child-view {
+        position: absolute;
+        width: 100%;
+        min-height: 100%;
+        background-color: #f1f2f7;
+        transition: all .3s cubic-bezier(.55, 0, .1, 1);
+    }
+    .app-slide-no-leave-to {display: none;}
+    /**
+     * 左右模式
+     */
+    .app-slide-left-leave-active{z-index:1;transform:translate(0,0)}
+    .app-slide-left-leave-to{z-index:1;transform:translate(0,0)}
+    .app-slide-left-enter-active{opacity:0;z-index:2;transform:translate(30%,0)}
+    .app-slide-left-enter-to{opacity:1;z-index:2;transform:translate(0,0)}
+    .app-slide-right-leave-active{opacity:1;z-index:2;transform:translate(0,0)}
+    .app-slide-right-leave-to{opacity:0;z-index:2;transform:translate(30%,0)}
+    .app-slide-right-enter-active{z-index:1;transform:translate(0,0)}
+    .app-slide-right-enter{z-index:1;transform:translate(0,0)}
+
+    /**
+     * 上下模式
+     */
+    .app-slide-up-leave-active{z-index:1;transform:translate(0,0)}
+    .app-slide-up-leave-to{z-index:1;transform:translate(0,0)}
+    .app-slide-up-enter-active{opacity:0;z-index:2;transform:translate(0,20%)}
+    .app-slide-up-enter-to{opacity:1;z-index:2;transform:translate(0,0)}
+    .app-slide-down-leave-active{opacity:1;z-index:2;transform:translate(0,0)}
+    .app-slide-down-leave-to{opacity:0;z-index:2;transform:translate(0,20%)}
+    .app-slide-down-enter-active{z-index:1;transform:translate(0,0)}
+    .app-slide-down-enter{z-index:1;transform:translate(0,0)}
+</style>

+ 94 - 0
assets/js/main/app.js

@@ -0,0 +1,94 @@
+import Vue from 'vue'
+import App from './App.vue'
+import routes from './routes'
+import VueRouter from 'vue-router'
+import ViewUI from 'view-design';
+import Language from '../_modules/language'
+import Mixins from '../_modules/mixins'
+
+
+import '../common'
+import './main'
+
+Vue.use(VueRouter);
+Vue.use(ViewUI);
+Vue.use(Language);
+Vue.use(Mixins);
+
+import Title from '../_components/Title.vue'
+import sreachTitle from '../_components/sreachTitle.vue'
+import UserInput from './components/UserInput'
+import UserView from './components/UserView'
+import UserImg from './components/UserImg'
+import WLoading from './components/WLoading'
+
+Vue.component('VTitle', Title);
+Vue.component('sreachTitle', sreachTitle);
+Vue.component('UserInput', UserInput);
+Vue.component('UserView', UserView);
+Vue.component('UserImg', UserImg);
+Vue.component('WLoading', WLoading);
+
+import TaskDetail from './components/project/task/detail'
+Vue.prototype.taskDetail = TaskDetail;
+
+import ReportDetail from './components/report/detail'
+Vue.prototype.reportDetail = ReportDetail;
+
+const originalPush = VueRouter.prototype.push
+VueRouter.prototype.push = function push(location) {
+    return originalPush.call(this, location).catch(err => err)
+}
+const router = new VueRouter({
+    mode: 'history',
+    routes
+});
+
+//进度条配置
+ViewUI.LoadingBar.config({
+    color: '#3fcc25',
+    failedColor: '#ff0000'
+});
+router.beforeEach((to, from, next) => {
+    ViewUI.LoadingBar.start();
+    next();
+});
+router.afterEach((to, from, next) => {
+    ViewUI.LoadingBar.finish();
+});
+
+//加载函数
+Vue.prototype.goForward = function(location, isReplace) {
+    if (typeof location === 'string') location = {name: location};
+    if (isReplace === true) {
+        this.$router.replace(location);
+    }else{
+        this.$router.push(location);
+    }
+};
+
+//返回函数
+Vue.prototype.goBack = function (number) {
+    let history = $A.jsonParse(window.sessionStorage['__history__'] || '{}');
+    if ($A.runNum(history['::count']) > 2) {
+        this.$router.go(typeof number === 'number' ? number : -1);
+    } else {
+        this.$router.replace(typeof number === "object" ? number : {path: '/'});
+    }
+};
+
+Vue.prototype.$A = $A;
+
+Vue.config.productionTip = false;
+
+const app = new Vue({
+    el: '#app',
+    router,
+    template: '<App/>',
+    components: { App }
+});
+
+$A.app = app;
+
+window.localStorage.setItem("__::WookTeam:check", "success")
+

+ 63 - 0
assets/js/main/components/DrawerTabsContainer.vue

@@ -0,0 +1,63 @@
+<template>
+    <div :class="[idDrawerTabs?'dtc-main':'']" :style="myStyle">
+        <div :class="[idDrawerTabs?'dtc-body':'']">
+            <slot/>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+    .dtc-main {
+        display: flex;
+        flex-direction: column;
+        width: 100%;
+        overflow: hidden;
+        position: relative;
+        transform: translateZ(0);
+
+        .dtc-body {
+            position: absolute;
+            left: 0;
+            right: 0;
+            top: 0;
+            bottom: 0;
+            width: 100%;
+            height: 100%;
+            overflow: auto;
+        }
+    }
+</style>
+<script>
+    export default {
+        name: 'DrawerTabsContainer',
+        data() {
+            return {
+                idDrawerTabs: false,
+                calculateHeight: 0,
+            }
+        },
+        mounted() {
+            let el = $A(this.$el);
+            let eb = el.parents(".ivu-drawer-body");
+            if (eb == 0 || eb.parents(".ivu-drawer-wrap").length == 0) {
+                return;
+            }
+            this.idDrawerTabs = true;
+            this.calculateHeight = Math.round(eb.outerHeight() - el.offset().top);
+            setInterval(() => {
+                this.calculateHeight = Math.round(eb.outerHeight() - el.offset().top);
+            }, 300);
+        },
+        computed: {
+            myStyle() {
+                const {calculateHeight, idDrawerTabs} = this;
+                if (!idDrawerTabs) {
+                    return {};
+                }
+                return {
+                    height: Math.max(0, calculateHeight - 16) + 'px'
+                }
+            }
+        },
+    }
+</script>

+ 178 - 0
assets/js/main/components/FullCalendar/FullCalendar.vue

@@ -0,0 +1,178 @@
+<template>
+    <div class="comp-full-calendar">
+        <!-- header pick month -->
+        <fc-header :current-date="currentDate"
+                   :title-format="titleFormat"
+                   :first-day="firstDay"
+                   :month-names="monthNames"
+                   :tableType="tableType"
+                   @change="changeDateRange">
+
+            <div slot="header-left">
+                <slot name="fc-header-left">
+                </slot>
+            </div>
+
+            <div slot="header-right" class="btn-group">
+                <div>
+                    <button :class="{cancel:tableType=='month',primary:tableType=='week'}" @click="changeType('week')">周</button>
+                    <button :class="{cancel:tableType=='week',primary:tableType=='month'}" @click="changeType('month')">月</button>
+                </Div>
+            </div>
+        </fc-header>
+        <!-- body display date day and events -->
+        <fc-body :current-date="currentDate" :events="events" :month-names="monthNames" ref="fcbody"
+                 :tableType="tableType"
+                 :loading="loading"
+                 :week-names="weekNames" :first-day="firstDay"
+                 :weekDays="weekDays"
+                 @eventclick="emitEventClick" @dayclick="emitDayClick"
+                 @moreclick="emitMoreClick">
+            <template slot="body-card">
+                <slot name="fc-body-card">
+                </slot>
+            </template>
+        </fc-body>
+    </div>
+</template>
+<script type="text/babel">
+    import langSets from './dataMap/langSets'
+    import fcBody from './components/body'
+    import fcHeader from './components/header'
+
+    export default {
+        name: "FullCalendar",
+        components: {
+            'fc-body': fcBody,
+            'fc-header': fcHeader
+        },
+        props: {
+            events: {
+                type: Array,
+                default: []
+            },
+            lang: {
+                type: String,
+                default: 'en'
+            },
+            firstDay: {
+                type: Number | String,
+                validator(val) {
+                    let res = parseInt(val)
+                    return res >= 0 && res <= 6
+                },
+                default: 0
+            },
+            titleFormat: {
+                type: String,
+                default() {
+                    return langSets[this.lang].titleFormat
+                }
+            },
+            monthNames: {
+                type: Array,
+                default() {
+                    return langSets[this.lang].monthNames
+                }
+            },
+            weekNames: {
+                type: Array,
+                default() {
+                    let arr = langSets[this.lang].weekNames
+                    return arr.slice(this.firstDay).concat(arr.slice(0, this.firstDay))
+                }
+            },
+            loading: {
+                type: Boolean,
+                default: false
+            },
+        },
+        data() {
+            return {
+                tableType: 'week',
+                weekDays: [],
+                currentDate: new Date()
+            }
+        },
+        methods: {
+            changeDateRange(start, end, currentStart, current, weekDays) {
+                this.currentDate = current
+                this.weekDays = weekDays;
+                this.$emit('change', start, end, currentStart, weekDays)
+            },
+            emitEventClick(event, jsEvent) {
+                this.$emit('eventClick', event, jsEvent)
+            },
+            emitDayClick(day, jsEvent) {
+                this.$emit('dayClick', day, jsEvent)
+            },
+            emitMoreClick(day, events, jsEvent) {
+                this.$emit('moreClick', day, event, jsEvent)
+            },
+            changeType(type) {
+                this.tableType = type;
+                this.$emit('changeType', type)
+            },
+        },
+    }
+
+</script>
+<style lang="scss">
+    .comp-full-calendar {
+        // font-family: "elvetica neue", tahoma, "hiragino sans gb";
+        // background: #fff;
+        min-width: 960px;
+        margin: 0 auto;
+
+        ul, p {
+            margin: 0;
+            padding: 0;
+            font-size: 14px;
+        }
+
+        .cancel {
+            border: 0;
+            outline: none;
+            box-shadow: unset;
+            background-color: #ECECED;
+            color: #8B8F94;
+
+            &:hover {
+                color: #3E444C;
+                z-index: 0;
+            }
+        }
+
+        .primary {
+            border: 0;
+            outline: none;
+            box-shadow: unset;
+            background-color: #2d8cf0;
+            color: #fff;
+
+            &:hover {
+                z-index: 0;
+            }
+        }
+
+        .btn-group {
+            width: 100%;
+            display: flex;
+            justify-content: flex-end;
+
+            > div {
+                display: flex;
+                align-items: center;
+                border-radius: 6px;
+                overflow: hidden;
+            }
+
+            button {
+                min-width: 48px;
+                cursor: pointer;
+                height: 28px;
+                padding: 0 12px;
+            }
+        }
+    }
+</style>

+ 787 - 0
assets/js/main/components/FullCalendar/components/body.vue

@@ -0,0 +1,787 @@
+<template>
+    <div class="full-calendar-body">
+
+        <div class="right-body">
+            <div class="weeks">
+                <div class="blank" v-if="tableType=='week'" style="width: 60px"></div>
+                <strong class="week" v-for="(week,index) in weekNames">
+                    {{week}}
+                    <span v-if="tableType=='week' && weekDate.length">({{weekDate[index].showDate}})</span>
+                </strong>
+            </div>
+            <div class="dates" ref="dates" v-if="tableType=='month'">
+                <Spin v-if="loading" fix></Spin>
+                <!-- absolute so we can make dynamic td -->
+                <div class="dates-events">
+                    <div class="events-week" v-for="week in currentDates"
+                         v-if="week[0].isCurMonth || week[week.length-1].isCurMonth">
+                        <div class="events-day" v-for="day in week" track-by="$index"
+                             :class="{'today': day.isToday, 'not-cur-month': !day.isCurMonth}">
+                            <p class="day-number">{{day.monthDay}}</p>
+                            <div class="event-box" v-if="day.events.length">
+                                <div class="event-item"
+                                     v-for="event in day.events"
+                                     :class="{selected: showCard == event.id}"
+                                     :style="{
+                                        'color': event.color||'#333333',
+                                        'background-color': showCard == event.id ? (event.selectedColor||'#C7E6FD') : (event.backgroundColor||'#C7E6FD'),
+                                     }"
+                                     @click="eventClick(event,$event)">
+                                    <img class="avatar" v-if="event.avatar" :src="event.avatar" @error="($set(event, 'avatar', null))"/>
+                                    <span v-else class="icon" :style="iconStyle(event.name)">{{event.name}}</span>
+                                    <p class="info" v-html="isBegin(event, day.date, day.weekDay)"></p>
+                                    <div id="card" :class="cardClass" v-if="$slots['body-card'] && event && showCard == event.id" @click.stop>
+                                        <slot name="body-card"></slot>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="time" ref="time" v-else-if="tableType=='week'">
+                <Spin v-if="loading" fix></Spin>
+                <!-- <div class="column" v-for="day in weekDate" v-if="weekDate.length">
+                  <div class="single" v-for="time in timeDivide"></div>
+                </div> -->
+                <div class="row" v-for="(time,index) in timeDivide">
+                    <div class="left-info" v-if="tableType=='week'">
+                        <div class="time-info first" v-if="index==0">
+                            <span class="center">{{$L('上午')}}</span>
+                        </div>
+                        <div class="time-info" v-if="index==1">
+                            <span class="top">12:00</span>
+                            <span class="center">{{$L('下午')}}</span>
+                        </div>
+                        <div class="time-info" v-if="index==2">
+                            <span class="top">18:00</span>
+                            <span class="center">{{$L('晚上')}}</span>
+                        </div>
+                    </div>
+                    <div class="events-day" v-for="item in weekDate" v-if="weekDate.length"
+                         :class="{today: item.isToday}">
+                        <div class="event-box" v-if="item.events.length">
+                            <div class="event-item"
+                                 v-for="event in item.events"
+                                 :class="{selected: showCard == event.id}"
+                                 :style="{
+                                    'color': event.color||'#333333',
+                                    'background-color': showCard == event.id ? (event.selectedColor||'#C7E6FD') : (event.backgroundColor||'#C7E6FD'),
+                                 }"
+                                 v-if="isTheday(item.date, event.start) && isInTime(time, event.start)"
+                                 @click="eventClick(event,$event)">
+                                <img class="avatar" v-if="event.avatar" :src="event.avatar" @error="($set(event, 'avatar', null))"/>
+                                <span v-else class="icon" :style="iconStyle(event.name)">{{event.name}}</span>
+                                <p class="info" v-html="event.title"></p>
+                                <div id="card" :class="cardClass" v-if="$slots['body-card'] && event && showCard == event.id" @click.stop>
+                                    <slot name="body-card"></slot>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script type="text/babel">
+    import dateFunc from './dateFunc'
+    import bus from './bus'
+
+    export default {
+        props: {
+            currentDate: {},
+            events: {
+                type: Array
+            },
+            weekNames: {
+                type: Array,
+                default: []
+            },
+            monthNames: {},
+            firstDay: {},
+            tableType: '',
+            weekDays: {
+                type: Array,
+                default() {
+                    return dateFunc.getDates(new Date())
+                }
+            },
+            isLimit: {
+                type: Boolean,
+                default: false
+            },
+            loading: {
+                type: Boolean,
+                default: true
+            }
+        },
+        created() {
+            let _this = this
+            document.addEventListener('click', function (e) {
+                _this.showCard = -1
+            });
+            // 监听header组件事件
+            bus.$on('changeWeekDays', res => {
+            });
+            //
+            this.initLanguage()
+        },
+        data() {
+            return {
+                // weekNames : DAY_NAMES,
+                weekMask: [1, 2, 3, 4, 5, 6, 7],
+                // events : [],
+                eventLimit: 18,
+                showMore: false,
+                morePos: {
+                    top: 0,
+                    left: 0
+                },
+                selectDay: {},
+                timeDivide: [],
+                showCard: -1,
+                cardLeft: 0,
+                cardRight: 0,
+            }
+        },
+
+        watch: {
+            // events(val){
+            //   this.getCalendar()
+            // },
+            currentDate() {
+                this.getCalendar()
+            }
+        },
+        computed: {
+            currentDates() {
+                return this.getCalendar()
+            },
+            weekDate() {
+                return this.getWeekDate()
+            }
+        },
+        methods: {
+            initLanguage() {
+                this.timeDivide = [{
+                    start: 0,
+                    end: 12,
+                    label: this.$L('上午')
+                }, {
+                    start: 12,
+                    end: 18,
+                    label: this.$L('下午')
+                }, {
+                    start: 18,
+                    end: 23,
+                    label: this.$L('晚上')
+                }];
+            },
+            isBegin(event, date, index) {
+                let st = new Date(event.start)
+
+                if (index == 0 || st.toDateString() == date.toDateString()) {
+                    return event.title
+                }
+                return ' '
+            },
+            moreTitle(date) {
+                let dt = new Date(date)
+                return this.weekNames[dt.getDay()] + ', ' + this.monthNames[dt.getMonth()] + dt.getDate()
+            },
+            classNames(cssClass) {
+                if (!cssClass) return ''
+                // string
+                if (typeof cssClass == 'string') return cssClass
+
+                // Array
+                if (Array.isArray(cssClass)) return cssClass.join(' ')
+
+                // else
+                return ''
+            },
+            getCalendar() {
+                // calculate 2d-array of each month
+                // first day of this month
+                let now = new Date() // today
+                let current = new Date(this.currentDate)
+
+                let startDate = dateFunc.getStartDate(current) // 1st day of this month
+
+                let curWeekDay = startDate.getDay()
+
+                // begin date of this table may be some day of last month
+                let diff = parseInt(this.firstDay) - curWeekDay + 1
+                diff = diff > 0 ? (diff - 7) : diff
+
+                startDate.setDate(startDate.getDate() + diff)
+                let calendar = []
+                for (let perWeek = 0; perWeek < 6; perWeek++) {
+
+                    let week = []
+
+                    for (let perDay = 0; perDay < 7; perDay++) {
+                        // console.log(startDate)
+                        week.push({
+                            monthDay: startDate.getDate(),
+                            isToday: now.toDateString() == startDate.toDateString(),
+                            isCurMonth: startDate.getMonth() == current.getMonth(),
+                            weekDay: perDay,
+                            date: new Date(startDate),
+                            events: this.slotEvents(new Date(startDate))
+                        })
+                        startDate.setDate(startDate.getDate() + 1)
+                    }
+                    calendar.push(week)
+                }
+                return calendar
+            },
+            slotEvents(date) {
+                // console.log(date)
+                let thisDayEvents = []
+                this.events.filter(event => {
+                    let day = new Date(event.start)
+                    if (date.toLocaleDateString() === day.toLocaleDateString()) {
+                        thisDayEvents.push(event)
+                    }
+                })
+                this.judgeTime(thisDayEvents)
+                return thisDayEvents
+            },
+            // 获取周视图的天元素格式化
+            getWeekDate() {
+                let newWeekDays = this.weekDays
+                newWeekDays.forEach((e, index) => {
+                    e.showDate = dateFunc.format(e, 'MM-dd');
+                    e.date = dateFunc.format(e, 'yyyy-MM-dd');
+                    e.isToday = (new Date().toDateString() == e.toDateString())
+                    e.events = this.slotTimeEvents(e) // 整理事件集合 (拿事件去比较时间,分发事件到时间插槽内)
+                })
+                return newWeekDays
+            },
+            // 发现该时间段所有的事件
+            slotTimeEvents(date) {
+                let thisDayEvents = this.events
+                thisDayEvents.filter(event => {
+                    let day = new Date(event.start)
+                    return date.toLocaleDateString() == day.toLocaleDateString()
+                })
+                this.judgeTime(thisDayEvents)
+                return thisDayEvents
+            },
+            judgeTime(arr) {
+                arr.forEach(event => {
+                    let day = new Date(event.start)
+                    // 加上时间戳后判断时间段
+                    let hour = day.getHours()
+                    let week = day.getDay()
+                    week == 0 ? week = 7 : ''
+                    if (this.timeDivide[0].start < hour < this.timeDivide[0].end) {
+                        event.time = 0
+                    } else if (this.timeDivide[1].start < hour < this.timeDivide[1].end) {
+                        event.time = 1
+                    } else if (this.timeDivide[2].start < hour < this.timeDivide[2].end) {
+                        event.time = 2
+                    }
+                    event.weekDay = this.weekNames[Number(week) - 1]
+                    event.weekDayIndex = week
+                })
+            },
+            isTheday(day1, day2) {
+                return new Date(day1).toDateString() === new Date(day2).toDateString()
+            },
+            isStart(eventDate, date) {
+                let st = new Date(eventDate)
+                return st.toDateString() == date.toDateString()
+            },
+            isEnd(eventDate, date) {
+                let ed = new Date(eventDate)
+                return ed.toDateString() == date.toDateString()
+            },
+            isInTime(time, date) {
+                let hour = new Date(date).getHours()
+                return (time.start <= hour) && (hour < time.end)
+            },
+            selectThisDay(day, jsEvent) {
+                this.selectDay = day
+                this.showMore = true
+                this.morePos = this.computePos(event.target)
+                this.morePos.top -= 100
+                let events = day.events.filter(item => {
+                    return item.isShow == true
+                })
+                this.$emit('moreclick', day.date, events, jsEvent)
+            },
+            computePos(target) {
+                let eventRect = target.getBoundingClientRect()
+                let pageRect = this.$refs.dates.getBoundingClientRect()
+                return {
+                    left: eventRect.left - pageRect.left,
+                    top: eventRect.top + eventRect.height - pageRect.top
+                }
+            },
+            dayClick(day, jsEvent) {
+                // console.log('dayClick')
+                // this.$emit('dayclick', day, jsEvent)
+            },
+            eventClick(event, jsEvent) {
+                // console.log(event,jsEvent, 'evenvet')
+                this.showCard = event.id
+                jsEvent.stopPropagation()
+                // let pos = this.computePos(jsEvent.target)
+                this.$emit('eventclick', event, jsEvent)
+                let x = jsEvent.x
+                let y = jsEvent.y
+                // console.log(jsEvent)
+                // 判断出左右中三边界的取值范围进而分配class
+                if (x > 400 && x < window.innerWidth - 200) {
+                    this.cardClass = "center-card"
+                } else if (x <= 400) {
+                    this.cardClass = "left-card"
+                } else {
+                    this.cardClass = "right-card"
+                }
+                if (y > window.innerHeight - 300) {
+                    this.cardClass += ' ' + 'bottom-card'
+                }
+            },
+            isEmojiPrefix(text) {
+                return /^[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(text);
+            },
+            iconStyle(name) {
+                const style = {
+                    backgroundColor: '#A0D7F1'
+                };
+                if (name) {
+                    let bgColor = '';
+                    for (let i = 0; i < name.length; i++) {
+                        bgColor += parseInt(name[i].charCodeAt(0), 10).toString(16);
+                    }
+                    style.backgroundColor = '#' + bgColor.slice(1, 4);
+                }
+                return style;
+            }
+        }
+    }
+</script>
+<style lang="scss">
+    .full-calendar-body {
+        background-color: #fff;
+        display: flex;
+        margin-top: 12px;
+        border-radius: 4px;
+        border: 1px solid #EEEEEE;
+
+        .left-info {
+            width: 60px;
+
+            .time-info {
+                height: 100%;
+                position: relative;
+
+                &:nth-child(2) {
+                    border-top: 1px solid #EFF2FF;
+                    border-bottom: 1px solid #EFF2FF;
+                }
+
+                .center {
+                    position: absolute;
+                    top: 50%;
+                    left: 50%;
+                    transform: translate(-50%, -50%);
+                    width: 14px;
+                    font-size: 14px;
+                    word-wrap: break-word;
+                    letter-spacing: 10px;
+                }
+
+                .top {
+                    position: absolute;
+                    top: -8px;
+                    width: 100%;
+                    text-align: center;
+                }
+            }
+        }
+
+        .right-body {
+            flex: 1;
+            width: 100%;
+            position: relative;
+
+            .weeks {
+                display: flex;
+                border-bottom: 1px solid #EEEEEE;
+
+                .week {
+                    flex: 1;
+                    text-align: center;
+                    height: 40px;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    font-weight: normal;
+                }
+            }
+
+            .dates {
+                position: relative;
+                .dates-events {
+                    z-index: 1;
+                    width: 100%;
+
+                    .events-week {
+                        display: flex;
+                        min-height: 180px;
+
+                        .events-day {
+                            text-overflow: ellipsis;
+                            flex: 1;
+                            width: 0;
+                            height: auto;
+                            padding: 4px;
+                            border-right: 1px solid #EFF2FF;
+                            border-bottom: 1px solid #EFF2FF;
+                            background-color: #fff;
+
+                            .day-number {
+                                text-align: left;
+                                padding: 4px 5px 4px 4px;
+                            }
+
+                            &.not-cur-month {
+                                .day-number {
+                                    color: #ECECED;
+                                }
+                            }
+
+                            &.today {
+                                background-color: #F9FAFB;
+                            }
+
+                            &:last-child {
+                                border-right: 0;
+                            }
+
+                            .event-box {
+                                max-height: 280px;
+                                overflow: auto;
+                                .event-item {
+                                    cursor: pointer;
+                                    font-size: 12px;
+                                    background-color: #C7E6FD;
+                                    margin-bottom: 4px;
+                                    color: rgba(0, 0, 0, .87);
+                                    padding: 6px 0 6px 4px;
+                                    height: auto;
+                                    line-height: 30px;
+                                    display: flex;
+                                    // transform:translate(0,0);
+                                    align-items: flex-start;
+                                    position: relative;
+                                    border-radius: 4px;
+
+                                    &.is-end {
+                                        display: none;
+                                    }
+
+                                    &.is-start {
+                                        display: block;
+                                    }
+
+                                    &.is-opacity {
+                                        display: none;
+                                    }
+
+                                    .avatar {
+                                        width: 18px;
+                                        height: 18px;
+                                        border: 0;
+                                        border-radius: 50%;
+                                        overflow: hidden;
+                                        display: inline-block;
+                                    }
+
+                                    .icon {
+                                        width: 18px;
+                                        height: 18px;
+                                        line-height: 18px;
+                                        border-radius: 10px;
+                                        text-align: center;
+                                        color: #fff;
+                                        display: inline-block;
+                                        overflow: hidden;
+                                    }
+
+                                    .info {
+                                        width: calc(100% - 30px);
+                                        display: inline-block;
+                                        margin-left: 5px;
+                                        line-height: 18px;
+                                        word-break: break-all;
+                                        word-wrap: break-word;
+                                        font-size: 12px;
+                                    }
+
+                                    #card {
+                                        cursor: initial;
+                                        position: absolute;
+                                        z-index: 999;
+                                        min-width: 250px;
+                                        height: auto;
+                                        left: 50%;
+                                        top: calc(100% + 10px);
+                                        transform: translate(-50%, 0);
+                                        min-height: 100px;
+                                        background: #fff;
+                                        // border: 1px solid #eee;
+                                        box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.1);
+                                        border-radius: 4px;
+                                        overflow: hidden;
+
+                                        &.left-card {
+                                            left: 0;
+                                            transform: translate(0, 0);
+                                        }
+
+                                        &.right-card {
+                                            right: 0;
+                                            left: auto;
+                                            transform: translate(0, 0);
+                                        }
+
+                                        &.bottom-card {
+                                            top: auto;
+                                            bottom: calc(100% + 10px);
+                                        }
+                                    }
+
+                                    &:hover {
+                                        .info {
+                                            // font-weight: bold;
+                                        }
+                                    }
+
+                                    &.selected {
+                                        /*.info {
+                                            color: #fff;
+                                            font-weight: normal;
+                                        }
+
+                                        .icon {
+                                            background-color: transparent !important;
+                                        }*/
+                                    }
+                                }
+
+                                .more-link {
+                                    cursor: pointer;
+                                    // text-align: right;
+                                    padding-left: 8px;
+                                    padding-right: 2px;
+                                    color: rgba(0, 0, 0, .38);
+                                    font-size: 12px;
+                                }
+                            }
+                        }
+
+                        &:last-child {
+                            .events-day {
+                                border-bottom: 0;
+                            }
+                        }
+                    }
+                }
+
+                .more-events {
+                    position: absolute;
+                    width: 150px;
+                    z-index: 2;
+                    border: 1px solid #eee;
+                    box-shadow: 0 2px 6px rgba(0, 0, 0, .15);
+
+                    .more-header {
+                        background-color: #eee;
+                        padding: 5px;
+                        display: flex;
+                        align-items: center;
+                        font-size: 14px;
+
+                        .title {
+                            flex: 1;
+                        }
+
+                        .close {
+                            margin-right: 2px;
+                            cursor: pointer;
+                            font-size: 16px;
+                        }
+                    }
+
+                    .more-body {
+                        height: 125px;
+                        overflow: hidden;
+                        background: #fff;
+
+                        .body-list {
+                            height: 120px;
+                            padding: 5px;
+                            overflow: auto;
+                            background-color: #fff;
+
+                            .body-item {
+                                cursor: pointer;
+                                font-size: 12px;
+                                background-color: #C7E6FD;
+                                margin-bottom: 2px;
+                                color: rgba(0, 0, 0, .87);
+                                padding: 0 0 0 4px;
+                                height: 18px;
+                                line-height: 18px;
+                                white-space: nowrap;
+                                overflow: hidden;
+                                text-overflow: ellipsis;
+                            }
+                        }
+                    }
+                }
+            }
+
+            .time {
+                position: relative;
+                .row {
+                    width: 100%;
+                    display: flex;
+                    min-height: 180px;
+
+                    .events-day {
+                        border-bottom: 1px solid #EFF2FF;
+                        border-left: 1px solid #EFF2FF;
+                        background-color: #fff;
+                        height: auto;
+                        text-overflow: ellipsis;
+                        flex: 1;
+                        width: 0;
+                        padding: 4px;
+
+                        .event-box {
+                            max-height: 280px;
+                            overflow: auto;
+                        }
+
+                        &.today {
+                            background-color: #F9FAFB;
+                        }
+                    }
+
+                    .event-item {
+                        cursor: pointer;
+                        font-size: 12px;
+                        background-color: #C7E6FD;
+                        margin-bottom: 4px;
+                        color: rgba(0, 0, 0, .87);
+                        padding: 6px 0 6px 4px;
+                        height: auto;
+                        line-height: 30px;
+                        display: flex;
+                        align-items: flex-start;
+                        position: relative;
+                        border-radius: 4px;
+
+                        .avatar {
+                            width: 18px;
+                            height: 18px;
+                            border: 0;
+                            border-radius: 50%;
+                            overflow: hidden;
+                            display: inline-block;
+                        }
+
+                        .icon {
+                            width: 18px;
+                            height: 18px;
+                            line-height: 18px;
+                            border-radius: 10px;
+                            text-align: center;
+                            color: #fff;
+                            display: inline-block;
+                            padding: 0 2px;
+                            overflow: hidden;
+                        }
+
+                        .info {
+
+                            width: calc(100% - 30px);
+                            display: inline-block;
+                            margin-left: 5px;
+                            line-height: 18px;
+                            word-break: break-all;
+                            word-wrap: break-word;
+                            font-size: 12px;
+                        }
+
+                        #card {
+                            cursor: initial;
+                            position: absolute;
+                            z-index: 999;
+                            min-width: 250px;
+                            height: auto;
+                            left: 50%;
+                            top: calc(100% + 10px);
+                            transform: translate(-50%, 0);
+                            min-height: 100px;
+                            background: #fff;
+                            box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.1);
+                            border-radius: 4px;
+                            overflow: hidden;
+
+                            &.left-card {
+                                left: 0;
+                                transform: translate(0, 0);
+                            }
+
+                            &.right-card {
+                                right: 0;
+                                left: auto;
+                                transform: translate(0, 0);
+                            }
+
+                            &.bottom-card {
+                                top: auto;
+                                bottom: calc(100% + 10px);
+                            }
+                        }
+
+                        &:hover {
+                            .info {
+                                // font-weight: bold;
+                            }
+                        }
+
+                        &.selected {
+                            /*.info {
+                                color: #fff;
+                                font-weight: normal;
+                            }
+
+                            // background-color: #5272FF !important;
+                            .icon {
+                                background-color: transparent !important;
+                            }*/
+                        }
+                    }
+
+                    &:last-child {
+                        .events-day {
+                            border-bottom: 0;
+                        }
+                        .single {
+                            border-bottom: 0;
+                        }
+                    }
+                }
+            }
+        }
+    }
+</style>

+ 3 - 0
assets/js/main/components/FullCalendar/components/bus.js

@@ -0,0 +1,3 @@
+import Vue from 'vue'
+
+export default new Vue()

+ 106 - 0
assets/js/main/components/FullCalendar/components/dateFunc.js

@@ -0,0 +1,106 @@
+let shortMonth = [
+    'Jan',
+    'Feb',
+    'Mar',
+    'Apr',
+    'May',
+    'Jun',
+    'Jul',
+    'Aug',
+    'Sep',
+    'Oct',
+    'Nov',
+    'Dec'
+]
+let defMonthNames = [
+    'January',
+    'February',
+    'March',
+    'April',
+    'May',
+    'June',
+    'July',
+    'August',
+    'September',
+    'October',
+    'November',
+    'December'
+]
+
+let dateFunc = {
+    getDuration(date) {
+        // how many days of this month
+        let dt = new Date(date)
+        let month = dt.getMonth();
+        dt.setMonth(dt.getMonth() + 1)
+        dt.setDate(0);
+        return dt.getDate()
+    },
+    changeDay(date, num) {
+        let dt = new Date(date)
+        return new Date(dt.setDate(dt.getDate() + num))
+    },
+    getStartDate(date) {
+        // return first day of this month
+        // console.log(new Date(date.getFullYear(), date.getMonth(), 1,0,0))
+        return new Date(date.getFullYear(), date.getMonth(), 1)
+    },
+    getEndDate(date) {
+        // get last day of this month
+        let dt = new Date(date.getFullYear(), date.getMonth() + 1, 1, 0, 0) // 1st day of next month
+        return new Date(dt.setDate(dt.getDate() - 1)) // last day of this month
+    },
+    // 获取当前周日期数组
+    getDates(date) {
+        let new_Date = date
+        let timesStamp = new Date(new_Date.getFullYear(), new_Date.getMonth(), new_Date.getDate(), 0, 0, 0).getTime()
+        // let timesStamp = new_Date.getTime();
+        let currenDay = new_Date.getDay();
+        let dates = [];
+        for (let i = 0; i < 7; i++) {
+            dates.push(new Date(timesStamp + 24 * 60 * 60 * 1000 * (i - (currenDay + 6) % 7)));
+        }
+        return dates
+    },
+    format(date, format, monthNames) {
+        monthNames = monthNames || defMonthNames
+        if (typeof date === 'string') {
+            date = new Date(date.replace(/-/g, '/'))
+        } else {
+            date = new Date(date)
+        }
+
+        let map = {
+            'M': date.getMonth() + 1,
+            'd': date.getDate(),
+            'h': date.getHours(),
+            'm': date.getMinutes(),
+            's': date.getSeconds(),
+            'q': Math.floor((date.getMonth() + 3) / 3),
+            'S': date.getMilliseconds()
+        }
+
+        format = format.replace(/([yMdhmsqS])+/g, (all, t) => {
+            let v = map[t]
+            if (v !== undefined) {
+                if (all === 'MMMM') {
+                    return monthNames[v - 1]
+                }
+                if (all === 'MMM') {
+                    return shortMonth[v - 1]
+                }
+                if (all.length > 1) {
+                    v = '0' + v
+                    v = v.substr(v.length - 2)
+                }
+                return v
+            } else if (t === 'y') {
+                return String(date.getFullYear()).substr(4 - all.length)
+            }
+            return all
+        })
+        return format
+    }
+}
+
+module.exports = dateFunc

+ 130 - 0
assets/js/main/components/FullCalendar/components/header.vue

@@ -0,0 +1,130 @@
+<template>
+    <div class="full-calendar-header">
+        <div class="header-left">
+            <slot name="header-left"></slot>
+        </div>
+        <div class="header-center">
+            <span class="prev-month" @click.stop="goPrev">{{leftArrow}}</span>
+            <span class="title">{{title}}</span>
+            <span class="next-month" @click.stop="goNext">{{rightArrow}}</span>
+        </div>
+        <div class="header-right">
+            <slot name="header-right"></slot>
+        </div>
+    </div>
+</template>
+<script type="text/babel">
+    import dateFunc from './dateFunc'
+    import bus from './bus'
+
+    export default {
+        created() {
+            this.dispatchEvent(this.tableType)
+        },
+        props: {
+            currentDate: {},
+            titleFormat: {},
+            firstDay: {},
+            monthNames: {},
+            tableType: ''
+        },
+        data() {
+            return {
+                title: '',
+                leftArrow: '<',
+                rightArrow: '>',
+                headDate: new Date()
+            }
+        },
+        watch: {
+            currentDate(val) {
+                if (!val) return
+                this.headDate = val
+            },
+            tableType(val) {
+                this.dispatchEvent(this.tableType)
+            }
+        },
+        methods: {
+            goPrev() {
+                this.headDate = this.changeDateRange(this.headDate, -1)
+                this.dispatchEvent(this.tableType)
+            },
+            goNext() {
+                this.headDate = this.changeDateRange(this.headDate, 1)
+                this.dispatchEvent(this.tableType)
+            },
+            changeDateRange(date, num) {
+                let dt = new Date(date)
+                if (this.tableType == 'month') {
+                    return new Date(dt.setMonth(dt.getMonth() + num))
+                } else {
+                    return new Date(dt.valueOf() + num * 7 * 24 * 60 * 60 * 1000)
+                }
+            },
+            dispatchEvent(type) {
+                if (type == 'month') {
+                    this.title = dateFunc.format(this.headDate, this.titleFormat, this.monthNames)
+                    let startDate = dateFunc.getStartDate(this.headDate)
+                    let curWeekDay = startDate.getDay()
+                    // 1st day of this monthView
+                    let diff = parseInt(this.firstDay) - curWeekDay
+                    if (diff) diff -= 7
+                    startDate.setDate(startDate.getDate() + diff)
+
+                    // the month view is 6*7
+                    let endDate = dateFunc.changeDay(startDate, 41)
+
+                    // 1st day of current month
+                    let currentDate = dateFunc.getStartDate(this.headDate)
+                    this.$emit('change',
+                        dateFunc.format(startDate, 'yyyy-MM-dd'),
+                        dateFunc.format(endDate, 'yyyy-MM-dd'),
+                        dateFunc.format(currentDate, 'yyyy-MM-dd'),
+                        this.headDate
+                    )
+                } else if (type == 'week') {
+                    let weekDays = dateFunc.getDates(this.headDate)
+
+                    this.title = dateFunc.format(weekDays[0], 'MM-dd') + `  至  ` + dateFunc.format(weekDays[6], 'MM-dd')
+                    this.$emit('change',
+                        dateFunc.format(weekDays[0], 'yyyy-MM-dd'),
+                        dateFunc.format(weekDays[6], 'yyyy-MM-dd'),
+                        dateFunc.format(weekDays[0], 'yyyy-MM-dd'),
+                        this.headDate,
+                        weekDays
+                    )
+                    bus.$emit('changeWeekDays', weekDays)
+                }
+            },
+
+        }
+    }
+</script>
+<style lang="scss">
+    .full-calendar-header {
+        display: flex;
+        align-items: center;
+
+        .header-left, .header-right {
+            flex: 1;
+        }
+
+        .header-center {
+            flex: 3;
+            text-align: center;
+            user-select: none;
+            font-weight: bold;
+
+            .title {
+                margin: 0 5px;
+                width: 150px;
+            }
+
+            .prev-month, .next-month {
+                cursor: pointer;
+                padding: 10px 15px;
+            }
+        }
+    }
+</style>

+ 17 - 0
assets/js/main/components/FullCalendar/dataMap/langSets.js

@@ -0,0 +1,17 @@
+export default {
+    en: {
+        weekNames: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+        monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+        titleFormat: 'MMMM yyyy'
+    },
+    zh: {
+        weekNames: ['周一', '周二', '周三', '周四', '周五', '周六', '周日',],
+        monthNames: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
+        titleFormat: 'yyyy年MM月'
+    },
+    fr: {
+        weekNames: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
+        monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
+        titleFormat: 'MMMM yyyy'
+    }
+}

+ 5 - 0
assets/js/main/components/FullCalendar/index.js

@@ -0,0 +1,5 @@
+import vueFullcalendar from './fullCalendar'
+
+const fc = vueFullcalendar
+
+module.exports = fc

+ 597 - 0
assets/js/main/components/ImgUpload.vue

@@ -0,0 +1,597 @@
+<template>
+    <div>
+        <div v-if="type !== 'callback'" class="imgcomp-upload-list" v-for="item in uploadList">
+            <template v-if="item.status === 'finished'">
+                <div class="imgcomp-upload-img" v-bind:style="{ 'background-image': 'url(' + __thumb(item.thumb) + ')' }"></div>
+                <div class="imgcomp-upload-list-cover">
+                    <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>
+                    <Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
+                </div>
+            </template>
+            <template v-else>
+                <Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
+            </template>
+        </div>
+        <div class="add-box" v-bind:class="{ 'callback-add-box': type === 'callback' }">
+            <div class="add-box-icon">
+                <Icon type="md-add" size="32"></Icon>
+            </div>
+            <div class="add-box-upload">
+                <div class="add-box-item" @click="browsePicture">
+                    <span>{{$L('浏览')}}<em v-if="type === 'callback'">{{$L('图片')}}</em></span>
+                </div>
+                <div class="add-box-item">
+                    <Upload
+                            name="image"
+                            ref="upload"
+                            accept="image/*"
+                            :action="actionUrl"
+                            :data="uploadParams"
+                            :show-upload-list="false"
+                            :max-size="maxSize"
+                            :format="['jpg', 'jpeg', 'gif', 'png']"
+                            :default-file-list="defaultList"
+                            :on-progress="handleProgress"
+                            :on-success="handleSuccess"
+                            :on-error="handleError"
+                            :on-format-error="handleFormatError"
+                            :on-exceeded-size="handleMaxSize"
+                            :before-upload="handleBeforeUpload"
+                            :multiple=multiple>
+                        <span>{{$L('上传')}}<em v-if="type === 'callback'">{{$L('图片')}}</em></span>
+                    </Upload>
+                </div>
+            </div>
+        </div>
+        <Modal :title="$L('浏览图片空间的图片')" v-model="browseVisible" class="img-upload-modal" class-name="simple-modal" width="710" :styles="{top: '35px',paddingBottom: '35px'}">
+            <div class="browse-load" v-if="isLoading">{{$L('加载中...')}}</div>
+            <div class="browse-list" :class="httpType==='input'?'browse-list-disabled':''" ref="browselistbox">
+                <div class="browse-item" v-for="item in browseList" @click="browseItem(item)">
+                    <Icon v-if="item.active" class="browse-icon" type="ios-checkmark-circle"></Icon>
+                    <div class="browse-img" v-bind:style="{ 'background-image': 'url(' + item.thumb + ')' }"></div>
+                    <div class="browse-title">{{item.title}}</div>
+                </div>
+            </div>
+            <div slot="footer" class="img-upload-foot">
+                <div v-if="type !== 'callback' && http && httpType===''" class="img-upload-foot-input" @click="httpType='input'">
+                    <Icon type="ios-image" size="22"/>
+                    <div class="img-upload-foot-httptitle">{{$L('自定义图片地址')}}</div>
+                </div>
+                <div v-if="type !== 'callback' && http && httpType==='input'" class="img-upload-foot-input">
+                    <Input v-model="httpValue" :placeholder="$L('以“http://”或“https://”开头')" @on-search="httpEnter" search :enter-button="$L('确定')">
+                        <span slot="prepend" @click="httpType=''" style="cursor:pointer">{{$L('自定义地址')}}: </span>
+                    </Input>
+                </div>
+                <Button v-if="httpType===''" @click="browseVisible=false">{{$L('关闭')}}</Button>
+                <Button v-if="httpType===''" type="primary" @click="handleCallback(true)">{{$L('完成')}}</Button>
+            </div>
+        </Modal>
+        <Modal :title="$L('查看图片')" v-model="visible" class="img-upload-modal" class-name="simple-modal" draggable>
+            <div style="max-height:480px;overflow:auto;">
+                <a :href="imgVisible" target="_blank"><img :src="imgVisible" v-if="visible" style="max-width:100%;max-height:900px;display:block;margin:0 auto"></a>
+            </div>
+        </Modal>
+    </div>
+</template>
+
+<style lang="scss">
+    .img-upload-modal {
+        .ivu-modal-mask {
+            z-index: 1001;
+        }
+        .ivu-modal-no-mask {
+            background-color: rgba(55,55,55,.2);
+        }
+        .ivu-modal-wrap {
+            z-index: 1001;
+        }
+    }
+    .imgcomp-upload-list{
+        display: inline-block;
+        width: 60px;
+        height: 60px;
+        text-align: center;
+        line-height: 60px;
+        border: 1px solid transparent;
+        border-radius: 4px;
+        overflow: hidden;
+        background: #fff;
+        position: relative;
+        box-shadow: 0 1px 1px rgba(0,0,0,.2);
+        margin-right: 4px;
+        vertical-align: top;
+        .imgcomp-upload-img {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            background-position: center;
+            background-size: cover;
+        }
+        .imgcomp-upload-list-cover{
+            display: none;
+            position: absolute;
+            top: 0;
+            bottom: 0;
+            left: 0;
+            right: 0;
+            background: rgba(0,0,0,.6);
+        }
+        .imgcomp-upload-list-cover i{
+            color: #fff;
+            font-size: 24px;
+            cursor: pointer;
+            vertical-align: middle;
+            margin: 0;
+            transition: all .2s;
+        }
+        .imgcomp-upload-list-cover i:hover{
+            font-size: 28px;
+        }
+        .ivu-progress-outer {
+            background-color: rgba(0, 0, 0, 0.68);
+            .ivu-progress-inner{
+                width: 88%;
+            }
+        }
+    }
+    .imgcomp-upload-list:hover .imgcomp-upload-list-cover{
+        display: block;
+    }
+    .img-upload-foot {
+        display: flex;
+        align-items: center;
+        justify-content: flex-end;
+        .img-upload-foot-input {
+            flex: 1;
+            text-align: left;
+            display: flex;
+            align-items: center;
+            justify-content: flex-end;
+            .img-upload-foot-httptitle {
+                cursor: pointer;
+                padding-left: 3px;
+                margin-right: 22px;
+            }
+        }
+    }
+    .add-box {
+        width: 60px;
+        height: 60px;
+        line-height: 60px;
+        display: inline-block;
+        background: #fff;
+        border: 1px dashed #dddee1;
+        border-radius: 4px;
+        text-align: center;
+        position: relative;
+        overflow: hidden;
+        vertical-align: top;
+        .add-box-icon {
+            i {
+                vertical-align:middle;
+                padding-bottom: 2px;
+            }
+        }
+        .add-box-upload {
+            display: none;
+            position: absolute;
+            top: 0;
+            left: 0;
+            height: 100%;
+            width: 100%;
+            color: #ffffff;
+            padding-top: 9px;
+            background: rgba(0, 0, 0, 0.6);
+            .add-box-item {
+                height: 22px;
+                line-height: 22px;
+                cursor: pointer;
+                .ivu-upload-drag,.ivu-upload-drag:hover {
+                    background:transparent;
+                    border:0;
+                    border-radius:0;
+                }
+                span {
+                    transition: all .2s;
+                    font-size: 12px;
+                }
+            }
+            .add-box-item:hover {
+                span {
+                    font-size: 14px;
+                }
+            }
+        }
+        em {
+            font-style: normal;
+        }
+    }
+    .add-box:hover {
+        border-color: rgba(0,0,0,.6);
+        .add-box-upload {
+            display: block;
+        }
+    }
+    .callback-add-box {
+        display: block;
+        width: auto;
+        height: 25px;
+        line-height: 25px;
+        border: 0;
+        background: transparent;
+        .add-box-icon {
+            display: none;
+        }
+        .add-box-upload {
+            display: block;
+            width: auto;
+            background: transparent;
+            color: #333;
+            padding: 0;
+            > div {
+                display: inline-block;
+                padding-right: 10px;
+            }
+        }
+    }
+    .browse-load {
+        margin: 20px;
+        text-align: center;
+    }
+    .browse-list {
+        max-height: 540px;
+        overflow: auto;
+        .browse-item {
+            margin: 10px 15px;
+            display: inline-block;
+            text-align: center;
+            cursor: pointer;
+            position: relative;
+            .browse-img {
+                width: 64px;
+                height: 64px;
+                background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKoAAABxCAAAAABg5GeyAAACW0lEQVR4Ae3XVRLjMBAE0L3/rSwKM3OcSNPyLVYOLvM6UD0Bd03LVe9XH+RlhlRSSSWVVFJJJZVUUkkllVRSSSWVVFJJJZVUUkl9WyqppJJKKqmkkgpURP17xngOAR5NxW5wlJ9MaLQh83F4NHWmd/gZtdVBaOldfDB1bq5UpJFbFOC6LKnYrkRO209PAw+hIuzWB8Ep5es8HvYo4z4tE1X8UeRwlMM2D5Bzkc7kj6Bi3VTKDDwEeUcrMxrUvGDXTnHa6kK69SDN9sgq1clxKSbNHqqnYmdri81Q9QHf1JPt1Frncaib2XbiTKL2GkHaurnY9LOulMV0O7G6Kw+g9sw2ohhm62KezVJaaufjWC1TnOkr1exilJ7Ji0vxCCqO9V4UwV4PYr9+apouhGYLKfnahdpqegjmeoXOpXgANe70pKT6Zhu19qkY2nC0PZS527lQOyInqr8Uvc5jqfUb1X+PGh5IhW90S2quh3FQC2XRcF66TUkTXPcLKm5FtdR9RJq+2hWII7UpFtmsQLEyzsdJtkxxpr6gLotbUSlV9yeT0Trmzk2XPdUThLYarUbWOY9j04xXQ2u+pMZLYSumGmNUH3HbM9qOAwSHodN2Pks25F2j3aI7+IxqNsB+YLWb16ukSjiW4xNB0gMoMfApBS/XZQgi3p9/5RsiKNKZEOwYFVIF5VyTyD19sbyjIJiNJRZxpNbx2S8sGKvGZNHJBniBu9Wy5WxjGuQFqIAcBHiRGyt4ua5gSCWVVFJJJZVUUkkllVRSSSWVVFJJJZVUUkkllVRSSSWVVFI/AgO0SXIVYHeGAAAAAElFTkSuQmCC);
+                background-position: center;
+                background-repeat: no-repeat;
+                background-size: cover;
+            }
+            .browse-title {
+                display: block;
+                width: 64px;
+                margin-top: 5px;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+            }
+            .browse-icon {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 64px;
+                font-size: 36px;
+                padding-top: 15px;
+                color: #ffffff;
+                background-color: rgba(0, 0, 0, 0.5);
+            }
+        }
+    }
+    .browse-list-disabled {
+        position: relative;
+    }
+    .browse-list-disabled:after {
+        position: absolute;
+        content: '';
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        background-color: rgba(255, 255, 255, 0.9);
+        z-index: 1;
+    }
+</style>
+<script>
+    export default {
+        name: 'ImgUpload',
+        props: {
+            value: {
+            },
+            num: {
+            },
+            width: {
+            },
+            height: {
+            },
+            type: {
+            },
+            http: {
+                type: Boolean,
+                default: false
+            },
+            otherParams: {
+                type: Object,
+                default: () => {
+                    return {};
+                }
+            },
+            uploadIng: {
+                type: Number,
+                default: 0
+            }
+        },
+        data () {
+            return {
+                actionUrl: $A.apiUrl('system/imgupload'),
+                params: {
+                    token: $A.getToken(),
+                    width: this.width,
+                    height: this.height
+                },
+                multiple: this.num > 1,
+                visible: false,
+                browseVisible: false,
+                isLoading: false,
+                browseList: [],
+                browseListNext: [],
+                imgVisible: '',
+                defaultList: this.initItems(this.value),
+                uploadList: [],
+                maxNum: Math.min(Math.max($A.runNum(this.num), 1), 99),
+                httpValue: '',
+                httpType: '',
+                maxSize: 204800
+            }
+        },
+        mounted () {
+            this.uploadList = this.$refs.upload.fileList;
+            this.$emit('input', this.uploadList);
+            //
+            let browseBox = $A(this.$refs.browselistbox);
+            browseBox.scroll(()=>{
+                let nHight = browseBox[0].scrollHeight;
+                let nTop = browseBox[0].scrollTop;
+                let boxHight = browseBox.height();
+                if(nTop + boxHight >= nHight) {
+                    //到底了
+                    if (this.browseListNext.length > 0) {
+                        let tmpNext = this.browseListNext;
+                        this.browseListNext = [];
+                        this.browsePictureFor(tmpNext);
+                    }
+                }
+            });
+        },
+        watch: {
+            value (val) {
+                if (typeof val === 'string') {
+                    this.$emit('input', this.initItems(val));
+                    return;
+                }
+                if (val === this.$refs.upload.fileList) {
+                    return;
+                }
+                this.$refs.upload.fileList = this.initItems(val);
+                this.uploadList = this.$refs.upload.fileList;
+            },
+            browseVisible() {
+                this.httpType = '';
+                this.httpValue = '';
+            }
+        },
+        computed: {
+            uploadParams() {
+                if (Object.keys(this.otherParams).length > 0) {
+                    return Object.assign(this.params, this.otherParams);
+                } else {
+                    return this.params;
+                }
+            }
+        },
+        methods: {
+            handleCallback(file) {
+                if (this.type === 'callback') {
+                    if (file === true) {
+                        this.$emit('on-callback', this.uploadList);
+                        this.$refs.upload.fileList = [];
+                        this.uploadList = this.$refs.upload.fileList;
+                    }else if (typeof file === "object") {
+                        this.$emit('on-callback', [file]);
+                    }
+                }
+                this.browseVisible = false;
+            },
+            initItems(items) {
+                //数据初始化
+                if (typeof items === 'string') {
+                    items = [{'url': items}];
+                }
+                let lists = [];
+                $A.each(items, (index, item)=>{
+                    if (typeof item === 'string') item = {'url': item};
+                    if (item.url) {
+                        item.active = true;
+                        item.status = 'finished';
+                        if (typeof item.path === 'undefined') item.path = item.url;
+                        if (typeof item.thumb === 'undefined') item.thumb = item.url;
+                        lists.push(item);
+                    }
+                });
+                return lists;
+            },
+            handleView (item) {
+                //查看
+                this.visible = true;
+                this.imgVisible = item.url;
+            },
+            handleRemove (item) {
+                //删除
+                let fileList = this.$refs.upload.fileList;
+                this.$refs.upload.fileList.splice(fileList.indexOf(item), 1);
+                this.$emit('input', this.$refs.upload.fileList);
+            },
+            handleProgress() {
+                //开始上传
+                this.$emit('update:uploadIng', this.uploadIng + 1);
+            },
+            handleSuccess (res, file) {
+                //上传完成
+                this.$emit('update:uploadIng', this.uploadIng - 1);
+                if (res.ret === 1) {
+                    file.url = res.data.url;
+                    file.path = res.data.path;
+                    file.thumb = res.data.thumb;
+                    this.handleCallback(file);
+                }else{
+                    this.$Modal.warning({
+                        title: this.$L('上传失败'),
+                        content: this.$L('文件 % 上传失败 %', file.name, res.msg)
+                    });
+                    this.$refs.upload.fileList.pop();
+                }
+                this.$emit('input', this.$refs.upload.fileList);
+            },
+            handleError() {
+                //上传错误
+                this.$emit('update:uploadIng', this.uploadIng - 1);
+            },
+            handleFormatError (file) {
+                //上传类型错误
+                this.$Modal.warning({
+                    title: this.$L('文件格式不正确'),
+                    content: this.$L('文件 % 格式不正确,请上传 jpg、jpeg、gif、png 格式的图片。', file.name)
+                });
+            },
+            handleMaxSize (file) {
+                //上传大小错误
+                this.$Modal.warning({
+                    title: this.$L('超出文件大小限制'),
+                    content: this.$L('文件 % 太大,不能超过%。', file.name, $A.bytesToSize(this.maxSize * 1024))
+                });
+            },
+            handleBeforeUpload () {
+                //上传前判断
+                let check = this.uploadList.length < this.maxNum;
+                if (!check && this.uploadList.length == 1) {
+                    this.handleRemove(this.uploadList[0]);
+                    check = this.uploadList.length < this.maxNum;
+                }
+                if (!check) {
+                    this.$Modal.warning({
+                        title: this.$L('温馨提示'),
+                        content: this.$L('最多只能上传 % 张图片。', this.maxNum)
+                    });
+                }
+                this.params = {
+                    token: $A.getToken(),
+                    width: this.width,
+                    height: this.height
+                };
+                return check;
+            },
+            handleClick() {
+                //手动上传
+                if (this.handleBeforeUpload()) {
+                    this.$refs.upload.handleClick()
+                }
+            },
+            handleManual(file) {
+                //手动传file
+                if (this.handleBeforeUpload()) {
+                    this.$refs.upload.upload(file);
+                }
+            },
+            browsePicture(path) {
+                //获取图片空间
+                this.browseVisible = true;
+                this.browseList = [];
+                this.browseListNext = [];
+                this.isLoading = true;
+                $A.apiAjax({
+                    url: 'system/imgview',
+                    data: { path: path?path:'' },
+                    beforeSend: true,
+                    complete: true,
+                    error: true,
+                    success: (res) => {
+                        this.isLoading = false;
+                        if (res.ret === 1) {
+                            let dirs = res.data['dirs'];
+                            for (let i = 0; i < dirs.length; i++) {
+                                this.browseList.push(dirs[i]);
+                            }
+                            this.browsePictureFor(res.data['files']);
+                        }else if (res.ret === -2) {
+                            this.browseVisible = false;
+                            this.$Modal.warning({ title: this.$L('温馨提示'), content: res.msg });
+                        }
+                    }
+                });
+            },
+
+            browsePictureFor(files) {
+                for (let o = 0; o < files.length; o++) {
+                    for (let j = 0; j < this.uploadList.length; j++) {
+                        if (this.uploadList[j]['url'] === files[o]['url']
+                            || this.uploadList[j]['url'] === files[o]['path']) {
+                            files[o]['active'] = true;
+                            break;
+                        }
+                    }
+                    if (o < 100) {
+                        this.browseList.push(files[o]);
+                    }else{
+                        this.browseListNext.push(files[o]);
+                    }
+                }
+            },
+
+            browseItem(item) {
+                //点击选择图片
+                if (item.type === 'dir') {
+                    //目录
+                    this.browsePicture(item.path);
+                }else if (item.type === 'file') {
+                    //文件
+                    if (item.active) {
+                        let fileList = this.$refs.upload.fileList;
+                        this.$refs.upload.fileList.splice(fileList.indexOf(item), 1);
+                        item.active = false;
+                    }else{
+                        if (this.maxNum === 1) {
+                            for (let i = 0; i < this.browseList.length; i++) {
+                                this.browseList[i].active = false;
+                            }
+                            this.$refs.upload.fileList = [];
+                            this.uploadList = this.$refs.upload.fileList;
+                        }
+                        let check = this.uploadList.length < this.maxNum;
+                        if (!check) {
+                            this.$Modal.warning({ title: this.$L('温馨提示'), content: this.$L('最多只能选择 % 张图片。', this.maxNum) });
+                            return;
+                        }
+                        item.active = true;
+                        item.status = 'finished';
+                        this.$refs.upload.fileList.push(item);
+                        this.uploadList = this.$refs.upload.fileList;
+                    }
+                    this.$emit('input', this.$refs.upload.fileList);
+                }
+            },
+
+            __thumb(url) {
+                if ($A.strExists(url, "?", false)) {
+                    return url + "&__thumb=true";
+                }else{
+                    return url + "?__thumb=true";
+                }
+            },
+
+            httpEnter() {
+                this.$emit('input', this.initItems(this.httpValue));
+                this.browseVisible = false;
+            }
+        }
+    }
+</script>

+ 13 - 0
assets/js/main/components/MDEditor/README.md

@@ -0,0 +1,13 @@
+新增`on-custom`事件
+
+新增`toolbars.custom_image`参数
+
+新增`toolbars.custom_uploadImage`参数
+
+新增`toolbars.custom_uploadFile`参数
+
+新增`toolbars.custom_fullscreen`参数
+
+新增`isCustomFullscreen`参数
+
+修改`height`参数

+ 138 - 0
assets/js/main/components/MDEditor/assets/css/dark.less

@@ -0,0 +1,138 @@
+@charset "utf-8";
+/*
+*Author zhaoxuhui
+*/
+
+// Dark
+/deep/ .markdown-theme-dark{
+    pre {
+        display: block;
+        padding: 20px 10px!important;
+        border-radius: 4px;
+        margin: 20px 0 !important;
+        background: #1e1e1e;
+        color: #DCDCDC;
+        overflow-y: hidden !important;
+        overflow-x: auto !important;
+        font-family: Menlo, Consolas, "Courier New", Courier, FreeMono, monospace !important;
+
+        * {
+            line-height: 1.6 !important;
+            font-size: 14px;
+            font-family: Menlo, Consolas, "Courier New", Courier, FreeMono, monospace !important;
+        }
+    }
+
+    code {
+        padding: 0 !important;
+        margin: 0 !important;
+    }
+
+
+    .hljs-literal,
+    .hljs-name,
+    .hljs-symbol {
+        color: #659bd1;
+    }
+
+    .hljs-keyword {
+        color: #bc89bd;
+    }
+
+    .hljs-link {
+        color: #569CD6;
+        text-decoration: underline;
+    }
+
+    .hljs-built_in,
+    .hljs-type {
+        color: #4EC9B0;
+    }
+
+    .hljs-class,
+    .hljs-number {
+        color: #B8D7A3;
+    }
+
+    .hljs-meta-string,
+    .hljs-string {
+        color: #D69D85;
+    }
+
+    .hljs-regexp,
+    .hljs-template-tag {
+        color: #9A5334;
+    }
+
+    .hljs-formula,
+    .hljs-function,
+    .hljs-params,
+    .hljs-subst,
+    .hljs-title {
+        color: #DCDCDC;
+    }
+
+    .hljs-comment,
+    .hljs-quote {
+        color: #57A64A;
+        font-style: italic;
+    }
+
+    .hljs-doctag {
+        color: #608B4E;
+    }
+
+    .hljs-meta,
+    .hljs-meta-keyword,
+    .hljs-tag {
+        color: #9B9B9B;
+    }
+
+    .hljs-template-variable,
+    .hljs-variable {
+        color: #BD63C5;
+    }
+
+    .hljs-attr,
+    .hljs-attribute,
+    .hljs-builtin-name {
+        color: #9CDCFE;
+    }
+
+    .hljs-section {
+        color: gold;
+    }
+
+    .hljs-emphasis {
+        font-style: italic;
+    }
+
+    .hljs-strong {
+        font-weight: bold;
+    }
+
+    .hljs-bullet,
+    .hljs-selector-attr,
+    .hljs-selector-class,
+    .hljs-selector-id,
+    .hljs-selector-pseudo,
+    .hljs-selector-tag {
+        color: #D7BA7D;
+    }
+
+    .hljs-addition {
+        background-color: #144212;
+        display: inline-block;
+        width: 100%;
+    }
+
+    .hljs-deletion {
+        background-color: #600;
+        display: inline-block;
+        width: 100%;
+    }
+
+    .hljs-comment {
+        font-style: normal;
+    }
+}

+ 113 - 0
assets/js/main/components/MDEditor/assets/css/github.less

@@ -0,0 +1,113 @@
+@charset "utf-8";
+/*
+*Author zhaoxuhui
+*/
+// gitHub 风格
+/deep/ .markdown-theme-gitHub{
+    pre {
+        padding: 20px 10px!important;
+        display: block;
+        overflow-x: auto;
+        color: #333;
+        background: #f7f8fa !important;
+        font-size: 13px;
+        line-height: 20px;
+        border-radius: 4px;
+        margin: 10px 0 !important;
+        overflow-x: auto !important;
+
+        * {
+            font-family: Consolas !important;
+        }
+    }
+
+    .hljs-comment,
+    .hljs-quote {
+        color: #998;
+        font-style: italic;
+    }
+
+    .hljs-selector-tag,
+    .hljs-subst {
+        color: #333;
+        font-weight: bold;
+    }
+
+    .hljs-keyword {
+        color: #d73a49;
+    }
+
+    .hljs-literal,
+    .hljs-number,
+    .hljs-tag .hljs-attr,
+    .hljs-template-variable,
+    .hljs-variable {
+        color: #008080;
+    }
+
+    .hljs-doctag,
+    .hljs-string {
+        color: #d73a49;
+    }
+
+    .hljs-section,
+    .hljs-selector-id,
+    .hljs-title {
+        color: #900;
+        font-weight: bold;
+    }
+
+    .hljs-subst {
+        font-weight: normal;
+    }
+
+    .hljs-class .hljs-title,
+    .hljs-type {
+        color: #458;
+        font-weight: bold;
+    }
+
+    .hljs-attribute,
+    .hljs-name,
+    .hljs-tag {
+        color: #000080;
+        font-weight: normal;
+    }
+
+    .hljs-link,
+    .hljs-regexp {
+        color: #009926;
+    }
+
+    .hljs-bullet,
+    .hljs-symbol {
+        color: #990073;
+    }
+
+    .hljs-built_in,
+    .hljs-builtin-name {
+        color: #0086b3;
+    }
+
+    .hljs-meta {
+        color: #999;
+        font-weight: bold;
+    }
+
+    .hljs-deletion {
+        background: #fdd;
+    }
+
+    .hljs-addition {
+        background: #dfd;
+    }
+
+    .hljs-emphasis {
+        font-style: italic;
+    }
+
+    .hljs-strong {
+        font-weight: bold;
+    }
+
+}

+ 950 - 0
assets/js/main/components/MDEditor/assets/css/index.less

@@ -0,0 +1,950 @@
+@margin: 8px 0;
+@line-height: 22px;
+
+.markdown {
+    overflow: hidden;
+    position: relative;
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    flex-direction: column;
+    background: @background;
+
+    &.border {
+        border: 1px solid @border;
+    }
+
+    * {
+        margin: 0;
+        padding: 0;
+        box-sizing: border-box;
+    }
+
+    &.fullscreen {
+        position: fixed;
+        z-index: 999999;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        height: 100% !important;
+        width: 100%;
+        border: none;
+
+        .markdown-content {
+            padding: 0;
+            padding-top: 10px;
+        }
+    }
+
+    .markdown-toolbars {
+        width: 100%;
+        display: flex;
+        align-items: center;
+        list-style: none;
+        background: #fff;
+        color: #6a6f7b;
+        height: 40px;
+        cursor: pointer;
+        //box-shadow: 0 2px 3px #ddd;
+        padding-left: 4px;
+        border-bottom: 1px solid @border;
+
+        > li {
+            position: relative;
+            cursor: pointer;
+            margin: 0;
+            line-height: normal;
+            min-height: auto;
+
+            &:after {
+                display: block;
+                content: attr(name);
+                position: absolute;
+                z-index: 999999999999;
+                top: 32px;
+                left: 20px;
+                background: #000;
+                color: #fff;
+                white-space: nowrap;
+                font-size: 12px;
+                line-height: 28px;
+                padding: 0 6px;
+                transition: all 0.3s 0.1s;
+                transform: scale(0);
+                opacity: 0;
+                transform-origin: top;
+                border-radius: 2px;
+            }
+
+            &:hover {
+                &:after {
+                    transform: scale(1);
+                    opacity: 1;
+                }
+            }
+
+            &:last-child {
+                &:after {
+                    right: 20%;
+                    left: auto;
+                }
+            }
+
+            .title {
+                font-size: 16px !important;
+            }
+
+            .icon-svg {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+            }
+        }
+
+        .empty {
+            flex: 1;
+            width: 12px;
+        }
+
+        span {
+            font-size: 18px;
+            color: #999;
+            cursor: pointer;
+            display: block;
+            width: 30px;
+            height: 30px;
+            border-radius: 3px;
+            line-height: 30px;
+            text-align: center;
+
+            &:hover {
+                background: @background;
+                color: @info;
+            }
+        }
+
+        .title {
+            padding-left: 4px;
+            padding-right: 10px;
+        }
+
+        li:last-child {
+            span {
+                font-size: 20px !important;
+                margin-right: 4px;
+            }
+        }
+
+        .shift-theme,
+        .export-file {
+
+            height: 46px;
+            //width: 80px;
+            position: relative;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+
+            span {
+                padding: 0 8px;
+                transition: all 0.3s;
+                font-size: 18px;
+                display: inline-block;
+                line-height: 32px;
+
+                &:hover {
+                    color: #0084ff;
+                    background: @background;
+                    border-radius: 3px;
+                }
+            }
+
+            ul {
+                position: absolute;
+                transform: scale(0);
+                transition: all 0.3s;
+                left: -50%;
+                top: 40px;
+                width: 160px;
+                transform-origin: top center;
+                list-style: none;
+                margin: 0;
+                padding: 6px 0;
+                box-sizing: border-box;
+                border: 1px solid @border;
+                background: #fff;
+                border-radius: 4px;
+                position: absolute;
+                z-index: 9999999;
+                box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
+
+                &.active {
+                    opacity: 1;
+                    transform: scaleY(1);
+                }
+
+                li {
+                    line-height: 30px;
+                    padding: 0 12px;
+                    padding-left: 12px;
+                    font-size: 13px;
+                    cursor: pointer;
+                    user-select: none;
+                    display: flex;
+                    align-items: center;
+                    color: @content;
+
+                    .iconfont {
+                        font-size: 14px;
+                        display: block;
+                        height: 30px;
+                        width: 30px;
+                        line-height: 30px;
+                        overflow: hidden;
+
+                        &:hover {
+                            color: @content;
+                        }
+                    }
+
+                    i {
+                        font-size: 13px;
+                        display: block;
+                        font-style: normal;
+                        flex: 1;
+                        white-space: normal;
+                    }
+
+                    &:last-child {
+                        border-bottom: 0;
+
+                        .iconfont {
+                            font-size: 14px !important;
+                            margin: 0 !important;
+                        }
+                    }
+
+                    &:hover {
+                        background: @background;
+                    }
+
+                    &.disabled {
+                        cursor: not-allowed;
+                        color: @disabled;
+
+                        &:hover {
+                            background: transparent;
+                        }
+                    }
+                }
+            }
+        }
+
+        .import-file {
+            position: relative;
+
+            input {
+                position: absolute;
+                z-index: 9999;
+                left: 0;
+                top: 0;
+                display: block;
+                width: 100%;
+                height: 100%;
+                opacity: 0;
+                cursor: pointer;
+                font-size: 0;
+
+            }
+
+            &:hover {
+                span {
+                    background: @background;
+                    color: @info;
+                }
+                &:after {
+                    transform: scale(1);
+                    opacity: 1;
+                }
+            }
+        }
+    }
+
+    .close-preview {
+        position: absolute;
+        z-index: 999;
+        right: 0;
+        top: 0;
+        height: 40px;
+        width: 40px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        color: @content;
+
+        span {
+            font-size: 22px;
+
+            &:hover {
+                color: @title;
+            }
+        }
+    }
+
+    .markdown-content {
+        flex: 1;
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        position: relative;
+        overflow: hidden;
+        padding-bottom: 0;
+
+        .markdown-editor { // simple版编辑器区域
+            flex: 1;
+            height: 100%;
+            position: relative;
+            margin: 0 !important;
+            overflow: hidden;
+            overflow-y: scroll;
+            display: flex;
+            justify-content: space-between;
+            background: #2d2d2d;
+
+            &::-webkit-scrollbar {
+                display: none;
+            }
+
+            .index {
+                background: #272727;
+                min-height: 100%;
+                width: 36px;
+                line-height: @line-height;
+                padding: 12px 0;
+
+                li {
+                    background: #272727;
+                    color: #ccc;
+                    font-size: 14px;
+                    text-align: center;
+                    font-family: Consolas;
+                }
+            }
+
+            textarea {
+                width: 100%;
+                min-height: 100%;
+                outline: none;
+                border: 0;
+                background: #2d2d2d;
+                line-height: @line-height;
+                caret-color: #ccc;
+                color: #669acc;
+                font-size: 14px;
+                font-family: Consolas;
+                resize: none;
+                padding: 12px 8px;
+                overflow: hidden;
+                white-space: nowrap;
+                overflow-x: auto;
+
+                &::selection {
+                    background: #999;
+                    color: #0084ff;
+                }
+            }
+        }
+
+        .codemirror {
+            flex: 1;
+            width: 0;
+            height: 100%;
+            overflow: auto;
+        }
+
+        .markdown-preview {
+            flex: 1;
+            width: 0;
+            height: 100%;
+        }
+    }
+}
+
+.insert-img-model {
+    position: fixed;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 99999;
+    background: @mask;
+    padding-top: 12%;
+    transition: all 0.3s;
+    opacity: 0;
+    display: none;
+
+    .model-container {
+        background: #fff;
+        width: 480px;
+        margin: 0 auto;
+        border-radius: 4px;
+        transition: all 0.3s;
+        transform: scale(0);
+        transform-origin: center;
+
+        .model-head {
+            line-height: 32px;
+            padding: 0 12px;
+            background: @background;
+            border-radius: 4px 4px 0 0;
+            box-shadow: 0 1px 2px @border;
+            display: flex;
+            justify-content: space-between;
+
+            span:nth-of-type(2) {
+                font-size: 14px;
+                padding-left: 12px;
+                cursor: pointer;
+
+                &:hover {
+                    color: @error;
+                }
+            }
+        }
+
+        .model-content {
+            padding: 20px 12px;
+            padding-top: 0;
+            min-height: 180px;
+
+            .insert-url {
+                padding: 42px 0;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+
+                input {
+                    display: block;
+                    border: 1px solid #ccc;
+                    font-size: 14px;
+                    padding: 4px 8px;
+                    line-height: 24px;
+                    color: #333;
+                    background: #fff;
+                    border-radius: 4px;
+                    writing-mode: horizontal-tb;
+                    text-rendering: auto;
+                    transition: box-shadow 2s;
+                    flex: 1;
+
+                    &:focus {
+                        border-color: @info;
+                    }
+
+                    &::placeholder {
+                        color: @tip;
+                    }
+                }
+
+                a {
+                    display: block;
+                    background: @info;
+                    color: #fff;
+                    line-height: 32px;
+                    height: 32px;
+                    font-size: 13px;
+                    padding: 0 12px;
+                    border-radius: 3px;
+                    margin-left: 20px;
+                    border: 1px solid @border;
+                    transition: all 0.3s;
+
+                    &:hover {
+                        background: @dark-info;
+                    }
+                }
+            }
+
+            .insert-local {
+                height: 120px;
+                border: 1px dashed @border;
+                border-radius: 4px;
+                transition: all 0.3s;
+                position: relative;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                flex-direction: column;
+                cursor: pointer;
+
+                span {
+                    font-size: 40px;
+                    color: @border;
+                    line-height: 50px;
+                    transition: all 0.3s;
+                }
+
+                p {
+                    font-size: 14px;
+                    color: @content;
+                    transition: all 0.3s;
+                }
+
+                &:hover {
+                    border-color: @info;
+
+                    span,
+                    p {
+                        color: @info;
+                    }
+                }
+
+                input {
+                    display: block;
+                    position: absolute;
+                    width: 100%;
+                    height: 100%;
+                    opacity: 0;
+                }
+            }
+
+        }
+
+        .model-foot {
+            display: flex;
+            justify-content: flex-end;
+            align-items: center;
+            padding: 10px 12px;
+            display: none;
+
+            a {
+                display: block;
+                background: @background;
+                color: @title;
+                line-height: 26px;
+                height: 26px;
+                font-size: 13px;
+                padding: 0 12px;
+                border-radius: 3px;
+                margin-left: 12px;
+                border: 1px solid @border;
+                transition: all 0.3s;
+
+                &:hover {
+                    background: @divider;
+                }
+
+                &.ok {
+                    background: @info;
+                    color: #fff;
+                    border-color: @info;
+
+                    &:hover {
+                        background: @dark-info;
+                    }
+                }
+
+            }
+        }
+    }
+
+    &.active {
+        opacity: 1;
+        display: block;
+
+        .model-container {
+            transform: scale(1);
+        }
+    }
+}
+
+ul.shift {
+    padding: 6px 12px;
+    display: flex;
+    align-items: center;
+
+    span {
+        font-size: 12px;
+        cursor: pointer;
+        user-select: none;
+
+        &.iconfont {
+            font-size: 14px;
+        }
+    }
+
+    label {
+        font-size: 12px;
+        padding-right: 10px;
+        position: relative;
+        cursor: pointer;
+        user-select: none;
+    }
+
+    input[type='radio'],
+    label {
+        transition: all 0.6s ease;
+        box-sizing: border-box;
+
+    }
+
+    input[type="radio"] + label::before {
+        content: "\a0";
+        display: inline-block;
+        vertical-align: middle;
+        margin-right: 4px;
+        width: 8px;
+        height: 8px;
+        border-radius: 50%;
+        border: 1px solid @primary;
+        padding: 2px;
+    }
+
+    input[type="radio"]:checked + label::before {
+        background-color: @primary;
+        background-clip: content-box;
+        padding: 2px;
+    }
+
+    input[type="radio"] {
+        position: absolute;
+        clip: rect(0, 0, 0, 0);
+    }
+
+    input[type="radio"]:checked + label {
+        color: @primary;
+    }
+}
+
+/deep/ .markdown-preview {
+    flex: 1;
+    overflow: hidden;
+    overflow-y: scroll;
+    background: #fff;
+    padding: 20px 12px !important;
+    font-family: 'Tahoma For Number', 'Chinese Quote', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+
+    * {
+        margin: 0;
+        padding: 0;
+        box-sizing: border-box;
+    }
+
+    > div {
+        padding: 10px 12px !important;
+        background: #fff;
+
+        &::-webkit-scrollbar {
+            display: none;
+        }
+    }
+
+    &::-webkit-scrollbar {
+        display: none;
+    }
+
+    em {
+        font-style: oblique;
+    }
+
+    ul {
+        list-style: none;
+        padding: 0 20px;
+
+        li {
+            position: relative;
+
+            &:after {
+                display: block;
+                content: "";
+                width: 8px;
+                height: 8px;
+                border-radius: 50%;
+                position: absolute;
+                z-index: 99;
+                top: 12px;
+                left: -16px;
+                background: @content;
+            }
+        }
+    }
+
+    ol,
+    ul {
+        margin: 10px 0;
+
+        li {
+            font-size: 14px !important;
+            color: @content;
+            line-height: 22px !important;
+            padding: 4px 0;
+            padding-left: 6px;
+            min-height: 28px;
+
+            input[type="checkbox"] {
+                position: relative;
+                cursor: pointer;
+                overflow: visible;
+                position: absolute;
+                left: -14px;
+                top: 5px;
+
+                &:before {
+                    font-family: "iconfont" !important;
+                    color: #999;
+                    display: block;
+                    width: 18px;
+                    height: 18px;
+                    position: absolute;
+                    content: "\E684";
+                    top: 0px;
+                    left: -4px;
+                    z-index: 999999;
+                    background-position: center;
+                    background: #fff;
+                    font-size: 18px;
+                    text-align: center;
+                    line-height: 18px;
+                }
+            }
+
+            input[type="checkbox"]:checked {
+                &:before {
+                    content: "\E683";
+                }
+            }
+        }
+    }
+
+    ol {
+        list-style-type: decimal;
+        padding-left: 20px;
+        li {
+            list-style: decimal;
+        }
+    }
+
+    hr {
+        color: @border;
+        height: 1px;
+        border: 0;
+        border-top: 1px solid @border;
+        margin: 20px 0;
+        padding: 0;
+    }
+
+    del,
+    em,
+    strong {
+        display: inline-block;
+    }
+
+    blockquote {
+        position: relative;
+        background: @background;
+        padding: 6px 12px;
+        border-left: 5px solid @divider;
+        border-radius: 2px;
+        margin: @margin;
+    }
+
+    /*基本样式*/
+
+    h1,
+    h2,
+    h3,
+    h4,
+    h5,
+    h6 {
+        color: @title;
+    }
+
+    h1 {
+        font-size: 28px;
+        border-bottom: 1px solid @border;
+    }
+
+    h2 {
+        font-size: 24px;
+    }
+
+    h3 {
+        font-size: 18px;
+    }
+
+    h4 {
+        font-size: 16px;
+    }
+
+    h5 {
+        font-size: 14px;
+    }
+
+    h6 {
+        font-size: 12px;
+    }
+
+    h1,
+    h2,
+    h3,
+    h4,
+    h5,
+    h6 {
+        padding: 8px 0;
+        font-weight: 600;
+    }
+    p {
+        font-size: 14px !important;
+        color: @content;
+        margin-bottom: 8px;
+        line-height: @line-height;
+    }
+    // 图片
+    img {
+        display: block;
+        max-width: 100%;
+        margin: 20px 0;
+        cursor: pointer;
+    }
+    // 表格样式
+    table {
+        width: 100%;
+        border: 1px solid @border;
+        border-bottom: 0;
+        background: #fff;
+        border-spacing: 0;
+        border-collapse: collapse;
+        margin: 20px 0;
+
+        tr {
+            -webkit-transition: background 0.1s;
+            transition: background 0.1s;
+        }
+
+        tr td,
+        tr th {
+            padding: 4px 8px;
+            font-size: 14px;
+            line-height: 24px;
+            color: #333;
+            border-bottom: 1px solid @border;
+            cursor: pointer;
+        }
+        th {
+            background: #f8f8f9;
+            text-align: left;
+            font-weight: bold;
+        }
+
+        tr:nth-of-type(even) {
+            td {
+                background: #fafafa;
+            }
+        }
+
+        tr {
+            &:hover {
+                td {
+                    background: #f5f5f5;
+                }
+            }
+        }
+
+        td,
+        th {
+            border: 1px solid @border;
+            word-break: break-all;
+        }
+    }
+
+    input[type="checkbox"] {
+        display: inline-block;
+        border-radius: 0;
+        margin-right: 8px;
+    }
+
+    a {
+        text-decoration: none;
+        color: @info;
+        font-size: 14px;
+        line-height: @line-height;
+    }
+
+    .code-block {
+        position: relative;
+        padding: 0 !important;
+
+        .copy-code {// 复制代码
+            position: absolute;
+            z-index: 999;
+            top: 5px;
+            right: 10px;
+            font-size: 12px;
+            color: @border;
+            line-height: 20px;
+            cursor: pointer;
+            user-select: none;
+            transition: all .3s;
+            opacity: 0;
+
+            &:hover {
+                color: @info;
+            }
+        }
+
+        &:hover {
+            .copy-code {
+                opacity: 1;
+            }
+        }
+    }
+}
+
+.preview-img {
+    position: fixed;
+    width: 100vw;
+    height: 100vh;
+    z-index: 99999999;
+    left: 0;
+    top: 0;
+    background: rgba(0, 0, 0, .5);
+    display: none;
+    opacity: 0;
+    transition: opacity .3s .1s;
+    justify-content: center;
+    align-items: center;
+
+    .close {
+        position: absolute;
+        right: 0;
+        top: 0;
+        color: #fff;
+        padding: 10px;
+        font-size: 20px;
+        cursor: pointer;
+    }
+
+    img {
+        display: block;
+        &.vertical {
+            height: 80%;
+            width: auto;
+        }
+
+        &.horizontal {
+            width: 80%;
+            height: auto;
+        }
+
+    }
+
+    &.active {
+        display: flex;
+        opacity: 1;
+    }
+}

+ 132 - 0
assets/js/main/components/MDEditor/assets/css/light.less

@@ -0,0 +1,132 @@
+@charset "utf-8";
+/*
+*Author zhaoxuhui
+*/
+// 默认风格
+/deep/ .markdown-theme-light{
+    pre {
+        font-size: 14px !important;
+        line-height: 1.6 !important;
+        word-break: break-all;
+        word-wrap: break-word;
+        border: 0 !important;
+        border-radius: 0 !important;
+        background: #f7f8fb !important;
+        padding: 20px 10px!important;
+        border-radius: 4px !important;
+        overflow-y: hidden !important;
+        overflow-x: auto !important;
+        margin: 10px 0 !important;
+
+        code {
+            line-height: @line-height !important;
+            font-family: Consolas !important;
+            font-size: 13px;
+            line-height: @line-height !important;
+            color: #444;
+        }
+    }
+
+    * {
+        //-webkit-font-smoothing: antialiased;
+    }
+
+    .hljs {
+        display: block;
+        overflow-x: auto;
+        color: #525252;
+        padding: 15px;
+        -webkit-text-size-adjust: none;
+    }
+
+    .hljs-doctype {
+        color: #999;
+    }
+
+    .hljs-tag {
+        color: #3e76f6;
+    }
+
+    .hljs-attribute {
+        color: #e96900;
+    }
+
+    .hljs-value {
+        color: #42b983;
+    }
+
+    .hljs-keyword {
+        color: #e96900;
+    }
+
+    .hljs-string {
+        color: #42b983;
+    }
+
+    .hljs-comment {
+        color: #b3b3b3;
+    }
+
+    .hljs-operator .hljs-comment {
+        color: #525252;
+    }
+
+    .hljs-regexp {
+        color: #af7dff;
+    }
+
+    .hljs-built_in {
+        color: #2db7f5;
+    }
+
+    .css .hljs-class {
+        color: #e96900;
+    }
+
+    .css .hljs-number,
+    .javascript .hljs-number {
+        color: #fc1e70;
+    }
+
+    .css .hljs-attribute {
+        color: #af7dff;
+    }
+
+    .css .hljs-important {
+        color: red;
+    }
+
+    .actionscript .hljs-literal,
+    .javascript .hljs-literal {
+        color: #fc1e70;
+    }
+
+    pre {
+        padding: 0;
+        margin: 0;
+        background: @background !important;
+    }
+
+    code {
+        display: inline-block;
+        background: #f7f7f7;
+        font-family: Consolas, Monaco, Andale Mono, Ubuntu Mono, monospace;
+        margin: 0 3px;
+        padding: 1px 5px;
+        border-radius: 3px;
+        color: #666;
+        border: 1px solid #eee;
+    }
+
+    pre code {
+        display: inline;
+        margin: 0;
+        padding: 0;
+        border: none;
+        background: transparent;
+    }
+
+    pre.bg code {
+        background: #f7f7f7;
+    }
+}

+ 93 - 0
assets/js/main/components/MDEditor/assets/css/one-dark.less

@@ -0,0 +1,93 @@
+@charset "utf-8";
+/*
+*Author zhaoxuhui
+*/
+/deep/ .markdown-theme-oneDark {
+    pre {
+        padding: 20px 10px!important;
+        display: block;
+        color: #abb2bf;
+        font-family: Menlo, Consolas, "Courier New", Courier, FreeMono, monospace;
+        background: #292c34;
+        border-radius: 4px;
+        overflow-y: hidden !important;
+        overflow-x: auto !important;
+        margin: 10px 0 !important;
+
+        * {
+            line-height: 1.6 !important;
+            font-size: 14px;
+            font-family: Menlo, Consolas, "Courier New", Courier, FreeMono, monospace;
+        }
+    }
+
+    .hljs-comment,
+    .hljs-quote {
+        color: #5c6370;
+        font-style: italic;
+    }
+
+    .hljs-doctag,
+    .hljs-formula,
+    .hljs-keyword {
+        color: #c678dd;
+    }
+
+    .hljs-deletion,
+    .hljs-name,
+    .hljs-section,
+    .hljs-selector-tag,
+    .hljs-subst {
+        color: #e06c75;
+    }
+
+    .hljs-literal {
+        color: #56b6c2;
+    }
+
+    .hljs-addition,
+    .hljs-attribute,
+    .hljs-meta-string,
+    .hljs-regexp,
+    .hljs-string {
+        color: #98c379;
+    }
+
+    .hljs-built_in,
+    .hljs-class .hljs-title {
+        color: #e6c07b;
+    }
+
+    .hljs-attr,
+    .hljs-number,
+    .hljs-selector-attr,
+    .hljs-selector-class,
+    .hljs-selector-pseudo,
+    .hljs-template-variable,
+    .hljs-type,
+    .hljs-variable {
+        color: #d19a66;
+    }
+
+    .hljs-bullet,
+    .hljs-link,
+    .hljs-meta,
+    .hljs-selector-id,
+    .hljs-symbol,
+    .hljs-title {
+        color: #61aeee;
+    }
+
+    .hljs-emphasis {
+        font-style: italic;
+    }
+
+    .hljs-strong {
+        font-weight: bold;
+    }
+
+    .hljs-link {
+        text-decoration: underline;
+    }
+
+}

+ 27 - 0
assets/js/main/components/MDEditor/assets/css/theme.less

@@ -0,0 +1,27 @@
+@charset "utf-8";
+/*
+*Author zhaoxuhui
+*/
+
+//主体颜色
+@primary: #292d35;
+@light-primary: #323741;
+@dark-primary: #1c1e24;
+//
+@info: #1890ff;
+@success: #19be6b;
+@warning: #ff9900;
+@error: #ed3f14;
+//
+@title: #262626;
+@content: #262626;
+@sub-color: #80848f;
+@disabled: #bbbec4;
+@border: #d9d9d9;
+@divider: #d9d9d9;
+@background: #f7f7f7;
+@tip:#c1c1c1;
+@primary-rgba:rgba(49,204,102,0.2);
+@mask:rgba(0, 0, 0, 0.3);
+@blue-rgba:rgba(0,122,204,0.2);
+@dark-info:#0169af;

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 3 - 0
assets/js/main/components/MDEditor/assets/font/iconfont.css


BIN
assets/js/main/components/MDEditor/assets/font/iconfont.eot


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 37 - 0
assets/js/main/components/MDEditor/assets/font/iconfont.svg


BIN
assets/js/main/components/MDEditor/assets/font/iconfont.ttf


BIN
assets/js/main/components/MDEditor/assets/font/iconfont.woff


BIN
assets/js/main/components/MDEditor/assets/font/iconfont.woff2


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно