carvendy 2 days ago
commit
af36a370f0
100 changed files with 216966 additions and 0 deletions
  1. 7 0
      Gemfile
  2. 96 0
      Gemfile.lock
  3. 222 0
      LICENSE
  4. 5 0
      NOTICE
  5. 269 0
      README.md
  6. 7 0
      android/Gemfile
  7. 222 0
      android/Gemfile.lock
  8. 151 0
      android/app/build.gradle
  9. BIN
      android/app/debug.keystore
  10. 48 0
      android/app/proguard-rules.pro
  11. 9 0
      android/app/src/debug/AndroidManifest.xml
  12. 70 0
      android/app/src/main/AndroidManifest.xml
  13. BIN
      android/app/src/main/assets/fonts/Outfit-Black.ttf
  14. BIN
      android/app/src/main/assets/fonts/Outfit-Bold.ttf
  15. BIN
      android/app/src/main/assets/fonts/Outfit-ExtraBold.ttf
  16. BIN
      android/app/src/main/assets/fonts/Outfit-ExtraLight.ttf
  17. BIN
      android/app/src/main/assets/fonts/Outfit-Light.ttf
  18. BIN
      android/app/src/main/assets/fonts/Outfit-Medium.ttf
  19. BIN
      android/app/src/main/assets/fonts/Outfit-Regular.ttf
  20. BIN
      android/app/src/main/assets/fonts/Outfit-SemiBold.ttf
  21. BIN
      android/app/src/main/assets/fonts/Outfit-Thin.ttf
  22. BIN
      android/app/src/main/assets/fonts/Outfit-VariableFont_wght.ttf
  23. 2469 0
      android/app/src/main/assets/index.android.bundle
  24. 1 0
      android/app/src/main/assets/index.android.map
  25. 14 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/css/gc.spread.sheets.designer.18.2.4.min.css
  26. 14 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/css/gc.spread.sheets.designer.dark.18.2.4.min.css
  27. 14 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/css/gc.spread.sheets.designer.light.18.2.4.min.css
  28. 13621 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/definition/gc.spread.sheets.designer.d.ts
  29. 2081 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.all.18.2.4.min.js
  30. 85 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.cn.18.2.4.min.js
  31. 86 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.en.18.2.4.min.js
  32. 83 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.ja.18.2.4.min.js
  33. 87 0
      android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.ko.18.2.4.min.js
  34. BIN
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/GrapeCitySoftware-EULA.pdf
  35. 858 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/LICENSE
  36. 7739 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.18.2.4.css
  37. 7791 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2013darkGray.18.2.4.css
  38. 7796 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2013lightGray.18.2.4.css
  39. 7782 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2013white.18.2.4.css
  40. 7797 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2016black.18.2.4.css
  41. 7787 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2016colorful.18.2.4.css
  42. 7783 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2016darkGray.18.2.4.css
  43. 144 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/definition/gc.spread.excelio.d.ts
  44. 62047 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/definition/gc.spread.sheets.d.ts
  45. 59 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/default.html
  46. BIN
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/img/logo.png
  47. 22 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/home.htm
  48. 36 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/celltype.html
  49. 23 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/databinding.html
  50. 23 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/datavalidation.html
  51. 85 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/layout.html
  52. 26 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/style.html
  53. 17 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/readme.txt
  54. 925 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/angularjs/1.2.22/angular-route.js
  55. 21922 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/angularjs/1.2.22/angular.js
  56. 4 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/jquery-2.1.1.min.js
  57. 2 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/license.js
  58. 12 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/spreadjs/gc.spread.sheets.all.18.2.4.min.js
  59. 10 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/spreadjs/gc.spread.sheets.angularjs.18.2.4.min.js
  60. 12 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/spreadjs/gc.spread.sheets.resources.zh.18.2.4.min.js
  61. 20 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/waxApp.js
  62. 86 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/waxCtrl.js
  63. 95 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/app.css
  64. 5 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/bootstrap/3.2.0/bootstrap-theme.min.css
  65. 5 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/bootstrap/3.2.0/bootstrap.min.css
  66. 19 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/fonts.css
  67. 7739 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.18.2.4.css
  68. 7791 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2013darkGray.18.2.4.css
  69. 7796 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2013lightGray.18.2.4.css
  70. 7782 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2013white.18.2.4.css
  71. 7797 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2016black.18.2.4.css
  72. 7787 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2016colorful.18.2.4.css
  73. 7783 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2016darkGray.18.2.4.css
  74. 85 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/angular.json
  75. 39 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/package.json
  76. 1109 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app-data.service.ts
  77. 105 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.component.css
  78. 27 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.component.html
  79. 19 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.component.ts
  80. 11 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.config.ts
  81. 33 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/column/app-column.component.html
  82. 28 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/column/app-column.component.ts
  83. 19 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/dataBind/app-dataBind.component.html
  84. 22 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/dataBind/app-dataBind.component.ts
  85. 29 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/outline/app-outline.component.html
  86. 26 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/outline/app-outline.component.ts
  87. 22 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/quickStart/app-quickStart.component.html
  88. 23 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/quickStart/app-quickStart.component.ts
  89. 19 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/route/app-routing.module.ts
  90. 78 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/spreadSheets/app-spreadSheets.component.html
  91. 34 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/spreadSheets/app-spreadSheets.component.ts
  92. 17 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/style/app-style.component.html
  93. 34 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/style/app-style.component.ts
  94. 66 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/worksheet/app-worksheet.component.html
  95. 34 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/worksheet/app-worksheet.component.ts
  96. BIN
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/assets/img/logo.png
  97. BIN
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/favicon.ico
  98. 19 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/fonts.css
  99. BIN
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/img/logo.png
  100. 0 0
      android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/index.html

+ 7 - 0
Gemfile

@@ -0,0 +1,7 @@
+source 'https://rubygems.org'
+# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
+ruby ">= 2.6.10"
+
+gem 'fastlane'
+gem 'cocoapods', '~> 1.13'
+gem 'activesupport', '>= 6.1.7.3', '< 7.1.0'

+ 96 - 0
Gemfile.lock

@@ -0,0 +1,96 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    CFPropertyList (3.0.5)
+      rexml
+    activesupport (6.1.4.4)
+      concurrent-ruby (~> 1.0, >= 1.0.2)
+      i18n (>= 1.6, < 2)
+      minitest (>= 5.1)
+      tzinfo (~> 2.0)
+      zeitwerk (~> 2.3)
+    addressable (2.8.0)
+      public_suffix (>= 2.0.2, < 5.0)
+    algoliasearch (1.27.5)
+      httpclient (~> 2.8, >= 2.8.3)
+      json (>= 1.5.1)
+    atomos (0.1.3)
+    claide (1.1.0)
+    cocoapods (1.11.2)
+      addressable (~> 2.8)
+      claide (>= 1.0.2, < 2.0)
+      cocoapods-core (= 1.11.2)
+      cocoapods-deintegrate (>= 1.0.3, < 2.0)
+      cocoapods-downloader (>= 1.4.0, < 2.0)
+      cocoapods-plugins (>= 1.0.0, < 2.0)
+      cocoapods-search (>= 1.0.0, < 2.0)
+      cocoapods-trunk (>= 1.4.0, < 2.0)
+      cocoapods-try (>= 1.1.0, < 2.0)
+      colored2 (~> 3.1)
+      escape (~> 0.0.4)
+      fourflusher (>= 2.3.0, < 3.0)
+      gh_inspector (~> 1.0)
+      molinillo (~> 0.8.0)
+      nap (~> 1.0)
+      ruby-macho (>= 1.0, < 3.0)
+      xcodeproj (>= 1.21.0, < 2.0)
+    cocoapods-core (1.11.2)
+      activesupport (>= 5.0, < 7)
+      addressable (~> 2.8)
+      algoliasearch (~> 1.0)
+      concurrent-ruby (~> 1.1)
+      fuzzy_match (~> 2.0.4)
+      nap (~> 1.0)
+      netrc (~> 0.11)
+      public_suffix (~> 4.0)
+      typhoeus (~> 1.0)
+    cocoapods-deintegrate (1.0.5)
+    cocoapods-downloader (1.5.1)
+    cocoapods-plugins (1.0.0)
+      nap
+    cocoapods-search (1.0.1)
+    cocoapods-trunk (1.6.0)
+      nap (>= 0.8, < 2.0)
+      netrc (~> 0.11)
+    cocoapods-try (1.2.0)
+    colored2 (3.1.2)
+    concurrent-ruby (1.1.9)
+    escape (0.0.4)
+    ethon (0.15.0)
+      ffi (>= 1.15.0)
+    ffi (1.15.5)
+    fourflusher (2.3.1)
+    fuzzy_match (2.0.4)
+    gh_inspector (1.1.3)
+    httpclient (2.8.3)
+    i18n (1.8.11)
+      concurrent-ruby (~> 1.0)
+    json (2.6.1)
+    minitest (5.15.0)
+    molinillo (0.8.0)
+    nanaimo (0.3.0)
+    nap (1.1.0)
+    netrc (0.11.0)
+    public_suffix (4.0.6)
+    rexml (3.2.5)
+    ruby-macho (2.5.1)
+    typhoeus (1.4.0)
+      ethon (>= 0.9.0)
+    tzinfo (2.0.4)
+      concurrent-ruby (~> 1.0)
+    xcodeproj (1.21.0)
+      CFPropertyList (>= 2.3.3, < 4.0)
+      atomos (~> 0.1.3)
+      claide (>= 1.0.2, < 2.0)
+      colored2 (~> 3.1)
+      nanaimo (~> 0.3.0)
+      rexml (~> 3.2.4)
+    zeitwerk (2.5.3)
+PLATFORMS
+  ruby
+DEPENDENCIES
+  cocoapods (~> 1.11, >= 1.11.2)
+RUBY VERSION
+   ruby 2.7.4p191
+BUNDLED WITH
+   2.2.27

+ 222 - 0
LICENSE

@@ -0,0 +1,222 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+
+
+========================================================================
+This product bundles various third-party components under other open source licenses.
+This section summarizes those components and their licenses. See licenses/
+for text of these licenses.
+
+Apache Software Foundation License 2.0
+--------------------------------------
+
+src/assets/iconpark/*
+src/pages/explore/charts/*
+
+MIT License
+--------------------------------------
+
+ios/RNDevManager.m

+ 5 - 0
NOTICE

@@ -0,0 +1,5 @@
+Taro Playground
+Copyright 2021-present 58.com
+
+This product includes software developed at
+Wuba (https://www.58.com/).

+ 269 - 0
README.md

@@ -0,0 +1,269 @@
+### 特别注意  添加第三方库别特须知
+-- 如功能需要添加第三方库,需要查询通过npmjs查询该库与项目版本的兼容性版本;
+2. 系统版本,详见package.json文件,当前版本使用的是 taro-rn@4.0.7-canary.3,及相关的锁定版本的其他库;
+``` npm
+# 尽量锁定安装依赖版本号,避免安装最新版本导致项目启动问题, 如下
+npm install sass@1.0.0
+#避免类似安装,因为这样子安装的当前依赖的最新的稳定的版本,不一定当前适用项目需要,导致其他的依赖包循环依赖进行跟新导致项目启动问题
+#一定要查阅文档,避免导致项目循环依赖包版本与包内部的依赖版本不一致导致项目启动问题
+# yarn add sass
+```
+3. 安装新的依赖包后,重新清空缓存,查看是否导致项目启动问题
+
+``` npm
+# 安装新的依赖包
+npm install 包名
+
+# 安装新的依赖包后,重新清空缓存,查看是否导致项目启动问题
+npx react-native start --reset-cache
+```
+4. 总之,添加新的包之前一定要慎重,切记
+
+## Supported versions
+
+0. taro: `@tarojs/cli@^3.2.0`
+1. framework: 'react'
+
+| Playground Version | Taro version | React Native version | branch |
+| - | - | - | - |
+| 1.1.2 | >= 3.2.0, < 3.3.10 | 0.64 | [releases/rn-0.64+taro-3.3.9](https://github.com/wuba/taro-playground/tree/releases/rn-0.64+taro-3.3.9) |
+| 1.2.0 ~ 1.3.9 | >= 3.3.10, < 3.4.2 | 0.66 | [releases/rn-0.66+taro-3.4.2](https://github.com/wuba/taro-playground/tree/releases/rn-0.66+taro-3.4.2) |
+| 1.4.0 ~ 1.4.8 | >= 3.4.2, < 3.5.0 | 0.67 | [releases/rn-0.67+taro-3.4.10](https://github.com/wuba/taro-playground/tree/releases/rn-0.67+taro-3.4.10) |
+| 1.6.0 ~ 1.6.5 | >= 3.5.0, < 3.5.6 | 0.68 | [releases/rn-0.68+taro-3.5.5](https://github.com/wuba/taro-playground/tree/releases/rn-0.68+taro-3.5.5) |
+| 1.7.0 ~ 1.7.4 | >=3.5.6, < 3.6.0 | 0.69 | [releases/rn-0.69+taro-3.5.11](https://github.com/wuba/taro-playground/tree/releases/rn-0.69+taro-3.5.11) |
+| 1.8.0 ~ 1.8.2 | >=3.5.6, < 4.0.0 | 0.70 | [releases/rn-0.70+taro-3.6.18](https://github.com/wuba/taro-playground/tree/releases/rn-0.70+taro-3.6.18) |
+| 1.11.0 ~ | >=4.0.8 | 0.73 | [main](https://github.com/wuba/taro-playground/tree/main) |
+
+## Quick start
+
+### install react native library
+> install peerDependencies of `@tarojs/taro-rn` `@tarojs/components-rn` and `@tarojs/router-rn`, it will also run `post-install`. please modify and run `upgradePeerdeps` script when you change taro version.
+> 
+> **run this script after the project is initialized.**
+
+```
+yarn upgradePeerdeps
+```
+
+### pod install
+> run this script when you add new react native library or update react native library version.
+> 
+> see [pod-install](https://www.npmjs.com/package/pod-install) for more information.
+
+```
+yarn podInstall
+```
+
+### start ios app
+
+```
+yarn ios
+```
+
+### start android app
+
+```
+yarn android
+```
+
+### start bundler
+
+```
+yarn start
+```
+
+### reset cache and start bundler
+
+```
+yarn start --reset-cache
+```
+
+### more information
+
+0. [development process of taro react native](https://taro-docs.jd.com/taro/docs/react-native)
+1. [github address of the taro project](https://github.com/NervJS/taro)
+2. [related articles of taro playground](https://docs.taro.zone/blog/2021-10-14-Taro-React-Native-update)
+
+## Release
+
+### build ios bundle
+
+```
+yarn build:rn --platform ios
+```
+
+### build Android bundle
+
+```
+yarn build:rn --platform android
+```
+
+### release ios APP
+
+see [publishing-to-app-store](https://reactnative.cn/docs/publishing-to-app-store) for details.
+
+### release android apk
+
+see [signed-apk-android](https://reactnative.cn/docs/signed-apk-android) for details.
+
+## Github workflows
+> use github actions to build your apps. this template include basic github action config.
+
+see [.github/workflows](.github/workflows) for details.
+
+### events
+
+we assemble debug and release product for both android and ios when you push or pull request on master branch by default. design your own pipeline by modify [.github/workflows](.github/workflows) files.
+
+see [events-that-trigger-workflows](https://docs.github.com/en/actions/reference/events-that-trigger-workflows) 
+### ios
+
+#### configuration
+
+Modify the following configuration items for package and publish your app.
+
+> [.github/workflows/assemble_ios_debug.yml](.github/workflows/assemble_ios_debug.yml)
+> [.github/workflows/assemble_ios_release.yml](.github/workflows/assemble_ios_release.yml)
+
+```yml
+env:
+  APP_ID: com.taro.demo # Application Product Bundle Identifier
+  APP_NAME: Taro Demo # The Display Name of your app
+  VERSION_NUMBER: 1.0.0 # Application version number
+  BUILD_NUMBER: 1.0.0.0 # Application build number, used by release only.
+  TEAM_ID: XXXXXXXXXX # Team ID, is used when upgrading project
+  PROVISIONING_PROFILE_SPECIFIER: Product_profile # Provisioning profile name to use for code signing
+  CODE_SIGN_IDENTITY: iPhone Distribution # Code signing identity type (iPhone Developer, iPhone Distribution)
+  SIGNING_CERTIFICATE_P12_DATA: ${{secrets.RELEASE_SIGNING_CERTIFICATE_P12_DATA}}
+  SIGNING_CERTIFICATE_PASSWORD: ${{secrets.RELEASE_SIGNING_CERTIFICATE_PASSWORD}}
+  PROVISIONING_PROFILE_DATA: ${{secrets.RELEASE_PROVISIONING_PROFILE_DATA}}
+  APP_STORE_CONNECT_USERNAME: ${{secrets.APP_STORE_CONNECT_USERNAME}} # This secret should be set to the Apple ID of your developer account, used by release only.
+  APP_STORE_CONNECT_PASSWORD: ${{secrets.APP_STORE_CONNECT_PASSWORD}} # used by release only.
+```
+
+values like ${{secrets.xxxxx}} are manually generated and store in your github encrypted secrets.
+
+##### SIGNING_CERTIFICATE_P12_DATA
+
+```
+cat Certificates.p12 | base64 | pbcopy
+```
+
+##### SIGNING_CERTIFICATE_PASSWORD
+
+encryption password of your Personal Information Exchange (.p12)
+
+##### PROVISIONING_PROFILE_DATA
+
+```
+cat profile.mobileprovision | base64 | pbcopy
+```
+
+##### APP_STORE_CONNECT_PASSWORD
+
+This secret should be set to an application-specific password for your Apple ID account. Follow [these instructions](https://support.apple.com/en-us/HT204397) to create an application-specific password.
+
+#### read more
+
+1. [deploy an ios app to testflight or the app store using github actions](https://betterprogramming.pub/deploy-an-ios-app-to-testflight-or-the-app-store-using-github-actions-c4d7082b1430)
+2. [encrypted-secrets](https://docs.github.com/en/actions/reference/encrypted-secrets)
+3. [fastlane](https://docs.fastlane.tools/)
+
+### android
+
+#### configuration
+
+Modify the following configuration items for package and publish your app.
+
+> [.github/workflows/assemble_android_debug.yml](.github/workflows/assemble_android_debug.yml)
+> [.github/workflows/assemble_android_release.yml](.github/workflows/assemble_android_release.yml)
+
+```yml
+env:
+  APP_ID: com.taro.demo  # Application Product Bundle Identifier
+  APP_NAME: Taro Demo  # The Display Name of your app
+  VERSION_NAME: 1.0.0 # version name
+  VERSION_CODE: 10 # version code
+  KEYSTORE_FILE: debug.keystore # key store file
+  KEYSTORE_PASSWORD: android # key store password
+  KEYSTORE_KEY_ALIAS: androiddebugkey # key store key alias
+  KEYSTORE_KEY_PASSWORD: android # key store key password
+```
+
+For the security of your app, please regenerate the .keystore file and store the password in your github encrypted secrets.
+
+#### build
+
+```shell
+
+yarn build:rn --platform android --reset-cache
+cd android
+# 清理缓存
+./gradlew clean
+# 构建Release版本
+./gradlew assembleRelease
+# 构建debug包
+./gradlew assembleDebug
+```
+
+
+#### read more
+
+1. [app signing](https://developer.android.com/studio/publish/app-signing)
+2. [encrypted-secrets](https://docs.github.com/en/actions/reference/encrypted-secrets)
+
+## Web & Mini Program support
+
+This project supports web and mini program, but it has not been fully tested.
+
+### start web server
+
+```shell
+yarn dev:h5
+```
+
+### Github workflows of Web
+
+see [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) for more details.
+
+### start wechat mini program
+
+```shell
+yarn dev:weapp
+```
+
+### Github workflows of Wechat Mini Program
+
+#### configuration
+
+We use [@tarojs/plugin-mini-ci](https://github.com/NervJS/taro/tree/next/packages/taro-plugin-mini-ci) to deploy mini programs. Modify the following configuration items for package and publish your wechat mini program.
+
+> [.github/workflows/assemble_weapp_release.yml](.github/workflows/assemble_weapp_release.yml)
+
+```yml
+env:
+  WEAPP_ID: ${{ secrets.WEAPP_ID }} # wechat mini program id
+  WEAPP_KEY: ${{ secrets.WEAPP_KEY }} # wechat mini program key
+```
+
+values like ${{secrets.xxxxx}} are manually generated and store in your github encrypted secrets.
+
+##### WEAPP_KEY
+
+```
+cat private.$WEAPP_ID.key | base64 | pbcopy
+```
+
+## Attention
+
+The source code is customized for the Taro playground application and is for reference only. If you want to use it directly, please make the following changes.
+
+0. Use your own signature file.
+1. Customize your app id, app name, app launcher, etc.
+2. Remove the attention block in ios/Podfile.
+
+## For React Native repo debugging
+
+0. Change appName to `taroDemo`, which used in `AppRegistry.registerComponent(appName, () => App);`.
+1. Generate a QR code with content `taro://${ip}:${port}` or shaking the phone and change bundle Location.
+

+ 7 - 0
android/Gemfile

@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+source "https://rubygems.org"
+gem 'fastlane'
+
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)

+ 222 - 0
android/Gemfile.lock

@@ -0,0 +1,222 @@
+GEM
+  remote: https://rubygems.org/
+  specs:
+    CFPropertyList (3.0.6)
+      rexml
+    addressable (2.8.1)
+      public_suffix (>= 2.0.2, < 6.0)
+    artifactory (3.0.15)
+    atomos (0.1.3)
+    aws-eventstream (1.2.0)
+    aws-partitions (1.712.0)
+    aws-sdk-core (3.170.0)
+      aws-eventstream (~> 1, >= 1.0.2)
+      aws-partitions (~> 1, >= 1.651.0)
+      aws-sigv4 (~> 1.5)
+      jmespath (~> 1, >= 1.6.1)
+    aws-sdk-kms (1.62.0)
+      aws-sdk-core (~> 3, >= 3.165.0)
+      aws-sigv4 (~> 1.1)
+    aws-sdk-s3 (1.119.1)
+      aws-sdk-core (~> 3, >= 3.165.0)
+      aws-sdk-kms (~> 1)
+      aws-sigv4 (~> 1.4)
+    aws-sigv4 (1.5.2)
+      aws-eventstream (~> 1, >= 1.0.2)
+    babosa (1.0.4)
+    claide (1.1.0)
+    colored (1.2)
+    colored2 (3.1.2)
+    commander (4.6.0)
+      highline (~> 2.0.0)
+    declarative (0.0.20)
+    digest-crc (0.6.4)
+      rake (>= 12.0.0, < 14.0.0)
+    domain_name (0.5.20190701)
+      unf (>= 0.0.5, < 1.0.0)
+    dotenv (2.8.1)
+    emoji_regex (3.2.3)
+    excon (0.99.0)
+    faraday (1.10.3)
+      faraday-em_http (~> 1.0)
+      faraday-em_synchrony (~> 1.0)
+      faraday-excon (~> 1.1)
+      faraday-httpclient (~> 1.0)
+      faraday-multipart (~> 1.0)
+      faraday-net_http (~> 1.0)
+      faraday-net_http_persistent (~> 1.0)
+      faraday-patron (~> 1.0)
+      faraday-rack (~> 1.0)
+      faraday-retry (~> 1.0)
+      ruby2_keywords (>= 0.0.4)
+    faraday-cookie_jar (0.0.7)
+      faraday (>= 0.8.0)
+      http-cookie (~> 1.0.0)
+    faraday-em_http (1.0.0)
+    faraday-em_synchrony (1.0.0)
+    faraday-excon (1.1.0)
+    faraday-httpclient (1.0.1)
+    faraday-multipart (1.0.4)
+      multipart-post (~> 2)
+    faraday-net_http (1.0.1)
+    faraday-net_http_persistent (1.2.0)
+    faraday-patron (1.0.0)
+    faraday-rack (1.0.0)
+    faraday-retry (1.0.3)
+    faraday_middleware (1.2.0)
+      faraday (~> 1.0)
+    fastimage (2.2.6)
+    fastlane (2.211.0)
+      CFPropertyList (>= 2.3, < 4.0.0)
+      addressable (>= 2.8, < 3.0.0)
+      artifactory (~> 3.0)
+      aws-sdk-s3 (~> 1.0)
+      babosa (>= 1.0.3, < 2.0.0)
+      bundler (>= 1.12.0, < 3.0.0)
+      colored
+      commander (~> 4.6)
+      dotenv (>= 2.1.1, < 3.0.0)
+      emoji_regex (>= 0.1, < 4.0)
+      excon (>= 0.71.0, < 1.0.0)
+      faraday (~> 1.0)
+      faraday-cookie_jar (~> 0.0.6)
+      faraday_middleware (~> 1.0)
+      fastimage (>= 2.1.0, < 3.0.0)
+      gh_inspector (>= 1.1.2, < 2.0.0)
+      google-apis-androidpublisher_v3 (~> 0.3)
+      google-apis-playcustomapp_v1 (~> 0.1)
+      google-cloud-storage (~> 1.31)
+      highline (~> 2.0)
+      json (< 3.0.0)
+      jwt (>= 2.1.0, < 3)
+      mini_magick (>= 4.9.4, < 5.0.0)
+      multipart-post (~> 2.0.0)
+      naturally (~> 2.2)
+      optparse (~> 0.1.1)
+      plist (>= 3.1.0, < 4.0.0)
+      rubyzip (>= 2.0.0, < 3.0.0)
+      security (= 0.1.3)
+      simctl (~> 1.6.3)
+      terminal-notifier (>= 2.0.0, < 3.0.0)
+      terminal-table (>= 1.4.5, < 2.0.0)
+      tty-screen (>= 0.6.3, < 1.0.0)
+      tty-spinner (>= 0.8.0, < 1.0.0)
+      word_wrap (~> 1.0.0)
+      xcodeproj (>= 1.13.0, < 2.0.0)
+      xcpretty (~> 0.3.0)
+      xcpretty-travis-formatter (>= 0.0.3)
+    fastlane-plugin-update_android_strings (0.1.0)
+      ox
+    gh_inspector (1.1.3)
+    google-apis-androidpublisher_v3 (0.34.0)
+      google-apis-core (>= 0.9.1, < 2.a)
+    google-apis-core (0.11.0)
+      addressable (~> 2.5, >= 2.5.1)
+      googleauth (>= 0.16.2, < 2.a)
+      httpclient (>= 2.8.1, < 3.a)
+      mini_mime (~> 1.0)
+      representable (~> 3.0)
+      retriable (>= 2.0, < 4.a)
+      rexml
+      webrick
+    google-apis-iamcredentials_v1 (0.16.0)
+      google-apis-core (>= 0.9.1, < 2.a)
+    google-apis-playcustomapp_v1 (0.12.0)
+      google-apis-core (>= 0.9.1, < 2.a)
+    google-apis-storage_v1 (0.19.0)
+      google-apis-core (>= 0.9.0, < 2.a)
+    google-cloud-core (1.6.0)
+      google-cloud-env (~> 1.0)
+      google-cloud-errors (~> 1.0)
+    google-cloud-env (1.6.0)
+      faraday (>= 0.17.3, < 3.0)
+    google-cloud-errors (1.3.0)
+    google-cloud-storage (1.44.0)
+      addressable (~> 2.8)
+      digest-crc (~> 0.4)
+      google-apis-iamcredentials_v1 (~> 0.1)
+      google-apis-storage_v1 (~> 0.19.0)
+      google-cloud-core (~> 1.6)
+      googleauth (>= 0.16.2, < 2.a)
+      mini_mime (~> 1.0)
+    googleauth (1.3.0)
+      faraday (>= 0.17.3, < 3.a)
+      jwt (>= 1.4, < 3.0)
+      memoist (~> 0.16)
+      multi_json (~> 1.11)
+      os (>= 0.9, < 2.0)
+      signet (>= 0.16, < 2.a)
+    highline (2.0.3)
+    http-cookie (1.0.5)
+      domain_name (~> 0.5)
+    httpclient (2.8.3)
+    jmespath (1.6.2)
+    json (2.6.3)
+    jwt (2.7.0)
+    memoist (0.16.2)
+    mini_magick (4.12.0)
+    mini_mime (1.1.2)
+    multi_json (1.15.0)
+    multipart-post (2.0.0)
+    nanaimo (0.3.0)
+    naturally (2.2.1)
+    optparse (0.1.1)
+    os (1.1.4)
+    ox (2.14.14)
+    plist (3.6.0)
+    public_suffix (5.0.1)
+    rake (13.0.6)
+    representable (3.2.0)
+      declarative (< 0.1.0)
+      trailblazer-option (>= 0.1.1, < 0.2.0)
+      uber (< 0.2.0)
+    retriable (3.1.2)
+    rexml (3.2.5)
+    rouge (2.0.7)
+    ruby2_keywords (0.0.5)
+    rubyzip (2.3.2)
+    security (0.1.3)
+    signet (0.17.0)
+      addressable (~> 2.8)
+      faraday (>= 0.17.5, < 3.a)
+      jwt (>= 1.5, < 3.0)
+      multi_json (~> 1.10)
+    simctl (1.6.10)
+      CFPropertyList
+      naturally
+    terminal-notifier (2.0.0)
+    terminal-table (1.8.0)
+      unicode-display_width (~> 1.1, >= 1.1.1)
+    trailblazer-option (0.1.2)
+    tty-cursor (0.7.1)
+    tty-screen (0.8.1)
+    tty-spinner (0.9.3)
+      tty-cursor (~> 0.7)
+    uber (0.1.0)
+    unf (0.1.4)
+      unf_ext
+    unf_ext (0.0.8.2)
+    unicode-display_width (1.8.0)
+    webrick (1.8.1)
+    word_wrap (1.0.0)
+    xcodeproj (1.22.0)
+      CFPropertyList (>= 2.3.3, < 4.0)
+      atomos (~> 0.1.3)
+      claide (>= 1.0.2, < 2.0)
+      colored2 (~> 3.1)
+      nanaimo (~> 0.3.0)
+      rexml (~> 3.2.4)
+    xcpretty (0.3.0)
+      rouge (~> 2.0.7)
+    xcpretty-travis-formatter (1.0.1)
+      xcpretty (~> 0.2, >= 0.0.7)
+
+PLATFORMS
+  universal-darwin-21
+
+DEPENDENCIES
+  fastlane
+  fastlane-plugin-update_android_strings
+
+BUNDLED WITH
+   2.2.27

+ 151 - 0
android/app/build.gradle

@@ -0,0 +1,151 @@
+import groovy.json.JsonSlurper
+apply plugin: "com.android.application"
+apply plugin: "org.jetbrains.kotlin.android"
+apply plugin: "com.facebook.react"
+
+// 获取当前时间戳,格式为 yymmddHHmm
+def getTimestampVersion = {
+    def date = new Date()
+    def formattedDate = date.format('yyMMddHHmm')
+    return '1.0.0-' + formattedDate
+}
+
+def getAppVersion() {
+    // 注意文件路径,'../package.json' 表示从当前目录(android/app)向上一级到项目根目录
+    def inputFile = new File("../package.json")
+    def packageJson = new JsonSlurper().parseText(inputFile.text)
+    return packageJson["version"]
+}
+
+/**
+ * This is the configuration block to customize your React Native Android app.
+ * By default you don't need to apply any configuration, just uncomment the lines you need.
+ */
+react {
+    /* Folders */
+    //   The root of your project, i.e. where "package.json" lives. Default is '..'
+    // root = file("../")
+    //   The folder where the react-native NPM package is. Default is ../node_modules/react-native
+    // reactNativeDir = file("../node_modules/react-native")
+    //   The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
+    // codegenDir = file("../node_modules/@react-native/codegen")
+    //   The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
+    // cliFile = file("../node_modules/react-native/cli.js")
+
+    /* Variants */
+    //   The list of variants to that are debuggable. For those we're going to
+    //   skip the bundling of the JS bundle and the assets. By default is just 'debug'.
+    //   If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
+    // debuggableVariants = ["liteDebug", "prodDebug"]
+
+    /* Bundling */
+    //   A list containing the node command and its flags. Default is just 'node'.
+    // nodeExecutableAndArgs = ["node"]
+    //
+    //   The command to run when bundling. By default is 'bundle'
+    // bundleCommand = "ram-bundle"
+    //
+    //   The path to the CLI configuration file. Default is empty.
+    // bundleConfig = file(../rn-cli.config.js)
+    //
+    //   The name of the generated asset file containing your JS bundle
+    // bundleAssetName = "MyApplication.android.bundle"
+    //
+    //   The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
+    // entryFile = file("../js/MyApplication.android.js")
+    //
+    //   A list of extra flags to pass to the 'bundle' commands.
+    //   See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
+    // extraPackagerArgs = []
+
+    /* Hermes Commands */
+    //   The hermes compiler command to run. By default it is 'hermesc'
+    // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
+    //
+    //   The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
+    // hermesFlags = ["-O", "-output-source-map"]
+}
+
+/**
+ * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
+ */
+def enableProguardInReleaseBuilds = false
+
+/**
+ * The preferred build flavor of JavaScriptCore (JSC)
+ *
+ * For example, to use the international variant, you can use:
+ * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
+ *
+ * The international variant includes ICU i18n library and necessary data
+ * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
+ * give correct results when using with locales other than en-US. Note that
+ * this variant is about 6MiB larger per architecture than default.
+ */
+def jscFlavor = 'org.webkit:android-jsc:+'
+
+android {
+    ndkVersion rootProject.ext.ndkVersion
+
+    buildToolsVersion rootProject.ext.buildToolsVersion
+    compileSdk rootProject.ext.compileSdkVersion
+
+    dexOptions {
+        javaMaxHeapSize "4g"
+    }
+
+    namespace "com.tjy.app"
+    defaultConfig {
+        applicationId app_id
+        minSdkVersion rootProject.ext.minSdkVersion
+        targetSdkVersion rootProject.ext.targetSdkVersion
+        versionCode 111000
+        // versionName getTimestampVersion()
+        versionName getAppVersion() // 改为使用从 package.json 读取的版本
+    }
+    signingConfigs {
+        debug {
+            storeFile file('debug.keystore')
+            storePassword 'testAndroid'
+            keyAlias 'androiddebugkey'
+            keyPassword 'testAndroid'
+        }
+        release {
+            storeFile file('tjy-release-key.keystore')
+            storePassword 'tjy@2025'
+            keyAlias 'tjy-release-key'
+            keyPassword 'tjy@2025'
+        }
+    }
+    buildTypes {
+        debug {
+            signingConfig signingConfigs.debug
+        }
+        release {
+            // Caution! In production, you need to generate your own keystore file.
+            // see https://reactnative.dev/docs/signed-apk-android.
+            signingConfig signingConfigs.release
+            minifyEnabled enableProguardInReleaseBuilds
+            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
+//            shrinkResources true  // 移除无用资源
+//            debuggable false
+//            jniDebuggable false
+//            renderscriptDebuggable false
+        }
+    }
+}
+
+dependencies {
+    // The version of react-native is set by the React Native Gradle Plugin
+    implementation("com.facebook.react:react-android")
+    implementation 'com.facebook.fresco:animated-gif:2.5.0'
+
+    implementation("com.facebook.react:flipper-integration")
+    if (hermesEnabled.toBoolean()) {
+        implementation("com.facebook.react:hermes-android")
+    } else {
+        implementation jscFlavor
+    }
+}
+
+apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

BIN
android/app/debug.keystore


+ 48 - 0
android/app/proguard-rules.pro

@@ -0,0 +1,48 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# reanimated
+-keep class com.swmansion.reanimated.** { *; }
+-keep class com.facebook.react.turbomodule.** { *; }
+
+# skia
+-keep class com.shopify.reactnative.skia.** { *; }
+
+# ========== 高德地图保护规则 ==========
+-keep class com.amap.api.** { *; }
+-keep class com.autonavi.** { *; }
+-keep class com.loc.** { *; }
+
+-dontwarn com.amap.api.**
+-dontwarn com.autonavi.**
+-dontwarn com.loc.**
+
+# 保留所有包含"amap"的类
+-keep class **.*amap*.** { *; }
+
+# 保留React Native相关类
+-keep class com.facebook.react.** { *; }
+-keep class com.facebook.hermes.** { *; }
+
+# 保留JS调用的原生方法
+-keepclassmembers class ** {
+    @com.facebook.react.uimanager.annotations.ReactProp <methods>;
+    @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>;
+}
+
+# 保留序列化相关
+-keepattributes Signature,InnerClasses,EnclosingMethod
+-keepattributes *Annotation*
+
+# 保留本地方法
+-keepclasseswithmembernames class * {
+    native <methods>;
+}

+ 9 - 0
android/app/src/debug/AndroidManifest.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <application
+        android:usesCleartextTraffic="true"
+        tools:targetApi="28"
+        tools:ignore="GoogleAppIndexingWarning"/>
+</manifest>

+ 70 - 0
android/app/src/main/AndroidManifest.xml

@@ -0,0 +1,70 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.VIBRATE" />
+
+    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+
+    <!-- Android 10+ 需要这个权限来访问媒体文件 -->
+    <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
+
+    <!-- 添加以下 uses-feature 标签 -->
+    <uses-feature android:name="android.hardware.camera" android:required="false" />
+    <!-- 相机自动对焦特性 -->
+    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
+
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+
+    <!-- 安装未知来源应用权限 (Android 8.0+) -->
+    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
+
+    <queries>
+      <intent>
+        <action android:name="android.intent.action.DIAL" />
+      </intent>
+    </queries>
+
+    <application
+      android:name=".MainApplication"
+      android:label="@string/app_name"
+      android:icon="@mipmap/ic_launcher"
+      android:roundIcon="@mipmap/ic_launcher_round"
+      android:allowBackup="false"
+      android:theme="@style/AppTheme"
+      android:usesCleartextTraffic="true"
+      android:requestLegacyExternalStorage="true"
+      android:largeHeap="true">
+      <activity
+        android:name=".MainActivity"
+        android:label="@string/app_name"
+        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
+        android:launchMode="singleTask"
+        android:windowSoftInputMode="adjustResize"
+        android:exported="true">
+        <intent-filter>
+            <action android:name="android.intent.action.MAIN" />
+            <category android:name="android.intent.category.LAUNCHER" />
+        </intent-filter>
+        <intent-filter>
+            <action android:name="android.intent.action.VIEW"/>
+            <category android:name="android.intent.category.DEFAULT" />
+            <category android:name="android.intent.category.BROWSABLE" />
+            <data android:scheme="taro" />
+        </intent-filter>
+      </activity>
+
+        <meta-data
+            android:name="com.amap.api.v2.apikey"
+            android:value="1c6a28dc64c0c4664a70131f5d3450dd" />
+    </application>
+</manifest>

BIN
android/app/src/main/assets/fonts/Outfit-Black.ttf


BIN
android/app/src/main/assets/fonts/Outfit-Bold.ttf


BIN
android/app/src/main/assets/fonts/Outfit-ExtraBold.ttf


BIN
android/app/src/main/assets/fonts/Outfit-ExtraLight.ttf


BIN
android/app/src/main/assets/fonts/Outfit-Light.ttf


BIN
android/app/src/main/assets/fonts/Outfit-Medium.ttf


BIN
android/app/src/main/assets/fonts/Outfit-Regular.ttf


BIN
android/app/src/main/assets/fonts/Outfit-SemiBold.ttf


BIN
android/app/src/main/assets/fonts/Outfit-Thin.ttf


BIN
android/app/src/main/assets/fonts/Outfit-VariableFont_wght.ttf


File diff suppressed because it is too large
+ 2469 - 0
android/app/src/main/assets/index.android.bundle


File diff suppressed because it is too large
+ 1 - 0
android/app/src/main/assets/index.android.map


File diff suppressed because it is too large
+ 14 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/css/gc.spread.sheets.designer.18.2.4.min.css


File diff suppressed because it is too large
+ 14 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/css/gc.spread.sheets.designer.dark.18.2.4.min.css


File diff suppressed because it is too large
+ 14 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/css/gc.spread.sheets.designer.light.18.2.4.min.css


File diff suppressed because it is too large
+ 13621 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/definition/gc.spread.sheets.designer.d.ts


File diff suppressed because it is too large
+ 2081 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.all.18.2.4.min.js


File diff suppressed because it is too large
+ 85 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.cn.18.2.4.min.js


File diff suppressed because it is too large
+ 86 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.en.18.2.4.min.js


File diff suppressed because it is too large
+ 83 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.ja.18.2.4.min.js


File diff suppressed because it is too large
+ 87 - 0
android/app/src/main/assets/web-resources/SpreadJS/Designer/Designer Component/scripts/gc.spread.sheets.designer.resource.ko.18.2.4.min.js


BIN
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/GrapeCitySoftware-EULA.pdf


File diff suppressed because it is too large
+ 858 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/LICENSE


File diff suppressed because it is too large
+ 7739 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.18.2.4.css


File diff suppressed because it is too large
+ 7791 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2013darkGray.18.2.4.css


File diff suppressed because it is too large
+ 7796 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2013lightGray.18.2.4.css


File diff suppressed because it is too large
+ 7782 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2013white.18.2.4.css


File diff suppressed because it is too large
+ 7797 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2016black.18.2.4.css


File diff suppressed because it is too large
+ 7787 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2016colorful.18.2.4.css


File diff suppressed because it is too large
+ 7783 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/css/gc.spread.sheets.excel2016darkGray.18.2.4.css


+ 144 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/definition/gc.spread.excelio.d.ts

@@ -0,0 +1,144 @@
+declare module GC{
+    module Spread{
+        module Excel{
+
+            export class IO{
+                /**
+                 * Represents an excel import and export class.
+                 * @class
+                 */
+                constructor();
+                /**
+                 * Build in pivot table themes.
+                 * @type {{ [key: string]: any }}
+                 */
+                static pivotTableThemes: { [key: string]: any };
+                /**
+                 * Build in item slicer themes.
+                 * @type {{ [key: string]: any }}
+                 */
+                static slicerStyles: { [key: string]: any };
+                /**
+                 * Build in table themes.
+                 * @type {{ [key: string]: any }}
+                 */
+                static tableThemes: { [key: string]: any };
+                /**
+                 * Build in timeline slicer themes.
+                 * @type {{ [key: string]: any }}
+                 */
+                static timelineStyles: { [key: string]: any };
+                /**
+                 * Imports an excel file.
+                 * @param {Blob} file The excel file.
+                 * @param {function} successCallBack Call this function after successfully loading the file. `function (json) { }`.
+                 * @param {function} errorCallBack Call this function if an error occurs. The exception parameter object structure `{ errorCode: GC.Spread.Excel.IO.ErrorCode, errorMessage: string}`.
+                 * @param {GC.Spread.Excel.IO.OpenOptions} options The options for import excel.
+                 * @returns {void}
+                 * @example
+                 * ```
+                 * var workbook = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
+                 * var excelIO = new GC.Spread.Excel.IO();
+                 * var excelFile = document.getElementById("fileDemo").files[0];
+                 * excelIO.open(excelFile, function (json) {
+                 *    workbook.fromJSON(json);
+                 * }, function (e) {
+                 *    console.log(e);
+                 * }, {
+                 *    password: "password",
+                 *    importPictureAsFloatingObject: false
+                 * });
+                 * ```
+                 */
+                open(file: Blob,  successCallBack: Function,  errorCallBack?: Function,  options?: GC.Spread.Excel.IO.OpenOptions): void;
+                /**
+                 * Register a unknown max digit width info to ExcelIO.
+                 * @param {string} fontFamily The font family of default style's font.
+                 * @param {number} fontSize The font size of default style's font(in point).
+                 * @param {number} maxDigitWidth The  max digit width of default style's font.
+                 * @returns {void}
+                 * @example
+                 * ```
+                 * GC.Spread.Excel.IO.registerMaxDigitWidth("\ub3cb\uc6c0", 11, Math.floor(80/8.11));
+                 * ```
+                 */
+                registerMaxDigitWidth(fontFamily: string,  fontSize: number,  maxDigitWidth: number): void;
+                /**
+                 * Creates and saves an excel file with the SpreadJS json.
+                 * @param {object} json The spread sheets json object, or string.
+                 * @param {function} successCallBack Call this function after successfully exporting the file. `function (blob) { }`.
+                 * @param {function} errorCallBack Call this function if an error occurs. The exception parameter object structure `{ errorCode: GC.Spread.Excel.IO.ErrorCode, errorMessage: string}`.
+                 * @param {GC.Spread.Excel.IO.SaveOptions} options The options for export excel.
+                 * @returns {void}
+                 * @example
+                 * ```
+                 * var workbook = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
+                 * var excelIO = new GC.Spread.Excel.IO();
+                 * var json = JSON.stringify(workbook.toJSON());
+                 * excelIO.save(json, function (blob) {
+                 *    saveAs(blob, fileName); //saveAs is from FileSaver.
+                 * }, function (e) {
+                 *    console.log(e);
+                 * }, {
+                 *    password: "password",
+                 *    xlsxStrictMode: false
+                 * });
+                 * ```
+                 */
+                save(json: string | object,  successCallBack: Function,  errorCallBack?: Function,  options?: GC.Spread.Excel.IO.SaveOptions): void;
+            }
+            module IO{
+
+                /**
+                 * @typedef GC.Spread.Excel.IO.OpenOptions - The options for import excel.
+                 * @property {string} password the excel file's password.
+                 * @property {boolean} importPictureAsFloatingObject import picture as floatingObject instead of shape.
+                 */
+                export type OpenOptions = 
+                    {
+                        password?: string;
+                        importPictureAsFloatingObject?: boolean;
+                    }
+                
+
+                /**
+                 * @typedef GC.Spread.Excel.IO.SaveOptions - The options for export excel.
+                 * @property {string} password the excel file's password.
+                 * @property {boolean} xlsxStrictMode the mode of exporting process, the non-strict mode may reduce the export size. Default is true.
+                 */
+                export type SaveOptions = 
+                    {
+                        password?: string;
+                        xlsxStrictMode?: boolean;
+                    }
+                
+                /**
+                 * Specifies the excel io error code.
+                 * @enum {number}
+                 */
+                export enum ErrorCode{
+                    /**
+                     *  File read and write exception.
+                     */
+                    fileIOError= 0,
+                    /**
+                     *  Incorrect file format.
+                     */
+                    fileFormatError= 1,
+                    /**
+                     *  The Excel file cannot be opened because the workbook/worksheet is password protected.
+                     */
+                    noPassword= 2,
+                    /**
+                     *  The specified password is incorrect.
+                     */
+                    invalidPassword= 3
+                }
+
+            }
+
+        }
+
+    }
+
+}

File diff suppressed because it is too large
+ 62047 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/definition/gc.spread.sheets.d.ts


+ 59 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/default.html

@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html ng-app="waxApp">
+<head>
+    <meta charset="utf-8">
+
+    <title>AngularJS Directive Gallery</title>
+    <meta name="spreadjs culture" content="zh-cn" />
+    <!-- Bootstrap CSS -->
+    <link href="styles/bootstrap/3.2.0/bootstrap.min.css" rel="stylesheet" type="text/css">
+    <link href="styles/bootstrap/3.2.0/bootstrap-theme.min.css" rel="stylesheet" type="text/css">
+    
+    <!-- jQuery -->
+    <script src="scripts/jquery-2.1.1.min.js" type="text/javascript"></script>
+
+    <!-- AngularJS (after jQuery) -->
+    <script src="scripts/angularjs/1.2.22/angular.js" type="text/javascript"></script>
+    <script src="scripts/angularjs/1.2.22/angular-route.js" type="text/javascript"></script>
+
+    <!-- SpreadJS Reference -->
+    <script type="text/javascript" src="scripts/spreadjs/gc.spread.sheets.all.18.2.4.min.js"></script>
+    <script type="text/javascript" src="scripts/spreadjs/gc.spread.sheets.angularjs.18.2.4.min.js"></script>
+    <script type="text/javascript" src="scripts/spreadjs/gc.spread.sheets.resources.zh.18.2.4.min.js"></script>
+	<script type="text/javascript" src="scripts/license.js"></script>
+
+    <!-- app scripts and styles -->
+    <script src="scripts/waxApp.js" type="text/javascript"></script>
+    <script src="scripts/waxCtrl.js" type="text/javascript"></script>
+    <link href="styles/app.css" rel="stylesheet" type="text/css" />
+    <link href="styles/fonts.css" rel="stylesheet" type="text/css">
+
+    <!-- SpreadJS CSS -->
+    <link href="styles/spreadjs/gc.spread.sheets.excel2016colorful.18.2.4.css" rel="stylesheet" type="text/css" />   
+</head>
+<body ng-controller="waxCtrl">
+    <div class="mainContainer">
+        <div class="contentContainer">
+            <h1 class="content">
+                <img class="logo" src="img/logo.png" alt="logo" />
+                AngularJS Directive Gallery
+            </h1>
+        </div>
+        <div class="contentContainer">
+            <div class="leftContainer content">
+                <h4>SpreadJS</h4>
+                <ul>
+                    <li><a href="#/spreadjs/databinding">Data Binding</a></li>
+                    <li><a href="#/spreadjs/layout">Layout</a></li>
+                    <li><a href="#/spreadjs/style">Style</a></li>
+                    <li><a href="#/spreadjs/celltype">Cell Type</a></li>
+                    <li><a href="#/spreadjs/datavalidation">Data Validation</a></li>
+                </ul>
+            </div>
+            <div class="rightContainer content">
+                <div ng-view></div>
+            </div>
+        </div>
+    </div>
+</body>
+</html>

BIN
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/img/logo.png


+ 22 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/home.htm

@@ -0,0 +1,22 @@
+<h3>Home</h3>
+
+<p>This sample shows how you can create and use directives in your AngularJS 
+applications.</p>
+
+<p>Directives encapsulate HTML and javascript into re-usable units that can 
+be tested and maintained independently. Using directives is very easy, all 
+you have to do is include the directive definitions in your HTML pages and 
+then use the directive tags as you would any regular HTML tag.</p>
+
+<p>The SpreadJS library includes AngularJS directives
+that make development more declarative, with views that contain only markup
+(no script) and are compact, expressive, easy to create, and easy to maintain.</p>
+
+<p>In addition to those directives, we also created additional directive sets 
+for SpreadJS as well as for common UI elements.
+
+<p>These directives allow you to focus on writing your application logic and
+pure HTML5 markup (writing the code that only <i>you</i> can write).</p>
+
+<p>Feel free to use these directives as they are, to customize them, or to
+use them as a starting point for writing your own.</p>

+ 36 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/celltype.html

@@ -0,0 +1,36 @@
+<h3>SpreadJS Cell Type</h3>
+
+<p>
+    The sample below shows how to ceate cell types that define cell's appearance and behavior.
+</p>
+
+<gc-spread-sheets id="ss" newtabvisible="false">
+    <worksheets>
+        <worksheet datasource="employees">
+            <columns>
+                <column width="130" datafield="name" headertext="Name"></column>
+                <column width="90" datafield="phone" headertext="Phone"></column>
+                <column width="80" datafield="country" headertext="Country">
+                    <default-style>
+                        <combobox-cell-type>
+                            <item text="US"></item>
+                            <item text="UK"></item>
+                            <item text="Germany"></item>
+                            <item text="Maxico"></item>
+                        </combobox-cell-type>
+                    </default-style>
+                </column>
+                <column width="240" datafield="email" headertext="Email">
+                    <default-style>
+                        <hyperlink-cell-type></hyperlink-cell-type>
+                    </default-style>
+                </column>
+                <column datafield="onJob" headertext="OnJob">
+                    <default-style halign="center">
+                        <checkbox-cell-type></checkbox-cell-type>
+                    </default-style>
+                </column>
+            </columns>
+        </worksheet>
+    </worksheets>
+</gc-spread-sheets>

+ 23 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/databinding.html

@@ -0,0 +1,23 @@
+<h3>SpreadJS Data Binding</h3>
+
+<p>
+    The sample below is bound to the list of major US airports and their traffic in 2005-2011.
+    <br />
+    The first sheet is bound all data from data source, and the second sheet is bound 2011 data from data source.
+</p>
+
+<gc-spread-sheets id="ssdb" newtabvisible="false">
+    <worksheets>
+        <worksheet datasource="airports" name="All Data"></worksheet>
+        <worksheet datasource="airports" name="Part Data">
+            <columns>
+                <column datafield="name" headertext="Name"></column>
+                <column datafield="city" headertext="City"></column>
+                <column datafield="state" headertext="State"></column>
+                <column datafield="lat" headertext="Lat"></column>
+                <column datafield="lon" headertext="Lon"></column>
+                <column datafield="vol2011" headertext="Vol2011"></column>
+            </columns>
+        </worksheet>
+    </worksheets>
+</gc-spread-sheets>

+ 23 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/datavalidation.html

@@ -0,0 +1,23 @@
+<h3>SpreadJS Data Validation</h3>
+
+<p>
+    The sample below shows how to ceate Excel-like validation.
+</p>
+
+<gc-spread-sheets id="ss" newtabvisible="false" highlightinvaliddata="true">
+    <worksheets>
+        <worksheet datasource="employees">
+            <columns>
+                <column width="130" datafield="name" headertext="Name"></column>
+                <column width="90" datafield="phone" headertext="Phone"></column>
+                <column width="80" datafield="country" headertext="Country">
+                    <data-validation>
+                        <list-validator list="Japan,Germany,UK,Italy,US"></list-validator>
+                    </data-validation>
+                </column>
+                <column width="240" datafield="email" headertext="Email"></column>
+                <column datafield="onJob" headertext="OnJob"></column>
+            </columns>
+        </worksheet>
+    </worksheets>
+</gc-spread-sheets>

+ 85 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/layout.html

@@ -0,0 +1,85 @@
+<h3>SpreadJS Layout</h3>
+
+<p>
+    The sample below shows how to bind some properties of spread and sheet bilaterally.
+</p>
+
+<gc-spread-sheets id="ss"
+    newtabvisible="{{newTabVisible}}"
+    tabstripvisible="{{tabStripVisible}}"
+    showhorizontalscrollbar="{{showHorizontalScrollbar}}"
+    showverticalscrollbar="{{showVerticalScrollbar}}"
+    backcolor="{{backColor}}">
+    <worksheets>
+        <worksheet rowcount="20" colcount="10"
+                   frozenrowcount="{{frozenRowCount}}"
+                   frozencolumncount="{{frozenColumnCount}}"
+                   frozentrailingrowcount="{{frozenTrailingRowCount}}"
+                   frozentrailingcolumncount="{{frozenTrailingColumnCount}}"
+                   frozenlinecolor="{{frozenlineColor}}"
+                   rowheadervisible="{{rowHeaderVisible}}"
+                   colheadervisible="{{columnHeaderVisible}}"
+                   selectionbackcolor="{{selectionBackColor}}"
+                   selectionbordercolor="{{selectionBorderColor}}">
+        </worksheet>
+    </worksheets>
+</gc-spread-sheets>
+
+<table>
+    <tr>
+        <td>
+            <label><input type="checkbox" ng-model="newTabVisible" />newTabVisible</label>
+        </td>
+        <td>
+            <label><input type="checkbox" ng-model="tabStripVisible" />tabStripVisible</label>
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <label><input type="checkbox" ng-model="showHorizontalScrollbar" />showHorizontalScrollbar</label>
+        </td>
+        <td>
+            <label><input type="checkbox" ng-model="showVerticalScrollbar " />showVerticalScrollbar</label>
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <label><input type="checkbox" ng-model="rowHeaderVisible" />rowHeaderVisible</label>
+        </td>
+        <td>
+            <label><input type="checkbox" ng-model="columnHeaderVisible" />columnHeaderVisible</label>
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <input type="text" ng-model="backColor" />backColor
+        </td>
+        <td>
+            <input type="text" ng-model="frozenlineColor" />frozenlineColor
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <input type="text" ng-model="frozenRowCount" />frozenRowCount
+        </td>
+        <td>
+            <input type="text" ng-model="frozenColumnCount" />frozenColumnCount
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <input type="text" ng-model="frozenTrailingRowCount" />frozenTrailingRowCount
+        </td>
+        <td>
+            <input type="text" ng-model="frozenTrailingColumnCount" />frozenTrailingColumnCount
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <input type="text" ng-model="selectionBackColor" />selectionBackColor
+        </td>
+        <td>
+            <input type="text" ng-model="selectionBorderColor" />selectionBorderColor
+        </td>
+    </tr>
+</table>

+ 26 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/partials/spreadjs/style.html

@@ -0,0 +1,26 @@
+<h3>SpreadJS Style</h3>
+
+<p>
+    The sample below shows how to ceate style for column header cells, row header cells and viewport cells.
+</p>
+
+<gc-spread-sheets id="ss" newtabvisible="false">
+    <worksheets>
+        <worksheet datasource="employees">
+            <column-header-default-style borderright="#9BBB59" borderbottom="#9BBB59" font="bold 10pt Arial"></column-header-default-style>
+            <row-header-default-style borderright="#9BBB59" borderbottom="#9BBB59" font="italic 10pt Arial"></row-header-default-style>
+            <default-style backcolor="#EBF1DE" borderright="#9BBB59" borderbottom="#9BBB59"></default-style>
+            <columns>
+                <column autofit="true" datafield="name" headertext="Name"></column>
+                <column autofit="true" datafield="phone" headertext="Phone">
+                    <default-style backcolor="white"></default-style>
+                </column>
+                <column autofit="true" datafield="country" headertext="Country"></column>
+                <column autofit="true" datafield="email" headertext="Email">
+                    <default-style backcolor="white"></default-style>
+                </column>
+                <column autofit="true" datafield="onJob" headertext="OnJob"></column>
+            </columns>
+        </worksheet>
+    </worksheets>
+</gc-spread-sheets>

+ 17 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/readme.txt

@@ -0,0 +1,17 @@
+AngularJSExplorer
+--------------------------------------------------------------
+Shows how to create and use directives in AngularJS applications.
+
+Directives encapsulate HTML and javascript into re-usable units that can be tested 
+and maintained independently. Using directives is very easy, all you have to do is 
+include the directive definitions in your HTML pages and then use the directive 
+tags as you would any regular HTML tag. Parameters are passed as regular attributes,
+and they can be data-bound.
+
+SpreadJS ships with AngularJS directives for almost all its module. This makes it easy to develop
+and maintain AngularJS applications, with views that contain pure markup and little 
+or no script.
+
+You can use all these directives as they are or customize them to fit your needs.
+
+<product>SpreadJS;HTML5</product>

+ 925 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/angularjs/1.2.22/angular-route.js

@@ -0,0 +1,925 @@
+/**
+ * @license AngularJS v1.2.22
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc module
+ * @name ngRoute
+ * @description
+ *
+ * # ngRoute
+ *
+ * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
+ *
+ * ## Example
+ * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
+ *
+ *
+ * <div doc-module-components="ngRoute"></div>
+ */
+ /* global -ngRouteModule */
+var ngRouteModule = angular.module('ngRoute', ['ng']).
+                        provider('$route', $RouteProvider);
+
+/**
+ * @ngdoc provider
+ * @name $routeProvider
+ * @kind function
+ *
+ * @description
+ *
+ * Used for configuring routes.
+ *
+ * ## Example
+ * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
+ *
+ * ## Dependencies
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ */
+function $RouteProvider(){
+  function inherit(parent, extra) {
+    return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra);
+  }
+
+  var routes = {};
+
+  /**
+   * @ngdoc method
+   * @name $routeProvider#when
+   *
+   * @param {string} path Route path (matched against `$location.path`). If `$location.path`
+   *    contains redundant trailing slash or is missing one, the route will still match and the
+   *    `$location.path` will be updated to add or drop the trailing slash to exactly match the
+   *    route definition.
+   *
+   *    * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up
+   *        to the next slash are matched and stored in `$routeParams` under the given `name`
+   *        when the route matches.
+   *    * `path` can contain named groups starting with a colon and ending with a star:
+   *        e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name`
+   *        when the route matches.
+   *    * `path` can contain optional named groups with a question mark: e.g.`:name?`.
+   *
+   *    For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
+   *    `/color/brown/largecode/code/with/slashes/edit` and extract:
+   *
+   *    * `color: brown`
+   *    * `largecode: code/with/slashes`.
+   *
+   *
+   * @param {Object} route Mapping information to be assigned to `$route.current` on route
+   *    match.
+   *
+   *    Object properties:
+   *
+   *    - `controller` – `{(string|function()=}` – Controller fn that should be associated with
+   *      newly created scope or the name of a {@link angular.Module#controller registered
+   *      controller} if passed as a string.
+   *    - `controllerAs` – `{string=}` – A controller alias name. If present the controller will be
+   *      published to scope under the `controllerAs` name.
+   *    - `template` – `{string=|function()=}` – html template as a string or a function that
+   *      returns an html template as a string which should be used by {@link
+   *      ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
+   *      This property takes precedence over `templateUrl`.
+   *
+   *      If `template` is a function, it will be called with the following parameters:
+   *
+   *      - `{Array.<Object>}` - route parameters extracted from the current
+   *        `$location.path()` by applying the current route
+   *
+   *    - `templateUrl` – `{string=|function()=}` – path or function that returns a path to an html
+   *      template that should be used by {@link ngRoute.directive:ngView ngView}.
+   *
+   *      If `templateUrl` is a function, it will be called with the following parameters:
+   *
+   *      - `{Array.<Object>}` - route parameters extracted from the current
+   *        `$location.path()` by applying the current route
+   *
+   *    - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
+   *      be injected into the controller. If any of these dependencies are promises, the router
+   *      will wait for them all to be resolved or one to be rejected before the controller is
+   *      instantiated.
+   *      If all the promises are resolved successfully, the values of the resolved promises are
+   *      injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
+   *      fired. If any of the promises are rejected the
+   *      {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
+   *      is:
+   *
+   *      - `key` – `{string}`: a name of a dependency to be injected into the controller.
+   *      - `factory` - `{string|function}`: If `string` then it is an alias for a service.
+   *        Otherwise if function, then it is {@link auto.$injector#invoke injected}
+   *        and the return value is treated as the dependency. If the result is a promise, it is
+   *        resolved before its value is injected into the controller. Be aware that
+   *        `ngRoute.$routeParams` will still refer to the previous route within these resolve
+   *        functions.  Use `$route.current.params` to access the new route parameters, instead.
+   *
+   *    - `redirectTo` – {(string|function())=} – value to update
+   *      {@link ng.$location $location} path with and trigger route redirection.
+   *
+   *      If `redirectTo` is a function, it will be called with the following parameters:
+   *
+   *      - `{Object.<string>}` - route parameters extracted from the current
+   *        `$location.path()` by applying the current route templateUrl.
+   *      - `{string}` - current `$location.path()`
+   *      - `{Object}` - current `$location.search()`
+   *
+   *      The custom `redirectTo` function is expected to return a string which will be used
+   *      to update `$location.path()` and `$location.search()`.
+   *
+   *    - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
+   *      or `$location.hash()` changes.
+   *
+   *      If the option is set to `false` and url in the browser changes, then
+   *      `$routeUpdate` event is broadcasted on the root scope.
+   *
+   *    - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
+   *
+   *      If the option is set to `true`, then the particular route can be matched without being
+   *      case sensitive
+   *
+   * @returns {Object} self
+   *
+   * @description
+   * Adds a new route definition to the `$route` service.
+   */
+  this.when = function(path, route) {
+    routes[path] = angular.extend(
+      {reloadOnSearch: true},
+      route,
+      path && pathRegExp(path, route)
+    );
+
+    // create redirection for trailing slashes
+    if (path) {
+      var redirectPath = (path[path.length-1] == '/')
+            ? path.substr(0, path.length-1)
+            : path +'/';
+
+      routes[redirectPath] = angular.extend(
+        {redirectTo: path},
+        pathRegExp(redirectPath, route)
+      );
+    }
+
+    return this;
+  };
+
+   /**
+    * @param path {string} path
+    * @param opts {Object} options
+    * @return {?Object}
+    *
+    * @description
+    * Normalizes the given path, returning a regular expression
+    * and the original path.
+    *
+    * Inspired by pathRexp in visionmedia/express/lib/utils.js.
+    */
+  function pathRegExp(path, opts) {
+    var insensitive = opts.caseInsensitiveMatch,
+        ret = {
+          originalPath: path,
+          regexp: path
+        },
+        keys = ret.keys = [];
+
+    path = path
+      .replace(/([().])/g, '\\$1')
+      .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option){
+        var optional = option === '?' ? option : null;
+        var star = option === '*' ? option : null;
+        keys.push({ name: key, optional: !!optional });
+        slash = slash || '';
+        return ''
+          + (optional ? '' : slash)
+          + '(?:'
+          + (optional ? slash : '')
+          + (star && '(.+?)' || '([^/]+)')
+          + (optional || '')
+          + ')'
+          + (optional || '');
+      })
+      .replace(/([\/$\*])/g, '\\$1');
+
+    ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
+    return ret;
+  }
+
+  /**
+   * @ngdoc method
+   * @name $routeProvider#otherwise
+   *
+   * @description
+   * Sets route definition that will be used on route change when no other route definition
+   * is matched.
+   *
+   * @param {Object} params Mapping information to be assigned to `$route.current`.
+   * @returns {Object} self
+   */
+  this.otherwise = function(params) {
+    this.when(null, params);
+    return this;
+  };
+
+
+  this.$get = ['$rootScope',
+               '$location',
+               '$routeParams',
+               '$q',
+               '$injector',
+               '$http',
+               '$templateCache',
+               '$sce',
+      function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
+
+    /**
+     * @ngdoc service
+     * @name $route
+     * @requires $location
+     * @requires $routeParams
+     *
+     * @property {Object} current Reference to the current route definition.
+     * The route definition contains:
+     *
+     *   - `controller`: The controller constructor as define in route definition.
+     *   - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
+     *     controller instantiation. The `locals` contain
+     *     the resolved values of the `resolve` map. Additionally the `locals` also contain:
+     *
+     *     - `$scope` - The current route scope.
+     *     - `$template` - The current route template HTML.
+     *
+     * @property {Object} routes Object with all route configuration Objects as its properties.
+     *
+     * @description
+     * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
+     * It watches `$location.url()` and tries to map the path to an existing route definition.
+     *
+     * Requires the {@link ngRoute `ngRoute`} module to be installed.
+     *
+     * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
+     *
+     * The `$route` service is typically used in conjunction with the
+     * {@link ngRoute.directive:ngView `ngView`} directive and the
+     * {@link ngRoute.$routeParams `$routeParams`} service.
+     *
+     * @example
+     * This example shows how changing the URL hash causes the `$route` to match a route against the
+     * URL, and the `ngView` pulls in the partial.
+     *
+     * Note that this example is using {@link ng.directive:script inlined templates}
+     * to get it working on jsfiddle as well.
+     *
+     * <example name="$route-service" module="ngRouteExample"
+     *          deps="angular-route.js" fixBase="true">
+     *   <file name="index.html">
+     *     <div ng-controller="MainController">
+     *       Choose:
+     *       <a href="Book/Moby">Moby</a> |
+     *       <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+     *       <a href="Book/Gatsby">Gatsby</a> |
+     *       <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+     *       <a href="Book/Scarlet">Scarlet Letter</a><br/>
+     *
+     *       <div ng-view></div>
+     *
+     *       <hr />
+     *
+     *       <pre>$location.path() = {{$location.path()}}</pre>
+     *       <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
+     *       <pre>$route.current.params = {{$route.current.params}}</pre>
+     *       <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
+     *       <pre>$routeParams = {{$routeParams}}</pre>
+     *     </div>
+     *   </file>
+     *
+     *   <file name="book.html">
+     *     controller: {{name}}<br />
+     *     Book Id: {{params.bookId}}<br />
+     *   </file>
+     *
+     *   <file name="chapter.html">
+     *     controller: {{name}}<br />
+     *     Book Id: {{params.bookId}}<br />
+     *     Chapter Id: {{params.chapterId}}
+     *   </file>
+     *
+     *   <file name="script.js">
+     *     angular.module('ngRouteExample', ['ngRoute'])
+     *
+     *      .controller('MainController', function($scope, $route, $routeParams, $location) {
+     *          $scope.$route = $route;
+     *          $scope.$location = $location;
+     *          $scope.$routeParams = $routeParams;
+     *      })
+     *
+     *      .controller('BookController', function($scope, $routeParams) {
+     *          $scope.name = "BookController";
+     *          $scope.params = $routeParams;
+     *      })
+     *
+     *      .controller('ChapterController', function($scope, $routeParams) {
+     *          $scope.name = "ChapterController";
+     *          $scope.params = $routeParams;
+     *      })
+     *
+     *     .config(function($routeProvider, $locationProvider) {
+     *       $routeProvider
+     *        .when('/Book/:bookId', {
+     *         templateUrl: 'book.html',
+     *         controller: 'BookController',
+     *         resolve: {
+     *           // I will cause a 1 second delay
+     *           delay: function($q, $timeout) {
+     *             var delay = $q.defer();
+     *             $timeout(delay.resolve, 1000);
+     *             return delay.promise;
+     *           }
+     *         }
+     *       })
+     *       .when('/Book/:bookId/ch/:chapterId', {
+     *         templateUrl: 'chapter.html',
+     *         controller: 'ChapterController'
+     *       });
+     *
+     *       // configure html5 to get links working on jsfiddle
+     *       $locationProvider.html5Mode(true);
+     *     });
+     *
+     *   </file>
+     *
+     *   <file name="protractor.js" type="protractor">
+     *     it('should load and compile correct template', function() {
+     *       element(by.linkText('Moby: Ch1')).click();
+     *       var content = element(by.css('[ng-view]')).getText();
+     *       expect(content).toMatch(/controller\: ChapterController/);
+     *       expect(content).toMatch(/Book Id\: Moby/);
+     *       expect(content).toMatch(/Chapter Id\: 1/);
+     *
+     *       element(by.partialLinkText('Scarlet')).click();
+     *
+     *       content = element(by.css('[ng-view]')).getText();
+     *       expect(content).toMatch(/controller\: BookController/);
+     *       expect(content).toMatch(/Book Id\: Scarlet/);
+     *     });
+     *   </file>
+     * </example>
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeChangeStart
+     * @eventType broadcast on root scope
+     * @description
+     * Broadcasted before a route change. At this  point the route services starts
+     * resolving all of the dependencies needed for the route change to occur.
+     * Typically this involves fetching the view template as well as any dependencies
+     * defined in `resolve` route property. Once  all of the dependencies are resolved
+     * `$routeChangeSuccess` is fired.
+     *
+     * @param {Object} angularEvent Synthetic event object.
+     * @param {Route} next Future route information.
+     * @param {Route} current Current route information.
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeChangeSuccess
+     * @eventType broadcast on root scope
+     * @description
+     * Broadcasted after a route dependencies are resolved.
+     * {@link ngRoute.directive:ngView ngView} listens for the directive
+     * to instantiate the controller and render the view.
+     *
+     * @param {Object} angularEvent Synthetic event object.
+     * @param {Route} current Current route information.
+     * @param {Route|Undefined} previous Previous route information, or undefined if current is
+     * first route entered.
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeChangeError
+     * @eventType broadcast on root scope
+     * @description
+     * Broadcasted if any of the resolve promises are rejected.
+     *
+     * @param {Object} angularEvent Synthetic event object
+     * @param {Route} current Current route information.
+     * @param {Route} previous Previous route information.
+     * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
+     */
+
+    /**
+     * @ngdoc event
+     * @name $route#$routeUpdate
+     * @eventType broadcast on root scope
+     * @description
+     *
+     * The `reloadOnSearch` property has been set to false, and we are reusing the same
+     * instance of the Controller.
+     */
+
+    var forceReload = false,
+        $route = {
+          routes: routes,
+
+          /**
+           * @ngdoc method
+           * @name $route#reload
+           *
+           * @description
+           * Causes `$route` service to reload the current route even if
+           * {@link ng.$location $location} hasn't changed.
+           *
+           * As a result of that, {@link ngRoute.directive:ngView ngView}
+           * creates new scope, reinstantiates the controller.
+           */
+          reload: function() {
+            forceReload = true;
+            $rootScope.$evalAsync(updateRoute);
+          }
+        };
+
+    $rootScope.$on('$locationChangeSuccess', updateRoute);
+
+    return $route;
+
+    /////////////////////////////////////////////////////
+
+    /**
+     * @param on {string} current url
+     * @param route {Object} route regexp to match the url against
+     * @return {?Object}
+     *
+     * @description
+     * Check if the route matches the current url.
+     *
+     * Inspired by match in
+     * visionmedia/express/lib/router/router.js.
+     */
+    function switchRouteMatcher(on, route) {
+      var keys = route.keys,
+          params = {};
+
+      if (!route.regexp) return null;
+
+      var m = route.regexp.exec(on);
+      if (!m) return null;
+
+      for (var i = 1, len = m.length; i < len; ++i) {
+        var key = keys[i - 1];
+
+        var val = m[i];
+
+        if (key && val) {
+          params[key.name] = val;
+        }
+      }
+      return params;
+    }
+
+    function updateRoute() {
+      var next = parseRoute(),
+          last = $route.current;
+
+      if (next && last && next.$$route === last.$$route
+          && angular.equals(next.pathParams, last.pathParams)
+          && !next.reloadOnSearch && !forceReload) {
+        last.params = next.params;
+        angular.copy(last.params, $routeParams);
+        $rootScope.$broadcast('$routeUpdate', last);
+      } else if (next || last) {
+        forceReload = false;
+        $rootScope.$broadcast('$routeChangeStart', next, last);
+        $route.current = next;
+        if (next) {
+          if (next.redirectTo) {
+            if (angular.isString(next.redirectTo)) {
+              $location.path(interpolate(next.redirectTo, next.params)).search(next.params)
+                       .replace();
+            } else {
+              $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))
+                       .replace();
+            }
+          }
+        }
+
+        $q.when(next).
+          then(function() {
+            if (next) {
+              var locals = angular.extend({}, next.resolve),
+                  template, templateUrl;
+
+              angular.forEach(locals, function(value, key) {
+                locals[key] = angular.isString(value) ?
+                    $injector.get(value) : $injector.invoke(value);
+              });
+
+              if (angular.isDefined(template = next.template)) {
+                if (angular.isFunction(template)) {
+                  template = template(next.params);
+                }
+              } else if (angular.isDefined(templateUrl = next.templateUrl)) {
+                if (angular.isFunction(templateUrl)) {
+                  templateUrl = templateUrl(next.params);
+                }
+                templateUrl = $sce.getTrustedResourceUrl(templateUrl);
+                if (angular.isDefined(templateUrl)) {
+                  next.loadedTemplateUrl = templateUrl;
+                  template = $http.get(templateUrl, {cache: $templateCache}).
+                      then(function(response) { return response.data; });
+                }
+              }
+              if (angular.isDefined(template)) {
+                locals['$template'] = template;
+              }
+              return $q.all(locals);
+            }
+          }).
+          // after route change
+          then(function(locals) {
+            if (next == $route.current) {
+              if (next) {
+                next.locals = locals;
+                angular.copy(next.params, $routeParams);
+              }
+              $rootScope.$broadcast('$routeChangeSuccess', next, last);
+            }
+          }, function(error) {
+            if (next == $route.current) {
+              $rootScope.$broadcast('$routeChangeError', next, last, error);
+            }
+          });
+      }
+    }
+
+
+    /**
+     * @returns {Object} the current active route, by matching it against the URL
+     */
+    function parseRoute() {
+      // Match a route
+      var params, match;
+      angular.forEach(routes, function(route, path) {
+        if (!match && (params = switchRouteMatcher($location.path(), route))) {
+          match = inherit(route, {
+            params: angular.extend({}, $location.search(), params),
+            pathParams: params});
+          match.$$route = route;
+        }
+      });
+      // No route matched; fallback to "otherwise" route
+      return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
+    }
+
+    /**
+     * @returns {string} interpolation of the redirect path with the parameters
+     */
+    function interpolate(string, params) {
+      var result = [];
+      angular.forEach((string||'').split(':'), function(segment, i) {
+        if (i === 0) {
+          result.push(segment);
+        } else {
+          var segmentMatch = segment.match(/(\w+)(.*)/);
+          var key = segmentMatch[1];
+          result.push(params[key]);
+          result.push(segmentMatch[2] || '');
+          delete params[key];
+        }
+      });
+      return result.join('');
+    }
+  }];
+}
+
+ngRouteModule.provider('$routeParams', $RouteParamsProvider);
+
+
+/**
+ * @ngdoc service
+ * @name $routeParams
+ * @requires $route
+ *
+ * @description
+ * The `$routeParams` service allows you to retrieve the current set of route parameters.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * The route parameters are a combination of {@link ng.$location `$location`}'s
+ * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}.
+ * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
+ *
+ * In case of parameter name collision, `path` params take precedence over `search` params.
+ *
+ * The service guarantees that the identity of the `$routeParams` object will remain unchanged
+ * (but its properties will likely change) even when a route change occurs.
+ *
+ * Note that the `$routeParams` are only updated *after* a route change completes successfully.
+ * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
+ * Instead you can use `$route.current.params` to access the new route's parameters.
+ *
+ * @example
+ * ```js
+ *  // Given:
+ *  // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
+ *  // Route: /Chapter/:chapterId/Section/:sectionId
+ *  //
+ *  // Then
+ *  $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
+ * ```
+ */
+function $RouteParamsProvider() {
+  this.$get = function() { return {}; };
+}
+
+ngRouteModule.directive('ngView', ngViewFactory);
+ngRouteModule.directive('ngView', ngViewFillContentFactory);
+
+
+/**
+ * @ngdoc directive
+ * @name ngView
+ * @restrict ECA
+ *
+ * @description
+ * # Overview
+ * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
+ * including the rendered template of the current route into the main layout (`index.html`) file.
+ * Every time the current route changes, the included view changes with it according to the
+ * configuration of the `$route` service.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * @animations
+ * enter - animation is used to bring new content into the browser.
+ * leave - animation is used to animate existing content away.
+ *
+ * The enter and leave animation occur concurrently.
+ *
+ * @scope
+ * @priority 400
+ * @param {string=} onload Expression to evaluate whenever the view updates.
+ *
+ * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll
+ *                  $anchorScroll} to scroll the viewport after the view is updated.
+ *
+ *                  - If the attribute is not set, disable scrolling.
+ *                  - If the attribute is set without value, enable scrolling.
+ *                  - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated
+ *                    as an expression yields a truthy value.
+ * @example
+    <example name="ngView-directive" module="ngViewExample"
+             deps="angular-route.js;angular-animate.js"
+             animations="true" fixBase="true">
+      <file name="index.html">
+        <div ng-controller="MainCtrl as main">
+          Choose:
+          <a href="Book/Moby">Moby</a> |
+          <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+          <a href="Book/Gatsby">Gatsby</a> |
+          <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+          <a href="Book/Scarlet">Scarlet Letter</a><br/>
+
+          <div class="view-animate-container">
+            <div ng-view class="view-animate"></div>
+          </div>
+          <hr />
+
+          <pre>$location.path() = {{main.$location.path()}}</pre>
+          <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
+          <pre>$route.current.params = {{main.$route.current.params}}</pre>
+          <pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre>
+          <pre>$routeParams = {{main.$routeParams}}</pre>
+        </div>
+      </file>
+
+      <file name="book.html">
+        <div>
+          controller: {{book.name}}<br />
+          Book Id: {{book.params.bookId}}<br />
+        </div>
+      </file>
+
+      <file name="chapter.html">
+        <div>
+          controller: {{chapter.name}}<br />
+          Book Id: {{chapter.params.bookId}}<br />
+          Chapter Id: {{chapter.params.chapterId}}
+        </div>
+      </file>
+
+      <file name="animations.css">
+        .view-animate-container {
+          position:relative;
+          height:100px!important;
+          position:relative;
+          background:white;
+          border:1px solid black;
+          height:40px;
+          overflow:hidden;
+        }
+
+        .view-animate {
+          padding:10px;
+        }
+
+        .view-animate.ng-enter, .view-animate.ng-leave {
+          -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+          transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+
+          display:block;
+          width:100%;
+          border-left:1px solid black;
+
+          position:absolute;
+          top:0;
+          left:0;
+          right:0;
+          bottom:0;
+          padding:10px;
+        }
+
+        .view-animate.ng-enter {
+          left:100%;
+        }
+        .view-animate.ng-enter.ng-enter-active {
+          left:0;
+        }
+        .view-animate.ng-leave.ng-leave-active {
+          left:-100%;
+        }
+      </file>
+
+      <file name="script.js">
+        angular.module('ngViewExample', ['ngRoute', 'ngAnimate'])
+          .config(['$routeProvider', '$locationProvider',
+            function($routeProvider, $locationProvider) {
+              $routeProvider
+                .when('/Book/:bookId', {
+                  templateUrl: 'book.html',
+                  controller: 'BookCtrl',
+                  controllerAs: 'book'
+                })
+                .when('/Book/:bookId/ch/:chapterId', {
+                  templateUrl: 'chapter.html',
+                  controller: 'ChapterCtrl',
+                  controllerAs: 'chapter'
+                });
+
+              // configure html5 to get links working on jsfiddle
+              $locationProvider.html5Mode(true);
+          }])
+          .controller('MainCtrl', ['$route', '$routeParams', '$location',
+            function($route, $routeParams, $location) {
+              this.$route = $route;
+              this.$location = $location;
+              this.$routeParams = $routeParams;
+          }])
+          .controller('BookCtrl', ['$routeParams', function($routeParams) {
+            this.name = "BookCtrl";
+            this.params = $routeParams;
+          }])
+          .controller('ChapterCtrl', ['$routeParams', function($routeParams) {
+            this.name = "ChapterCtrl";
+            this.params = $routeParams;
+          }]);
+
+      </file>
+
+      <file name="protractor.js" type="protractor">
+        it('should load and compile correct template', function() {
+          element(by.linkText('Moby: Ch1')).click();
+          var content = element(by.css('[ng-view]')).getText();
+          expect(content).toMatch(/controller\: ChapterCtrl/);
+          expect(content).toMatch(/Book Id\: Moby/);
+          expect(content).toMatch(/Chapter Id\: 1/);
+
+          element(by.partialLinkText('Scarlet')).click();
+
+          content = element(by.css('[ng-view]')).getText();
+          expect(content).toMatch(/controller\: BookCtrl/);
+          expect(content).toMatch(/Book Id\: Scarlet/);
+        });
+      </file>
+    </example>
+ */
+
+
+/**
+ * @ngdoc event
+ * @name ngView#$viewContentLoaded
+ * @eventType emit on the current ngView scope
+ * @description
+ * Emitted every time the ngView content is reloaded.
+ */
+ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];
+function ngViewFactory(   $route,   $anchorScroll,   $animate) {
+  return {
+    restrict: 'ECA',
+    terminal: true,
+    priority: 400,
+    transclude: 'element',
+    link: function(scope, $element, attr, ctrl, $transclude) {
+        var currentScope,
+            currentElement,
+            previousElement,
+            autoScrollExp = attr.autoscroll,
+            onloadExp = attr.onload || '';
+
+        scope.$on('$routeChangeSuccess', update);
+        update();
+
+        function cleanupLastView() {
+          if(previousElement) {
+            previousElement.remove();
+            previousElement = null;
+          }
+          if(currentScope) {
+            currentScope.$destroy();
+            currentScope = null;
+          }
+          if(currentElement) {
+            $animate.leave(currentElement, function() {
+              previousElement = null;
+            });
+            previousElement = currentElement;
+            currentElement = null;
+          }
+        }
+
+        function update() {
+          var locals = $route.current && $route.current.locals,
+              template = locals && locals.$template;
+
+          if (angular.isDefined(template)) {
+            var newScope = scope.$new();
+            var current = $route.current;
+
+            // Note: This will also link all children of ng-view that were contained in the original
+            // html. If that content contains controllers, ... they could pollute/change the scope.
+            // However, using ng-view on an element with additional content does not make sense...
+            // Note: We can't remove them in the cloneAttchFn of $transclude as that
+            // function is called before linking the content, which would apply child
+            // directives to non existing elements.
+            var clone = $transclude(newScope, function(clone) {
+              $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {
+                if (angular.isDefined(autoScrollExp)
+                  && (!autoScrollExp || scope.$eval(autoScrollExp))) {
+                  $anchorScroll();
+                }
+              });
+              cleanupLastView();
+            });
+
+            currentElement = clone;
+            currentScope = current.scope = newScope;
+            currentScope.$emit('$viewContentLoaded');
+            currentScope.$eval(onloadExp);
+          } else {
+            cleanupLastView();
+          }
+        }
+    }
+  };
+}
+
+// This directive is called during the $transclude call of the first `ngView` directive.
+// It will replace and compile the content of the element with the loaded template.
+// We need this directive so that the element content is already filled when
+// the link function of another directive on the same element as ngView
+// is called.
+ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route'];
+function ngViewFillContentFactory($compile, $controller, $route) {
+  return {
+    restrict: 'ECA',
+    priority: -400,
+    link: function(scope, $element) {
+      var current = $route.current,
+          locals = current.locals;
+
+      $element.html(locals.$template);
+
+      var link = $compile($element.contents());
+
+      if (current.controller) {
+        locals.$scope = scope;
+        var controller = $controller(current.controller, locals);
+        if (current.controllerAs) {
+          scope[current.controllerAs] = controller;
+        }
+        $element.data('$ngControllerController', controller);
+        $element.children().data('$ngControllerController', controller);
+      }
+
+      link(scope);
+    }
+  };
+}
+
+
+})(window, window.angular);

File diff suppressed because it is too large
+ 21922 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/angularjs/1.2.22/angular.js


File diff suppressed because it is too large
+ 4 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/jquery-2.1.1.min.js


+ 2 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/license.js

@@ -0,0 +1,2 @@
+//Please provide valid license key.
+//GC.Spread.Sheets.LicenseKey = "Your key";

File diff suppressed because it is too large
+ 12 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/spreadjs/gc.spread.sheets.all.18.2.4.min.js


File diff suppressed because it is too large
+ 10 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/spreadjs/gc.spread.sheets.angularjs.18.2.4.min.js


File diff suppressed because it is too large
+ 12 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/spreadjs/gc.spread.sheets.resources.zh.18.2.4.min.js


+ 20 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/waxApp.js

@@ -0,0 +1,20 @@
+"use strict";
+
+// define app (depends on "wijmo", and also on the modules that contain our directives)
+// IMPORTANT: if you forget to include a directive, there will be no error message!!!
+angular.module("waxApp", ["gcspreadsheets", "ngRoute"]).
+  config(["$routeProvider", function ($routeProvider) {
+      $routeProvider.
+
+      // show wijmo directives
+      when("/spreadjs/databinding", { templateUrl: "partials/spreadjs/databinding.html" }).
+      when("/spreadjs/layout", { templateUrl: "partials/spreadjs/layout.html" }).
+      when("/spreadjs/style", { templateUrl: "partials/spreadjs/style.html" }).
+      when("/spreadjs/celltype", { templateUrl: "partials/spreadjs/celltype.html" }).
+      when("/spreadjs/datavalidation", { templateUrl: "partials/spreadjs/datavalidation.html" }).
+
+      // home
+      when("/", { templateUrl: "partials/home.htm" }).
+      otherwise({ redirectTo: "/" });
+  } ]);
+

+ 86 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/scripts/waxCtrl.js

@@ -0,0 +1,86 @@
+"use strict";
+
+// the waxCtrl controller is used by all views in this app.
+function waxCtrl($scope, $routeParams) {
+
+    $scope.employees = [
+                { name: "Nancy Freehafer", phone: "(123)555-5100", country: "US", email: "mailto:nancy@northwindtraders.com", onJob: true },
+                { name: "Andrew Cencini", phone: "(123)555-5101", country: "UK", email: "mailto:andrew@northwindtraders.com", onJob: false },
+                { name: "Jan Kotas", phone: "(123)555-5102", country: "Germany", email: "mailto:jan@northwindtraders.com", onJob: true },
+                { name: "Mariya Sergienko", phone: "(123)555-5103", country: "US", email: "mailto:mariya@northwindtraders.com", onJob: true },
+                { name: "Steven Thorpe", phone: "(123)555-5104", country: "Mexico", email: "mailto:steven@northwindtraders.com", onJob: false },
+                { name: "Michael Neipper", phone: "(123)555-5105", country: "US", email: "mailto:michael@northwindtraders.com", onJob: true },
+                { name: "Robert Zare", phone: "(123)555-5106", country: "UK", email: "mailto:robert@northwindtraders.com", onJob: true },
+                { name: "Laura Giussani", phone: "(123)555-5107", country: "US", email: "mailto:laura@northwindtraders.com", onJob: false },
+                { name: "Anne Hellung-Larsen", phone: "(123)555-5108", country: "US", email: "mailto:anne@northwindtraders.com", onJob: true }
+    ];
+
+    // list of major US airports and their traffic in 2005-2011
+    // source http://en.wikipedia.org/wiki/List_of_the_busiest_airports_in_the_United_States
+    $scope.airports = [
+        { "name": "Hartsfield Jackson Atlanta International Airport", "code": "ATL", "city": "Atlanta", "state": "GA", "lat": 33.64, "lon": -84.444, "pop2011": 432427, "vol2011": 44414121, "vol2010": 43130585, "vol2009": 42280868, "vol2008": 43236665, "vol2007": 43236665, "vol2006": 41352038, "vol2005": 42402653 },
+        { "name": "O'Hare International Airport", "code": "ORD", "city": "Chicago", "state": "IL", "lat": 41.9794, "lon": -87.9044, "pop2011": 2707120, "vol2011": 31892301, "vol2010": 32171831, "vol2009": 31135732, "vol2008": 33683991, "vol2007": 36521585, "vol2006": 36825097, "vol2005": 36720005 },
+        { "name": "Los Angeles International Airport", "code": "LAX", "city": "Los Angeles", "state": "CA", "lat": 33.9425, "lon": -118.4081, "pop2011": 3819702, "vol2011": 30528737, "vol2010": 28857755, "vol2009": 27439897, "vol2008": 28861477, "vol2007": 30113985, "vol2006": 29357327, "vol2005": 29372272 },
+        { "name": "Dallas/Fort Worth International Airport", "code": "DFW", "city": "Dallas/Fort Worth", "state": "TX", "lat": 32.8974, "lon": -97.0407, "pop2011": 1223229, "vol2011": 27518358, "vol2010": 27100656, "vol2009": 26663984, "vol2008": 27219985, "vol2007": 28482417, "vol2006": 28627749, "vol2005": 28079147 },
+        { "name": "Denver International Airport", "code": "DEN", "city": "Denver", "state": "CO", "lat": 39.8631, "lon": -104.6736, "pop2011": 619968, "vol2011": 25667499, "vol2010": 25241962, "vol2009": 24013669, "vol2008": 24287939, "vol2007": 20796173, "vol2006": 20591909, "vol2005": 20315544 },
+        { "name": "John F. Kennedy International Airport", "code": "JFK", "city": "New York", "state": "NY", "lat": 40.6438, "lon": -73.782, "pop2011": 8244910, "vol2011": 23664830, "vol2010": 22934047, "vol2009": 22710272, "vol2008": 23620948, "vol2007": 23401351, "vol2006": 21071501, "vol2005": 20260359 },
+        { "name": "San Francisco International Airport", "code": "SFO", "city": "San Francisco", "state": "CA", "lat": 37.6152, "lon": -122.39, "pop2011": 812826, "vol2011": 20038679, "vol2010": 19359003, "vol2009": 18467908, "vol2008": 18135827, "vol2007": 17280328, "vol2006": 16236592, "vol2005": 16070133 },
+        { "name": "McCarran International Airport", "code": "LAS", "city": "Las Vegas", "state": "NV", "lat": 36.085, "lon": -115.1511, "pop2011": 589317, "vol2011": 19854759, "vol2010": 18996738, "vol2009": 19445952, "vol2008": 21024443, "vol2007": 22537950, "vol2006": 22028521, "vol2005": 21402676 },
+        { "name": "Phoenix Sky Harbor International Airport", "code": "PHX", "city": "Phoenix", "state": "AZ", "lat": 33.4365, "lon": -112.0073, "pop2011": 1469471, "vol2011": 19750306, "vol2010": 18907171, "vol2009": 18559647, "vol2008": 19450576, "vol2007": 20767144, "vol2006": 20479291, "vol2005": 19032196 },
+        { "name": "George Bush Intercontinental Airport", "code": "IAH", "city": "Houston", "state": "TX", "lat": 29.9867, "lon": -95.3381, "pop2011": 2145146, "vol2011": 19306660, "vol2010": 19528631, "vol2009": 19290239, "vol2008": 20030898, "vol2007": 24117623, "vol2006": 22822111, "vol2005": 20799886 },
+        { "name": "Charlotte/Douglas International Airport", "code": "CLT", "city": "Charlotte", "state": "NC", "lat": 35.221, "lon": -80.9442, "pop2011": 751087, "vol2011": 19022535, "vol2010": 18629181, "vol2009": 18165476, "vol2008": 19291428, "vol2007": 16884780, "vol2006": 14949568, "vol2005": 14109608 },
+        { "name": "Miami International Airport", "code": "MIA", "city": "Miami", "state": "FL", "lat": 25.7965, "lon": -80.2756, "pop2011": 408750, "vol2011": 18342158, "vol2010": 17017654, "vol2009": 16187768, "vol2008": 16369998, "vol2007": 16377488, "vol2006": 15664791, "vol2005": 15092763 },
+        { "name": "Orlando International Airport", "code": "MCO", "city": "Orlando", "state": "FL", "lat": 28.4316, "lon": -81.3083, "pop2011": 243195, "vol2011": 17250415, "vol2010": 17017491, "vol2009": 16371016, "vol2008": 17288480, "vol2007": 17614679, "vol2006": 16807856, "vol2005": 16592133 },
+        { "name": "Newark Liberty International Airport", "code": "EWR", "city": "Newark", "state": "NJ", "lat": 40.6899, "lon": -74.1782, "pop2011": 277540, "vol2011": 16814092, "vol2010": 16571754, "vol2009": 16659441, "vol2008": 17599578, "vol2007": 18163652, "vol2006": 17804107, "vol2005": 16444959 },
+        { "name": "Seattle-Tacoma International Airport", "code": "SEA", "city": "Seattle", "state": "WA", "lat": 47.4444, "lon": -122.3005, "pop2011": 620778, "vol2011": 15971676, "vol2010": 15406243, "vol2009": 15273092, "vol2008": 15839504, "vol2007": 15419116, "vol2006": 14703928, "vol2005": 14359530 },
+        { "name": "Minneapolis-St. Paul International Airport/Wold-Chamberlain Airport", "code": "MSP", "city": "Minneapolis/St. Paul", "state": "MN", "lat": 44.8812, "lon": -93.2031, "pop2011": 387753, "vol2011": 15895653, "vol2010": 15512487, "vol2009": 15551206, "vol2008": 16369324, "vol2007": 16962563, "vol2006": 17192410, "vol2005": 17971771 },
+        { "name": "Detroit Metropolitan Wayne County Airport", "code": "DTW", "city": "Detroit", "state": "MI", "lat": 42.2083, "lon": -83.3572, "pop2011": 706585, "vol2011": 15716865, "vol2010": 15643890, "vol2009": 15211402, "vol2008": 16998174, "vol2007": 17495135, "vol2006": 17483468, "vol2005": 17580363 },
+        { "name": "Philadelphia International Airport", "code": "PHL", "city": "Philadelphia", "state": "PA", "lat": 39.875, "lon": -75.2491, "pop2011": 1536471, "vol2011": 14883180, "vol2010": 14951254, "vol2009": 15002961, "vol2008": 15586852, "vol2007": 15656653, "vol2006": 15390848, "vol2005": 15376569 },
+        { "name": "Logan International Airport", "code": "BOS", "city": "Boston", "state": "MA", "lat": 42.3695, "lon": -71.0201, "pop2011": 625087, "vol2011": 14171476, "vol2010": 13561814, "vol2009": 12566797, "vol2008": 12820489, "vol2007": 13783297, "vol2006": 13544552, "vol2005": 13214923 },
+        { "name": "LaGuardia Airport", "code": "LGA", "city": "New York", "state": "NY", "lat": 40.7739, "lon": -73.8718, "pop2011": 8244910, "vol2011": 11989227, "vol2010": 12001501, "vol2009": 11084300, "vol2008": 11567586, "vol2007": 12529890, "vol2006": 12925697, "vol2005": 13014314 },
+        { "name": "Fort Lauderdale/Hollywood International Airport", "code": "FLL", "city": "Fort Lauderdale", "state": "FL", "lat": 26.0727, "lon": -80.14, "pop2011": 168528, "vol2011": 11332466, "vol2010": 10829810, "vol2009": 10258118, "vol2008": 11020091, "vol2007": 11079250, "vol2006": 10204579, "vol2005": 10729468 },
+        { "name": "Baltimore-Washington International Thurgood Marshall Airport", "code": "BWI", "city": "Baltimore/Washington, DC", "state": "MD", "lat": 39.188537, "lon": -76.678077, "pop2011": 619493, "vol2011": 11067317, "vol2010": 10848633, "vol2009": 10338950, "vol2008": 10215225, "vol2007": 10487789, "vol2006": 10297607, "vol2005": 9829432 },
+        { "name": "Washington Dulles International Airport", "code": "IAD", "city": "Washington, DC", "state": "VA", "lat": 38.9534, "lon": -77.4477, "pop2011": 617996, "vol2011": 11043829, "vol2010": 11276481, "vol2009": 11132098, "vol2008": 11348775, "vol2007": 11789441, "vol2006": 11045217, "vol2005": 13032502 },
+        { "name": "Salt Lake City International Airport", "code": "SLC", "city": "Salt Lake City", "state": "UT", "lat": 40.7868, "lon": -111.9819, "pop2011": 189899, "vol2011": 9701756, "vol2010": 9910493, "vol2009": 9903821, "vol2008": 9993198, "vol2007": 10560906, "vol2006": 10289129, "vol2005": 10601918 },
+        { "name": "Midway International Airport", "code": "MDW", "city": "Chicago", "state": "IL", "lat": 41.7883, "lon": -87.7418, "pop2011": 2707120, "vol2011": 9134576, "vol2010": 8518957, "vol2009": 8253620, "vol2008": 8021383, "vol2007": 9132836, "vol2006": 8915292, "vol2005": 8383698 },
+        { "name": "Ronald Reagan Washington National Airport", "code": "DCA", "city": "Washington, DC", "state": "VA", "lat": 38.8519, "lon": -77.0375, "pop2011": 617996, "vol2011": 9053004, "vol2010": 8736804, "vol2009": 8490288, "vol2008": 8704466, "vol2007": 9038174, "vol2006": 8973410, "vol2005": 8623907 },
+        { "name": "Honolulu International Airport", "code": "HNL", "city": "Honolulu", "state": "HI", "lat": 21.3329, "lon": -157.9214, "pop2011": 340936, "vol2011": 8643494, "vol2010": 8740077, "vol2009": 8739389, "vol2008": 9013440, "vol2007": 10393929, "vol2006": 9855838, "vol2005": 9784404 },
+        { "name": "San Diego International Airport", "code": "SAN", "city": "San Diego", "state": "CA", "lat": 32.7323, "lon": -117.1974, "pop2011": 1326179, "vol2011": 8465683, "vol2010": 8430509, "vol2009": 8453854, "vol2008": 9007617, "vol2007": 9138116, "vol2006": 8724442, "vol2005": 8628648 },
+        { "name": "Tampa International Airport", "code": "TPA", "city": "Tampa", "state": "FL", "lat": 27.9769, "lon": -82.5334, "pop2011": 346037, "vol2011": 8174194, "vol2010": 8137222, "vol2009": 8263294, "vol2008": 8871917, "vol2007": 9306036, "vol2006": 9187865, "vol2005": 9297643 },
+        { "name": "Portland International Airport", "code": "PDX", "city": "Portland", "state": "OR", "lat": 45.5892, "lon": -122.5939, "pop2011": 593820, "vol2011": 6808486 },
+        { "name": "Lambert-St. Louis International Airport", "code": "STL", "city": "St. Louis", "state": "MO", "lat": 38.7422, "lon": -90.3658, "pop2011": 318069, "vol2011": 6159090 },
+        { "name": "Kansas City International Airport", "code": "MCI", "city": "Kansas City", "state": "MO", "lat": 39.2977, "lon": -94.7163, "pop2011": 463202, "vol2011": 5011000 },
+        { "name": "William P. Hobby Airport", "code": "HOU", "city": "Houston", "state": "TX", "lat": 29.6541, "lon": -95.2766, "pop2011": 2145146, "vol2011": 4753554 },
+        { "name": "Nashville International Airport", "code": "BNA", "city": "Nashville", "state": "TN", "lat": 36.1302, "lon": -86.6672, "pop2011": 609644, "vol2011": 4673047 },
+        { "name": "General Mitchell International Airport", "code": "MKE", "city": "Milwaukee", "state": "WI", "lat": 42.9476, "lon": -87.9029, "pop2011": 597867, "vol2011": 4671976 },
+        { "name": "Metropolitan Oakland International Airport", "code": "OAK", "city": "Oakland", "state": "CA", "lat": 37.7107, "lon": -122.2144, "pop2011": 395817, "vol2011": 4550526 },
+        { "name": "Raleigh-Durham International Airport", "code": "RDU", "city": "Raleigh/Durham", "state": "NC", "lat": 35.8767, "lon": -78.7931, "pop2011": 416468, "vol2011": 4462508 },
+        { "name": "Austin-Bergstrom International Airport", "code": "AUS", "city": "Austin", "state": "TX", "lat": 30.2026, "lon": -97.6681, "pop2011": 820611, "vol2011": 4436661 },
+        { "name": "Cleveland-Hopkins International Airport", "code": "CLE", "city": "Cleveland", "state": "OH", "lat": 41.4117, "lon": -81.8347, "pop2011": 393806, "vol2011": 4401033 },
+        { "name": "Sacramento International Airport", "code": "SMF", "city": "Sacramento", "state": "CA", "lat": 38.6927, "lon": -121.5879, "pop2011": 472178, "vol2011": 4370895 },
+        { "name": "Memphis International Airport", "code": "MEM", "city": "Memphis", "state": "TN", "lat": 35.0447, "lon": -89.9817, "pop2011": 652050, "vol2011": 4344213 },
+        { "name": "Louis Armstrong New Orleans International Airport", "code": "MSY", "city": "New Orleans", "state": "LA", "lat": 29.9842, "lon": -90.256, "pop2011": 360740, "vol2011": 4255411 },
+        { "name": "John Wayne Airport-Orange County", "code": "SNA", "city": "Orange County", "state": "CA", "lat": 33.6805, "lon": -117.8602, "pop2011": 138409, "vol2011": 4247802 },
+        { "name": "San Jose International Airport", "code": "SJC", "city": "San Jose", "state": "CA", "lat": 37.3667, "lon": -121.9259, "pop2011": 967487, "vol2011": 4108006 },
+        { "name": "Pittsburgh International Airport", "code": "PIT", "city": "Pittsburgh", "state": "PA", "lat": 40.496, "lon": -80.2567, "pop2011": 307484, "vol2011": 4070614 },
+        { "name": "San Antonio International Airport", "code": "SAT", "city": "San Antonio", "state": "TX", "lat": 29.5249, "lon": -98.4733, "pop2011": 1359758, "vol2011": 3984024 },
+        { "name": "Luis Muñoz Marín International Airport", "code": "SJU", "city": "San Juan", "state": "PR", "lat": 18.4365, "lon": -66.0051, "pop2011": 389714, "vol2011": 3983130 },
+        { "name": "Dallas Love Field", "code": "DAL", "city": "Dallas", "state": "TX", "lat": 32.841, "lon": -96.8461, "pop2011": 1223229, "vol2011": 3852886 },
+        { "name": "Southwest Florida International Airport", "code": "RSW", "city": "Fort Myers", "state": "FL", "lat": 26.5429, "lon": -81.7546, "pop2011": 63512, "vol2011": 3748366 },
+        { "name": "Indianapolis International Airport", "code": "IND", "city": "Indianapolis", "state": "IN", "lat": 39.715, "lon": -86.2962, "pop2011": 827609, "vol2011": 3670396 },
+        { "name": "Cincinnati/Northern Kentucky International Airport", "code": "CVG", "city": "Greater Cincinnati", "state": "KY", "lat": 39.0552, "lon": -84.6613, "pop2011": 296223, "vol2011": 3422466 },
+        { "name": "Port Columbus International Airport", "code": "CMH", "city": "Columbus", "state": "OH", "lat": 39.9939, "lon": -82.891, "pop2011": 797434, "vol2011": 3134379 },
+        { "name": "Palm Beach International Airport", "code": "PBI", "city": "West Palm Beach", "state": "FL", "lat": 26.6886, "lon": -80.0907, "pop2011": 101043, "vol2011": 2877158 },
+        { "name": "Bradley International Airport", "code": "BDL", "city": "Windsor Locks", "state": "CT", "lat": 41.9287, "lon": -72.6839, "pop2011": 12498, "vol2011": 2772315 },
+        { "name": "Albuquerque International Sunport Airport", "code": "ABQ", "city": "Albuquerque", "state": "NM", "lat": 35.0487, "lon": -106.6167, "pop2011": 552804, "vol2011": 2768435 },
+        { "name": "Jacksonville International Airport", "code": "JAX", "city": "Jacksonville", "state": "FL", "lat": 30.4935, "lon": -81.6802, "pop2011": 827908, "vol2011": 2700514 },
+        { "name": "Kahului Airport", "code": "OGG", "city": "Kahului", "state": "HI", "lat": 20.8928, "lon": -156.4388, "pop2011": 26337, "vol2011": 2683933 },
+        { "name": "Buffalo Niagara International Airport", "code": "BUF", "city": "Buffalo", "state": "NY", "lat": 42.9339, "lon": -78.7308, "pop2011": 261025, "vol2011": 2582597 },
+        { "name": "Ted Stevens Anchorage International Airport", "code": "ANC", "city": "Anchorage", "state": "AK", "lat": 61.1739, "lon": -149.981, "pop2011": 295570, "vol2011": 2354987 },
+        { "name": "Ontario International Airport", "code": "ONT", "city": "Ontario", "state": "CA", "lat": 34.0609, "lon": -117.5983, "pop2011": 166390, "vol2011": 2271458 },
+        { "name": "Bob Hope Airport", "code": "BUR", "city": "Burbank", "state": "CA", "lat": 34.1958, "lon": -118.3492, "pop2011": 104092, "vol2011": 2144915 },
+        { "name": "Eppley Airfield", "code": "OMA", "city": "Omaha", "state": "NE", "lat": 41.3025, "lon": -95.8936, "pop2011": 415068, "vol2011": 2047055 },
+        { "name": "Theodore Francis Green State Airport", "code": "PVD", "city": "Warwick", "state": "RI", "lat": 41.7251, "lon": -71.45, "pop2011": 82361, "vol2011": 1920699 },
+        { "name": "Reno/Tahoe International Airport", "code": "RNO", "city": "Reno", "state": "NV", "lat": 39.5058, "lon": -119.7754, "pop2011": 227511, "vol2011": 1821051 }
+    ];
+}

+ 95 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/app.css

@@ -0,0 +1,95 @@
+body {
+    font-family: 'Gotham SSm A', 'Gotham SSm B';
+    font-size: 14px;
+    color: #333333;
+    background-color: #ffffff;
+}
+
+h1 {
+    font-size: 36px;
+}
+
+h1, h2, h3, h4, h5, h6 {
+    margin: 10px 0;
+    font-family: 'Forza SSm A', 'Forza SSm B';
+    font-weight: bold;
+    line-height: 20px;
+    color: inherit;
+    text-rendering: optimizelegibility;
+}
+
+img {
+    max-width: 100%;
+    width: auto;
+    height: auto;
+    vertical-align: middle;
+    border: 0;
+    -ms-interpolation-mode: bicubic;
+}
+
+td input[type=checkbox] {
+    margin: 5px;
+}
+
+td input[type=text] {
+    margin: 5px;
+    width: 100px;
+}
+
+label {
+    font-weight: normal;
+}
+
+.logo {
+    width: 64px;
+    height: 64px;
+}
+
+.mainContainer {
+    width: 80%;
+    margin-left: 10%;
+}
+
+.content {
+    min-height: 20px;
+    padding: 19px;
+    margin-bottom: 20px;
+    background-color: #f5f5f5;
+    border: 1px solid #e3e3e3;
+}
+
+.contentContainer {
+    width: 100%;
+}
+
+.contentContainer .leftContainer {
+    width: 25%;
+}
+
+.contentContainer .rightContainer {
+    width: 73%;
+}
+
+.contentContainer [class*="Container"] {
+    -webkit-box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    box-sizing: border-box;
+    float: left;
+    margin-left: 2%;
+}
+
+.contentContainer [class*="Container"]:first-child {
+    margin-left: 0;
+}
+
+#ssdb {
+    width:100%;
+    height:500px;
+    border:1px solid gray;
+}
+
+#ss {
+    width:100%;
+    height:300px;
+    border:1px solid gray;
+}

File diff suppressed because it is too large
+ 5 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/bootstrap/3.2.0/bootstrap-theme.min.css


File diff suppressed because it is too large
+ 5 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/bootstrap/3.2.0/bootstrap.min.css


File diff suppressed because it is too large
+ 19 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/fonts.css


File diff suppressed because it is too large
+ 7739 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.18.2.4.css


File diff suppressed because it is too large
+ 7791 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2013darkGray.18.2.4.css


File diff suppressed because it is too large
+ 7796 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2013lightGray.18.2.4.css


File diff suppressed because it is too large
+ 7782 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2013white.18.2.4.css


File diff suppressed because it is too large
+ 7797 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2016black.18.2.4.css


File diff suppressed because it is too large
+ 7787 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2016colorful.18.2.4.css


File diff suppressed because it is too large
+ 7783 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularJSSample/styles/spreadjs/gc.spread.sheets.excel2016darkGray.18.2.4.css


+ 85 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/angular.json

@@ -0,0 +1,85 @@
+{
+  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+  "version": 1,
+  "newProjectRoot": "projects",
+  "projects": {
+    "AngularSample": {
+      "projectType": "application",
+      "schematics": {},
+      "root": "",
+      "sourceRoot": "src",
+      "prefix": "app",
+      "architect": {
+        "build": {
+          "builder": "@angular/build:application",
+          "options": {
+            "outputPath": {
+              "base": "dist/AngularSample"
+            },
+            "index": "src/index.html",
+            "polyfills": [
+              "src/polyfills.ts"
+            ],
+            "tsConfig": "tsconfig.app.json",
+            "assets": [
+              "src/favicon.ico",
+              "src/assets"
+            ],
+            "styles": [
+              "src/styles.css",
+              "node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css"
+            ],
+            "scripts": [],
+            "extractLicenses": false,
+            "sourceMap": true,
+            "optimization": false,
+            "namedChunks": true,
+            "browser": "src/main.ts"
+          },
+          "configurations": {
+            "production": {
+              "optimization": true,
+              "outputHashing": "all",
+              "sourceMap": false,
+              "namedChunks": false,
+              "extractLicenses": true,
+              "budgets": [
+                {
+                  "type": "initial",
+                  "maximumWarning": "2mb",
+                  "maximumError": "5mb"
+                },
+                {
+                  "type": "anyComponentStyle",
+                  "maximumWarning": "6kb",
+                  "maximumError": "10kb"
+                }
+              ]
+            }
+          },
+          "defaultConfiguration": ""
+        },
+        "serve": {
+          "builder": "@angular/build:dev-server",
+          "options": {
+            "buildTarget": "AngularSample:build"
+          },
+          "configurations": {
+            "production": {
+              "buildTarget": "AngularSample:build:production"
+            }
+          }
+        },
+        "extract-i18n": {
+          "builder": "@angular/build:extract-i18n",
+          "options": {
+            "buildTarget": "AngularSample:build"
+          }
+        }
+      }
+    }
+  },
+  "cli": {
+    "analytics": "0a954329-60b4-488c-a9d8-f8a75226e243"
+  }
+}

+ 39 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/package.json

@@ -0,0 +1,39 @@
+{
+  "name": "spread-sheets-angular-sample",
+  "version": "1.0.0",
+  "description": "Angular support sample for SpreadJS",
+  "scripts": {
+    "ng": "ng",
+    "start": "ng serve",
+    "build": "ng build"
+  },
+  "keywords": [],
+  "author": "GrapeCity",
+  "license": "MIT",
+  "dependencies": {
+    "@angular/animations": "^20.2.3",
+    "@angular/common": "^20.2.3",
+    "@angular/compiler": "^20.2.3",
+    "@angular/core": "^20.2.3",
+    "@angular/forms": "^20.2.3",
+    "@angular/platform-browser": "^20.2.3",
+    "@angular/platform-browser-dynamic": "^20.2.3",
+    "@angular/router": "^20.2.3",
+    "@grapecity-software/spread-sheets": "^18.2.4",
+    "@grapecity-software/spread-sheets-angular": "^18.2.4",
+    "@grapecity-software/spread-sheets-resources-zh": "^18.2.4",
+    "rxjs": "~6.6.0",
+    "tslib": "^2.0.0",
+    "zone.js": "~0.15.0"
+  },
+  "devDependencies": {
+    "@angular/build": "^20.2.1",
+    "@angular/cli": "^20.2.1",
+    "@angular/compiler-cli": "^20.2.3",
+    "@types/node": "^12.11.1",
+    "codelyzer": "^6.0.0",
+    "protractor": "~7.0.0",
+    "ts-node": "~8.3.0",
+    "typescript": "~5.9.2"
+  }
+}

File diff suppressed because it is too large
+ 1109 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app-data.service.ts


+ 105 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.component.css

@@ -0,0 +1,105 @@
+.app-container {
+    margin: 0 10%;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    box-shadow: 0 0 20px #e3e3e3;
+}
+
+.app-header {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+    height: 60px;
+    background-color: black;
+    color: white;
+    text-align: center;
+}
+
+.header-text {
+    position: absolute;
+    left: 0;
+    right: 0;
+    font-size: 30px;
+    font-family: 'Forza SSm A', 'Forza SSm B';
+    font-weight: bold;
+    height: 30px;
+    margin-top: -15px;
+    top: 50%;
+    vertical-align: middle;
+}
+
+.app-footer {
+    position: absolute;
+    text-align: center;
+    background-color: black;
+    color: white;
+    height: 60px;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+
+.footer-text {
+    position: absolute;
+    left: 0;
+    right: 0;
+    top: 50%;
+    margin-top: -8px;
+    height: 16px;
+    font-size: 16px;
+    font-family: 'Forza SSm A', 'Forza SSm B';
+}
+
+.body-container {
+    position: absolute;
+    top: 80px;
+    bottom: 60px;
+    left: 0;
+    right: 0;
+}
+
+.navigationBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 20px;
+    padding: 0 10px;
+    width: 200px;
+    border-right: 2px solid #e3e3e3;
+}
+
+.navigationBar li {
+    margin-top: 0;
+    margin-bottom: 10px;
+}
+
+.componentContainer {
+    position: absolute;
+    padding: 10px;
+    left: 242px;
+    top: 0;
+    bottom: 20px;
+    right: 0;
+}
+
+nav a {
+    text-decoration: none;
+}
+
+nav a:visited, a:link {
+    color: #607D8B;
+}
+
+nav a:hover {
+    color: #039be5;
+    background-color: #CFD8DC;
+}
+
+nav a.active {
+    color: #039be5;
+}

+ 27 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.component.html

@@ -0,0 +1,27 @@
+<div class="app-container">
+    <div class="app-header content">
+      <img class="logo" src="assets/img/logo.png" alt="logo"><span class="header-text">{{ appHeader }}</span>
+    </div>
+    <div class="body-container">
+        <div class="navigationBar content">
+            <h2>SpreadJS</h2>
+            <nav>
+                <ul>
+                    <li><a routerLink="/quick-start" routerLinkActive="active">快速入门指南</a></li>
+                    <li><a routerLink="/gc-spread-sheets" routerLinkActive="active">GC-Spread-Sheets</a></li>
+                    <li><a routerLink="/gc-worksheet" routerLinkActive="active">GC-Worksheet</a></li>
+                    <li><a routerLink="/gc-column" routerLinkActive="active">GC-Column</a></li>
+                    <li><a routerLink="/data-binding" routerLinkActive="active">数据绑定</a></li>
+                    <li><a routerLink="/style" routerLinkActive="active">样式</a></li>
+                    <li><a routerLink="/outline" routerLinkActive="active">分组</a></li>
+                </ul>
+            </nav>
+        </div>
+        <div class="componentContainer content">
+            <router-outlet></router-outlet>
+        </div>
+    </div>
+    <div class="app-footer content">
+        <span class="footer-text">{{appFooter}}</span>
+    </div>
+</div>

+ 19 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.component.ts

@@ -0,0 +1,19 @@
+import {Component} from '@angular/core';
+import '@grapecity-software/spread-sheets-resources-zh';
+import * as GC from '@grapecity-software/spread-sheets';
+import { RouterLink, RouterOutlet } from '@angular/router';
+
+@Component({
+    selector: 'my-app',
+    standalone: true,
+    imports: [RouterLink, RouterOutlet],
+    templateUrl: './app.component.html',
+    styleUrls: ['./app.component.css']
+})
+export class AppComponent {
+    appHeader = 'SpreadJS Angular 示例';
+    appFooter = 'Copyright© GrapeCity, inc. All Rights Reserved.';
+    constructor () {
+        GC.Spread.Common.CultureManager.culture("zh-cn");
+    }
+}

+ 11 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/app.config.ts

@@ -0,0 +1,11 @@
+import { ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
+import { provideRouter } from '@angular/router';
+
+import { routes } from './route/app-routing.module';
+
+export const appConfig: ApplicationConfig = {
+  providers: [
+    provideZonelessChangeDetection(),
+    provideRouter(routes)
+  ]
+};

+ 33 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/column/app-column.component.html

@@ -0,0 +1,33 @@
+<h3>GC-Column</h3>
+<div>
+    <p>以下示例展示如何绑定列上的属性。</p>
+</div>
+
+<div>
+    <gc-spread-sheets [hostStyle]="hostStyle" hostClass="spreadContainer">
+        <gc-worksheet [dataSource]="data" [autoGenerateColumns]="autoGenerateColumns">
+            <gc-column [width]="width" [formatter]="formatter" [visible]="visible" [resizable]="resizable"></gc-column>
+        </gc-worksheet>
+    </gc-spread-sheets>
+</div>
+
+<div class="settingContainer">
+    <table>
+        <tr>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="visible" />可见</label>
+            </td>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="resizable" />可改变列宽</label>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <label><input type="text" [(ngModel)]="width" />列宽</label>
+            </td>
+            <td>
+                <label><input type="text" [(ngModel)]="formatter" />数据格式</label>
+            </td>
+        </tr>
+    </table>
+</div>

+ 28 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/column/app-column.component.ts

@@ -0,0 +1,28 @@
+import {Component} from "@angular/core";
+import {SpreadSheetsModule} from "@grapecity-software/spread-sheets-angular";
+import {FormsModule} from "@angular/forms";
+@Component({
+    standalone: true,
+    imports: [FormsModule, SpreadSheetsModule],
+    templateUrl: './app-column.component.html'
+})
+export class ColumnComponent {
+    hostStyle = {
+        top: '90px',
+        bottom: '74px'
+    };
+    visible = true;
+    resizable = true;
+    width = 300;
+    formatter = '$ #.00';
+    data: any;
+    autoGenerateColumns = false;
+
+    constructor() {
+        let dataTable = [];
+        for (let i = 0; i < 42; i++) {
+            dataTable.push({price: i + 0.56})
+        }
+        this.data = dataTable;
+    }
+}

+ 19 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/dataBind/app-dataBind.component.html

@@ -0,0 +1,19 @@
+<h3>数据绑定</h3>
+<div>
+    <p>以下示例展示如何绑定数据。</p>
+</div>
+
+<div>
+    <gc-spread-sheets [hostStyle]="hostStyle" hostClass="spreadContainer">
+        <gc-worksheet [dataSource]="data" name="All Data">
+        </gc-worksheet>
+        <gc-worksheet [dataSource]="data" name="Part Data" [autoGenerateColumns]="autoGenerateColumns">
+            <gc-column dataField="name" headerText="Name"></gc-column>
+            <gc-column dataField="city" headerText="City"></gc-column>
+            <gc-column dataField="state" headerText="State"></gc-column>
+            <gc-column dataField="lat" headerText="Lat"></gc-column>
+            <gc-column dataField="lon" headerText="Lon"></gc-column>
+            <gc-column dataField="vol2011" headerText="Vol2011"></gc-column>
+        </gc-worksheet>
+    </gc-spread-sheets>
+</div>

+ 22 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/dataBind/app-dataBind.component.ts

@@ -0,0 +1,22 @@
+import {Component} from "@angular/core";
+import {DataService} from "../app-data.service";
+import {SpreadSheetsModule} from "@grapecity-software/spread-sheets-angular";
+import {FormsModule} from "@angular/forms";
+@Component({
+    standalone: true,
+    imports: [FormsModule, SpreadSheetsModule],
+    providers: [DataService],
+    templateUrl: './app-dataBind.component.html'
+})
+export class DataBindComponent {
+    hostStyle = {
+        top: '90px',
+        bottom: '0px'
+    };
+    data: any;
+    autoGenerateColumns = false;
+
+    constructor(private dataService: DataService) {
+        this.data = dataService.getAirpotsData();
+    }
+}

+ 29 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/outline/app-outline.component.html

@@ -0,0 +1,29 @@
+<h3>分组</h3>
+
+<div>
+    <p>以下示例展示如何使用分组。</p>
+</div>
+
+<div>
+    <gc-spread-sheets [hostStyle]="hostStyle" hostClass="spreadContainer">
+        <gc-worksheet [showRowOutline]="showRowOutline" [showColumnOutline]="showColumnOutline"
+                      [rowOutlineInfo]="rowOutlineInfo" [columnOutlineInfo]="columnOutlineInfo" [dataSource]="data" [autoGenerateColumns]="autoGenerateColumns">
+            <gc-column width=150 dataField="Name"></gc-column>
+            <gc-column width=150 dataField="CountryRegionCode"></gc-column>
+            <gc-column width=100 dataField="City"></gc-column>
+            <gc-column width=200 dataField="AddressLine"></gc-column>
+            <gc-column width=100 dataField="PostalCode"></gc-column>
+        </gc-worksheet>
+    </gc-spread-sheets>
+</div>
+
+<div class="settingContainer">
+    <tr>
+        <td>
+            <label><input type="checkbox" [(ngModel)]="showRowOutline" />显示行分组</label>
+        </td>
+        <td>
+            <label><input type="checkbox" [(ngModel)]="showColumnOutline" />显示列分组</label>
+        </td>
+    </tr>
+</div>

+ 26 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/outline/app-outline.component.ts

@@ -0,0 +1,26 @@
+import {Component} from "@angular/core"
+import {DataService} from "../app-data.service";
+import {SpreadSheetsModule} from "@grapecity-software/spread-sheets-angular";
+import {FormsModule} from "@angular/forms";
+@Component({
+    standalone: true,
+    imports: [FormsModule, SpreadSheetsModule],
+    providers: [DataService],
+    templateUrl: './app-outline.component.html'
+})
+export class OutlineComponent {
+    hostStyle = {
+        top: '90px',
+        bottom: '35px'
+    };
+    showRowOutline = true;
+    showColumnOutline = true;
+    rowOutlineInfo = [{index: 1, count: 4}, {index: 6, count: 4}];
+    columnOutlineInfo = [{index: 0, count: 4}];
+    data: any;
+    autoGenerateColumns = false;
+
+    constructor(private dataservice: DataService) {
+        this.data = dataservice.getPersonAddressData();
+    }
+}

+ 22 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/quickStart/app-quickStart.component.html

@@ -0,0 +1,22 @@
+<h3>快速入门指南</h3>
+<div>
+    按照以下步骤快速将 SpreadJS 应用到 Angular 的应用程序中:
+    <div>
+        <p>1. 添加 SpreadJS 产品引用到 Angular 的应用程序中</p>
+        <p>2. 添加一个组件来提供数据和业务实现。</p>
+        <p>3. 绑定数据,并设置其他 SpreadJS 属性。</p>
+        <p>4. 添加一些 css 属性来定制外观。</p>
+    </div>
+</div>
+
+<div>
+    <gc-spread-sheets [backColor]="spreadBackColor" [hostStyle]="hostStyle" hostClass="spreadContainer">
+        <gc-worksheet [name]="sheetName" [dataSource]="data" [autoGenerateColumns]="autoGenerateColumns">
+            <gc-column width=150 dataField="Name"></gc-column>
+            <gc-column width=150 dataField="CountryRegionCode"></gc-column>
+            <gc-column width=100 dataField="City"></gc-column>
+            <gc-column width=200 dataField="AddressLine"></gc-column>
+            <gc-column width=100 dataField="PostalCode"></gc-column>
+        </gc-worksheet>
+    </gc-spread-sheets>
+</div>

+ 23 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/quickStart/app-quickStart.component.ts

@@ -0,0 +1,23 @@
+import {Component} from "@angular/core";
+import {DataService} from "../app-data.service";
+import { SpreadSheetsModule } from "@grapecity-software/spread-sheets-angular";
+@Component({
+    standalone: true,
+    imports: [SpreadSheetsModule],
+    providers: [DataService],
+    templateUrl: './app-quickStart.component.html'
+})
+export class QuickStartComponent {
+    spreadBackColor = 'aliceblue';
+    sheetName = 'Person Address';
+    hostStyle = {
+        top: '200px',
+        bottom: '10px'
+    };
+    data: any;
+    autoGenerateColumns = false;
+
+    constructor(private dataservice: DataService) {
+        this.data = dataservice.getPersonAddressData();
+    }
+}

+ 19 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/route/app-routing.module.ts

@@ -0,0 +1,19 @@
+import {Routes} from "@angular/router";
+import {QuickStartComponent} from "../quickStart/app-quickStart.component";
+import {SpreadSheetsComponent} from "../spreadSheets/app-spreadSheets.component";
+import {WorksheetComponent} from "../worksheet/app-worksheet.component";
+import {ColumnComponent} from "../column/app-column.component";
+import {DataBindComponent} from "../dataBind/app-dataBind.component";
+import {StyleComponent} from "../style/app-style.component";
+import {OutlineComponent} from "../outline/app-outline.component";
+
+export const routes: Routes = [
+    {path: '', redirectTo: '/quick-start', pathMatch: 'full'},
+    {path: 'quick-start', component: QuickStartComponent},
+    {path: 'gc-spread-sheets', component: SpreadSheetsComponent},
+    {path: 'gc-worksheet', component: WorksheetComponent},
+    {path: 'gc-column', component: ColumnComponent},
+    {path: 'data-binding', component: DataBindComponent},
+    {path: 'style', component: StyleComponent},
+    {path: 'outline', component: OutlineComponent}
+];

+ 78 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/spreadSheets/app-spreadSheets.component.html

@@ -0,0 +1,78 @@
+<h3>GC-Spread-Sheets</h3>
+<div>
+    <p>以下示例展示如何绑定 Workbook 上的属性。</p>
+</div>
+
+<div>
+    <gc-spread-sheets [hostStyle]="hostStyle" [newTabVisible]="newTabVisible"
+                      [tabStripVisible]="tabStripVisible"
+                      [tabStripRatio]="tabStripRatio"
+                      [tabNavigationVisible]="tabNavigationVisible"
+                      [scrollbarShowMax]="scrollbarShowMax"
+                      [scrollbarMaxAlign]="scrollbarMaxAlign"
+                      [showHorizontalScrollbar]="showHorizontalScrollbar"
+                      [showVerticalScrollbar]="showVerticalScrollbar" [backColor]="spreadBackColor"
+                      [grayAreaBackColor]="grayAreaBackColor" [allowUserZoom]="allowUserZoom"
+                      [allowUserResize]="allowUserResize" hostClass="spreadContainer">
+        <gc-worksheet [dataSource]="data" [autoGenerateColumns]="autoGenerateColumns">
+            <gc-column width=150 dataField="Name"></gc-column>
+            <gc-column width=150 dataField="CountryRegionCode"></gc-column>
+            <gc-column width=100 dataField="City"></gc-column>
+            <gc-column width=200 dataField="AddressLine"></gc-column>
+            <gc-column width=100 dataField="PostalCode"></gc-column>
+        </gc-worksheet>
+    </gc-spread-sheets>
+</div>
+
+<div class="settingContainer">
+    <table>
+        <tr>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="newTabVisible" />显示 new 标签页</label>
+            </td>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="tabStripVisible" />显示标签页</label>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="tabStripRatio"/>水平滚动条宽度比率</label>
+            </td>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="tabNavigationVisible"/>显示或隐藏表单标签导航项</label>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="scrollbarShowMax"/>基于表单全部的行列总数显示滚动条</label>
+            </td>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="scrollbarMaxAlign"/>滚动条对齐视图中表单的最后一行或一列</label>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="showHorizontalScrollbar" />显示横向滚动条</label>
+            </td>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="showVerticalScrollbar" />显示竖向滚动条</label>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="allowUserZoom">允许用户缩放</label>
+            </td>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="allowUserResize">允许用户改变行列宽高</label>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <input type="color" [(ngModel)]="spreadBackColor" /> 背景色
+            </td>
+            <td>
+                <input type="color" [(ngModel)]="grayAreaBackColor" /> 灰色区域背景色
+            </td>
+        </tr>
+    </table>
+</div>

+ 34 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/spreadSheets/app-spreadSheets.component.ts

@@ -0,0 +1,34 @@
+import {Component} from "@angular/core";
+import {DataService} from "../app-data.service";
+import {SpreadSheetsModule} from "@grapecity-software/spread-sheets-angular";
+import {FormsModule} from "@angular/forms";
+@Component({
+    standalone: true,
+    imports: [FormsModule, SpreadSheetsModule],
+    providers: [DataService],
+    templateUrl: './app-spreadSheets.component.html'
+})
+export class SpreadSheetsComponent {
+    hostStyle = {
+        top: '90px',
+        bottom: '180px'
+    };
+    newTabVisible = true;
+    tabStripVisible = true;
+    tabStripRatio = true;
+    tabNavigationVisible = true;
+    scrollbarShowMax = true;
+    scrollbarMaxAlign = true;
+    showHorizontalScrollbar = true;
+    showVerticalScrollbar = true;
+    allowUserZoom = true;
+    allowUserResize = true;
+    spreadBackColor = '#FFFFFF';
+    grayAreaBackColor = '#E4E4E4';
+    data: any;
+    autoGenerateColumns = false;
+
+    constructor(private dataservice: DataService) {
+        this.data = dataservice.getPersonAddressData();
+    }
+}

+ 17 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/style/app-style.component.html

@@ -0,0 +1,17 @@
+<h3>样式</h3>
+
+<div>
+    <p>以下示例展示如何使用样式。</p>
+</div>
+
+<div>
+    <gc-spread-sheets [hostStyle]="hostStyle" hostClass="spreadContainer">
+        <gc-worksheet [dataSource]="data" [autoGenerateColumns]="autoGenerateColumns">
+            <gc-column dataField="name" width=150 [style]="style"></gc-column>
+            <gc-column dataField="phone" width=150></gc-column>
+            <gc-column dataField="country" width=100 [cellType]="comboBoxCellType"></gc-column>
+            <gc-column dataField="email" width=240 [cellType]="hyperLinkCelleType"></gc-column>
+            <gc-column dataField="onJob" width=100 [cellType]="checkBoxCellType"></gc-column>
+        </gc-worksheet>
+    </gc-spread-sheets>
+</div>

+ 34 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/style/app-style.component.ts

@@ -0,0 +1,34 @@
+import {Component} from "@angular/core"
+import {DataService} from "../app-data.service"
+import * as GC from "@grapecity-software/spread-sheets"
+import {SpreadSheetsModule} from "@grapecity-software/spread-sheets-angular";
+import {FormsModule} from "@angular/forms";
+
+@Component({
+    standalone: true,
+    imports: [FormsModule, SpreadSheetsModule],
+    providers: [DataService],
+    templateUrl: './app-style.component.html'
+})
+export class StyleComponent {
+    hostStyle = {
+        top: '90px',
+        bottom: '0px'
+    };
+    checkBoxCellType = new GC.Spread.Sheets.CellTypes.CheckBox();
+    hyperLinkCelleType = new GC.Spread.Sheets.CellTypes.HyperLink();
+    comboBoxCellType = new GC.Spread.Sheets.CellTypes.ComboBox();
+    style = new GC.Spread.Sheets.Style();
+    data: any;
+    autoGenerateColumns = false;
+
+    constructor(private dataService: DataService) {
+        this.data = dataService.getEmployeesData();
+        this.comboBoxCellType.items([
+            {text: 'US', value: 'US'},
+            {text: 'UK', value: 'UK'},
+            {text: 'Germany', value: 'Germany'},
+            {text: 'Maxico', value: 'Maxico'}]);
+        this.style.backColor = 'lightgray';
+    }
+}

+ 66 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/worksheet/app-worksheet.component.html

@@ -0,0 +1,66 @@
+<h3>GC-Worksheet</h3>
+<div>
+    <p>以下示例展示如何使用表单上的属性。</p>
+</div>
+
+<div>
+    <gc-spread-sheets [hostStyle]="hostStyle" hostClass="spreadContainer">
+        <gc-worksheet [frozenRowCount]="frozenRowCount" [frozenColumnCount]="frozenColumnCount"
+                      [rowHeaderVisible]="rowHeaderVisible" [colHeaderVisible]="columnHeaderVisible"
+                      [frozenTrailingRowCount]="frozenTrailingRowCount"
+                      [frozenTrailingColumnCount]="frozenTrailingColumnCount" [sheetTabColor]="sheetTabColor"
+                      [frozenlineColor]="frozenlineColor" [selectionBackColor]="selectionBackColor"
+                      [selectionBorderColor]="selectionBorderColor" [dataSource]="data" [autoGenerateColumns]="autoGenerateColumns">
+            <gc-column width=150 dataField="Name"></gc-column>
+            <gc-column width=150 dataField="CountryRegionCode"></gc-column>
+            <gc-column width=100 dataField="City"></gc-column>
+            <gc-column width=200 dataField="AddressLine"></gc-column>
+            <gc-column width=100 dataField="PostalCode"></gc-column>
+        </gc-worksheet>
+    </gc-spread-sheets>
+</div>
+
+<div class="settingContainer">
+    <table>
+        <tr>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="rowHeaderVisible" />显示行头</label>
+            </td>
+            <td>
+                <label><input type="checkbox" [(ngModel)]="columnHeaderVisible" />显示列头</label>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <input type="text" [(ngModel)]="frozenRowCount" />冻结行数
+            </td>
+            <td>
+                <input type="text" [(ngModel)]="frozenColumnCount" />冻结列数
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <input type="text" [(ngModel)]="frozenTrailingRowCount" />末尾冻结行数
+            </td>
+            <td>
+                <input type="text" [(ngModel)]="frozenTrailingColumnCount" />末尾冻结列数
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <input type="color" [(ngModel)]="sheetTabColor" /> 标签色
+            </td>
+            <td>
+                <input type="color" [(ngModel)]="frozenlineColor" /> 冻结线色
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <input type="color" [(ngModel)]="selectionBackColor" /> 选择背景色
+            </td>
+            <td>
+                <input type="color" [(ngModel)]="selectionBorderColor" /> 选择边框色
+            </td>
+        </tr>
+    </table>
+</div>

+ 34 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/app/worksheet/app-worksheet.component.ts

@@ -0,0 +1,34 @@
+import {Component} from "@angular/core";
+import {DataService} from "../app-data.service";
+import {SpreadSheetsModule} from "@grapecity-software/spread-sheets-angular";
+import {FormsModule} from "@angular/forms";
+@Component({
+    standalone: true,
+    imports: [FormsModule, SpreadSheetsModule],
+    providers: [DataService],
+    templateUrl: './app-worksheet.component.html'
+})
+export class WorksheetComponent {
+    hostStyle = {
+        top: '90px',
+        bottom: '215px'
+    };
+    rowHeaderVisible = true;
+    columnHeaderVisible = true;
+    frozenRowCount = 3;
+    frozenColumnCount = 2;
+    frozenTrailingRowCount = 0;
+    frozenTrailingColumnCount = 0;
+    rowCount = 200;
+    columnCount = 20;
+    sheetTabColor = '#61E6E6';
+    frozenlineColor = '#000000';
+    selectionBackColor = '#D0D0D0';
+    selectionBorderColor = '#217346';
+    data: any;
+    autoGenerateColumns = false;
+
+    constructor(private dataservice: DataService) {
+        this.data = dataservice.getPersonAddressData();
+    }
+}

BIN
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/assets/img/logo.png


BIN
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/favicon.ico


File diff suppressed because it is too large
+ 19 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/fonts.css


BIN
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/img/logo.png


+ 0 - 0
android/app/src/main/assets/web-resources/SpreadJS/SpreadJS/samples/AngularSample/src/index.html


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