├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── stale.yml
├── .gitignore
├── FUNDING.yml
├── LICENSE
├── README.md
├── app.py
├── docs
├── BrowserWindow.html
├── Builder.html
├── Cleaner.html
├── Dispatcher.html
├── Packager.html
├── Requests.html
├── Services.html
├── Starter.html
├── Theme.html
├── Titlebar.html
├── global.html
├── index.html
├── main.js.html
├── scripts
│ ├── custom.js
│ ├── linenumber.js
│ ├── prettify
│ │ ├── Apache-License-2.0.txt
│ │ ├── lang-css.js
│ │ └── prettify.js
│ ├── search.js
│ └── utils.min.js
├── scripts_build.js.html
├── scripts_clean.js.html
├── scripts_dispatch.js.html
├── scripts_package.js.html
├── scripts_start.js.html
├── src_components_titlebar_Titlebar.js.html
├── src_components_titlebar_TitlebarButtons.js.html
├── src_theme_palette.js.html
├── src_utils_requests.js.html
├── src_utils_services.js.html
└── styles
│ ├── custom.css
│ ├── daybrush.css
│ ├── jsdoc.css
│ └── prettify.css
├── jsconfig.json
├── jsdoc.json
├── main.js
├── package.json
├── preload.js
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── renderer.js
├── requirements.txt
├── scripts
├── build.js
├── clean.js
├── dispatch.js
├── package.js
└── start.js
├── src
├── components
│ ├── App.js
│ ├── App.module.scss
│ ├── counter
│ │ ├── Counter.js
│ │ ├── Counter.module.scss
│ │ └── counterSlice.js
│ └── titlebar
│ │ ├── Titlebar.js
│ │ ├── TitlebarButtons.js
│ │ ├── img
│ │ └── favicon.png
│ │ └── scss
│ │ ├── Titlebar.module.scss
│ │ └── TitlebarButtons.module.scss
├── index.js
├── index.scss
├── logo.svg
├── serviceWorker.js
├── state
│ └── store.js
├── tests
│ ├── App.test.js
│ └── setupTests.js
├── theme
│ ├── palette.js
│ └── variables.scss
└── utils
│ ├── requests.js
│ └── services.js
├── utilities
├── deb
│ └── images
│ │ ├── background.png
│ │ ├── banner.png
│ │ └── icon.ico
├── dmg
│ └── images
│ │ ├── background.png
│ │ └── icon.icns
├── jsdoc
│ ├── LICENSE.md
│ ├── README.md
│ ├── fixtures
│ │ ├── base
│ │ │ ├── chains.js
│ │ │ └── index.js
│ │ ├── documents
│ │ │ ├── binder.js
│ │ │ ├── collector.js
│ │ │ ├── model.js
│ │ │ ├── probe.js
│ │ │ └── schema.js
│ │ ├── fixtures.conf.json
│ │ ├── mixins
│ │ │ ├── bussable.js
│ │ │ └── signalable.js
│ │ ├── strings
│ │ │ └── format.js
│ │ ├── tutorials
│ │ │ ├── Brush Teeth.md
│ │ │ ├── Drive Car.md
│ │ │ └── Fence Test.md
│ │ └── utils
│ │ │ └── logger.js
│ ├── package.json
│ ├── publish.js
│ ├── static
│ │ ├── scripts
│ │ │ ├── custom.js
│ │ │ ├── linenumber.js
│ │ │ ├── prettify
│ │ │ │ ├── Apache-License-2.0.txt
│ │ │ │ ├── lang-css.js
│ │ │ │ └── prettify.js
│ │ │ ├── search.js
│ │ │ └── utils.min.js
│ │ └── styles
│ │ │ ├── custom.css
│ │ │ ├── daybrush.css
│ │ │ ├── jsdoc.css
│ │ │ └── prettify.css
│ └── tmpl
│ │ ├── augments.tmpl
│ │ ├── container.tmpl
│ │ ├── details.tmpl
│ │ ├── example.tmpl
│ │ ├── examples.tmpl
│ │ ├── exceptions.tmpl
│ │ ├── layout.tmpl
│ │ ├── mainpage.tmpl
│ │ ├── members.tmpl
│ │ ├── method.tmpl
│ │ ├── params.tmpl
│ │ ├── properties.tmpl
│ │ ├── returns.tmpl
│ │ ├── source.tmpl
│ │ ├── tutorial.tmpl
│ │ └── type.tmpl
├── loaders
│ ├── react
│ │ ├── assets
│ │ │ ├── logo.svg
│ │ │ └── style.css
│ │ └── index.html
│ └── redux
│ │ ├── assets
│ │ ├── logo.svg
│ │ └── style.css
│ │ └── index.html
└── msi
│ └── images
│ ├── background.png
│ ├── banner.png
│ └── icon.ico
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-env",
4 | "@babel/react",
5 | ["minify", {
6 | "builtIns": false
7 | }]
8 | ],
9 | "plugins": [
10 | "@babel/plugin-proposal-async-generator-functions",
11 | "@babel/plugin-proposal-class-properties",
12 | "@babel/plugin-proposal-object-rest-spread",
13 | "@babel/plugin-transform-arrow-functions",
14 | "@babel/plugin-transform-async-to-generator",
15 | "@babel/plugin-transform-classes",
16 | "@babel/plugin-transform-computed-properties",
17 | "@babel/plugin-transform-destructuring",
18 | "@babel/plugin-transform-for-of",
19 | "@babel/plugin-transform-parameters",
20 | "@babel/plugin-transform-shorthand-properties",
21 | "@babel/plugin-transform-spread",
22 | "@babel/plugin-transform-sticky-regex",
23 | "@babel/plugin-transform-template-literals"
24 | ]
25 | }
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | build/
2 | dist/
3 | node_modules/
4 | stories/
5 | .snapshots/
6 | *.min.js
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es6: true,
5 | mocha: true
6 | },
7 | extends: ['plugin:react/recommended', 'airbnb'],
8 | globals: {
9 | Atomics: 'readonly',
10 | SharedArrayBuffer: 'readonly'
11 | },
12 | parser: 'babel-eslint',
13 | parserOptions: {
14 | ecmaFeatures: {
15 | jsx: true
16 | },
17 | ecmaVersion: 12,
18 | sourceType: 'module'
19 | },
20 | plugins: ['react'],
21 | rules: {
22 | 'array-bracket-spacing': [0],
23 | 'arrow-body-style': [0],
24 | 'arrow-parens': ['warn'],
25 | 'brace-style': [0],
26 | 'comma-dangle': ['warn', 'never'],
27 | 'consistent-return': [0],
28 | 'eol-last': [0],
29 | 'func-names': ['warn', 'always', {
30 | generators: 'as-needed'
31 | }],
32 | 'global-require': [0],
33 | 'implicit-arrow-linebreak': [0],
34 | 'import/no-dynamic-require': ['warn'],
35 | 'import/no-extraneous-dependencies': [0],
36 | 'import/order': ['warn'],
37 | 'import/prefer-default-export': [0],
38 | 'indent': ['warn', 2, {
39 | SwitchCase: 1
40 | }],
41 | 'jsx-a11y/anchor-is-valid': ['warn'],
42 | 'jsx-a11y/click-events-have-key-events': [0],
43 | 'jsx-a11y/interactive-supports-focus': [0],
44 | 'jsx-a11y/label-has-associated-control': [0],
45 | 'jsx-a11y/no-noninteractive-element-interactions': [0],
46 | 'keyword-spacing': ['warn'],
47 | 'linebreak-style': [0],
48 | 'max-len': ['warn'],
49 | 'no-console': ['warn', {
50 | allow: ['warn', 'error']
51 | }],
52 | 'no-mixed-spaces-and-tabs': ['warn'],
53 | 'no-multi-spaces': ['warn'],
54 | 'no-multiple-empty-lines': [0],
55 | 'no-nested-ternary': [0],
56 | 'no-param-reassign': [0],
57 | 'no-restricted-syntax': [0],
58 | 'no-tabs': ['warn'],
59 | 'no-trailing-spaces': ['warn'],
60 | 'no-underscore-dangle': ['warn'],
61 | 'no-unneeded-ternary': ['warn'],
62 | 'no-unused-expressions': [0],
63 | 'no-unused-vars': ['warn', { 'argsIgnorePattern': '^_' }],
64 | 'no-use-before-define': ['error', {
65 | 'functions': false
66 | }],
67 | 'object-curly-newline': [0],
68 | 'object-curly-spacing': ['warn'],
69 | 'object-shorthand': ['warn', 'always'],
70 | 'one-var': ['warn', {
71 | 'initialized': 'never'
72 | }],
73 | 'one-var-declaration-per-line': ['warn', 'initializations'],
74 | 'operator-linebreak': ['warn'],
75 | 'padded-blocks': [0],
76 | 'prefer-arrow-callback': ['warn'],
77 | 'prefer-const': ['warn'],
78 | 'prefer-destructuring': [
79 | 'warn',
80 | {
81 | array: true,
82 | object: true
83 | },
84 | {
85 | enforceForRenamedProperties: false
86 | }
87 | ],
88 | 'prefer-template': ['warn'],
89 | 'quote-props': ['warn', 'consistent'],
90 | 'quotes': ['warn'],
91 | 'react/destructuring-assignment': [0],
92 | 'react/forbid-prop-types': [0],
93 | 'react/jsx-closing-bracket-location': ['warn'],
94 | 'react/jsx-curly-newline': ['warn'],
95 | 'react/jsx-curly-spacing': ['warn', 'always'],
96 | 'react/jsx-equals-spacing': ['warn'],
97 | 'react/jsx-filename-extension': [0],
98 | 'react/jsx-fragments': [0],
99 | 'react/jsx-indent': ['warn', 2],
100 | 'react/jsx-one-expression-per-line': ['warn'],
101 | 'react/jsx-props-no-spreading': [0],
102 | 'react/jsx-tag-spacing': ['warn'],
103 | 'react/jsx-wrap-multilines': ['warn'],
104 | 'react/no-access-state-in-setstate': [0],
105 | 'react/no-array-index-key': [0],
106 | 'react/no-unused-state': ['warn'],
107 | 'react/prefer-stateless-function': ['warn'],
108 | 'react/prop-types': ['warn'],
109 | 'react/require-default-props': ['warn'],
110 | 'react/sort-comp': [0],
111 | 'react/state-in-constructor': ['warn', 'never'],
112 | 'rest-spread-spacing': ['warn', 'never'],
113 | 'semi': ['warn'],
114 | 'sort-keys': ['error', 'asc', { 'caseSensitive': false }],
115 | 'space-before-function-paren': ['warn'],
116 | 'spaced-comment': ['warn']
117 | },
118 | settings: {
119 | 'import/resolver': {
120 | node: {
121 | paths: ['./', 'src']
122 | }
123 | }
124 | }
125 | };
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: "bug \U0001F99F"
6 | assignees: iPzard
7 |
8 | ---
9 |
10 | **🦟 Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **Steps to Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement ✨
6 | assignees: iPzard
7 |
8 | ---
9 |
10 | **✨ Describe the feature**
11 | A clear and concise description of the feature you want.
12 |
13 | **Additional context**
14 | Add any other context or screenshots about the feature request here.
15 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 30
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pinned
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: wontfix
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because it has not had
14 | recent activity. It will be closed if no further activity occurs. Thank you
15 | for your contributions.
16 | # Comment to post when closing a stale issue. Set to `false` to disable
17 | closeComment: This issue has been closed due to inactivity.
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | #cache
4 | app.pyc
5 | app.spec
6 | __pycache__
7 |
8 | # debug
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 |
13 | # dependencies
14 | /node_modules
15 | /.pnp
16 | .pnp.js
17 |
18 | # testing
19 | /coverage
20 |
21 | # production
22 | /build
23 | /dist
24 | /resources/app
25 | /resources/app.app
26 |
27 | # misc
28 | .DS_Store
29 | .env.local
30 | .env.development.local
31 | .env.test.local
32 | .env.production.local
33 |
--------------------------------------------------------------------------------
/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # repo: your_github_handle/.github
2 | # filename: FUNDING.YML
3 |
4 | github: iPzard
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 iPzard
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Electron, React & Python Template
2 |
3 | [](https://github.com/iPzard/electron-react-python-template#readme)
4 | [](https://github.com/iPzard/electron-react-python-template/blob/master/LICENSE)
5 |
6 | > Multi-platform Electron template, using React & Redux Toolkit with Python/Flask microservices.
7 |
8 | 
9 |
10 | ## 🛠️ Setup
11 | Ensure you have [Node](https://nodejs.org/en/download/) and [Python](https://www.python.org/downloads/) installed, then clone this repository. After it's cloned, navigate to the project's root directory on your computer and
12 | run the following scrips in a terminal application *(e.g., Git Bash)*:
13 |
14 | **Install Python dependencies:**
15 | ```bash
16 | pip3 install -r requirements.txt
17 | ```
18 |
19 | **Install Node dependencies:**
20 | ```bash
21 | yarn install
22 | ```
23 |
24 |
25 |
26 | ## ⚙️ Config
27 |
28 | **Electron:** Electron's `main.js`, `preload.js`, and `renderer.js` files can be found in the project's root directory.
29 |
30 | **React:** React files can be found in the `./src/` folder, the custom toolbar is in `./src/components/toolbar`.
31 |
32 | **Python:** Python scripts can be created in the `./app.py` file and used on events via [REST](https://developer.mozilla.org/en-US/docs/Glossary/REST) calls.
33 |
34 |
35 |
36 | ## 📜 Scripts
37 |
38 | Below are the scripts you'll need to run and package your application, as well as build out JSDoc documentation, if you choose to do so. An exhaustive list of scripts that are available can be found in the `package.json` file of the project's root directory, in the `scripts` section.
39 |
40 | | ⚠️ When packaging, you must install [PyInstaller](https://pypi.org/project/pyinstaller) and add its path in your environment variables. The name of your package in [package.js](https://github.com/iPzard/electron-react-python-template/blob/master/scripts/package.js) must also match the name field in [package.json](https://github.com/iPzard/electron-react-python-template/blob/master/package.json). |
41 | | --- |
42 |
43 | **Start Developer Mode:**
44 | ```bash
45 | yarn run start
46 | ```
47 |
48 | **Package Windows: *1* **
49 | ```bash
50 | yarn run build:package:windows
51 | ```
52 |
53 | **Package macOS:**
54 | ```bash
55 | yarn run build:package:mac
56 | ```
57 |
58 | **Package Linux:**
59 | ```bash
60 | yarn run build:package:linux
61 | ```
62 |
63 | **Build Documentation:**
64 | ```bash
65 | yarn run build:docs
66 | ```
67 |
68 | *1 Windows uses [electron-wix-msi](https://github.com/felixrieseberg/electron-wix-msi), you must install and add its path to your environment variables.*
69 |
70 |
71 | ## 🐱👓 Docs
72 | Code documentation for this template, created with [JSDoc](https://github.com/jsdoc/jsdoc), can be found here:
73 | [Electron, React, & Python Template](https://ipzard.github.io/electron-react-python-template/)
74 |
75 |
76 | ## 🦟 Bugs
77 | Bugs reported on the project's [issues page](https://github.com/iPzard/electron-react-python-template/issues) will be exterminated as quickly as possible, be sure to include steps to reproduce so they can be spotted easily.
78 |
79 |
80 | ## 🏷️ License
81 | MIT © [iPzard](https://github.com/iPzard/electron-react-python-template/blob/master/LICENSE)
--------------------------------------------------------------------------------
/app.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from flask import Flask, jsonify, request
3 | from flask_cors import CORS
4 |
5 | app = Flask(__name__)
6 | app_config = {"host": "0.0.0.0", "port": sys.argv[1]}
7 |
8 | """
9 | ---------------------- DEVELOPER MODE CONFIG -----------------------
10 | """
11 | # Developer mode uses app.py
12 | if "app.py" in sys.argv[0]:
13 | # Update app config
14 | app_config["debug"] = True
15 |
16 | # CORS settings
17 | cors = CORS(
18 | app,
19 | resources={r"/*": {"origins": "http://localhost*"}},
20 | )
21 |
22 | # CORS headers
23 | app.config["CORS_HEADERS"] = "Content-Type"
24 |
25 |
26 | """
27 | --------------------------- REST CALLS -----------------------------
28 | """
29 | # Remove and replace with your own
30 | @app.route("/example")
31 | def example():
32 |
33 | # See /src/components/App.js for frontend call
34 | return jsonify("Example response from Flask! Learn more in /app.py & /src/components/App.js")
35 |
36 |
37 | """
38 | -------------------------- APP SERVICES ----------------------------
39 | """
40 | # Quits Flask on Electron exit
41 | @app.route("/quit")
42 | def quit():
43 | shutdown = request.environ.get("werkzeug.server.shutdown")
44 | shutdown()
45 |
46 | return
47 |
48 |
49 | if __name__ == "__main__":
50 | app.run(**app_config)
51 |
--------------------------------------------------------------------------------
/docs/Cleaner.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Cleaner - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
Cleaner
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Cleaner
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | Source:
63 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | See:
96 |
97 |
98 | scripts\dispatch.js cleanProject() for complete list
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | Cleans project by removing several files & folders.
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/docs/Theme.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Theme - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
Theme
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Theme
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | Source:
63 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | Tutorials:
94 |
95 |
96 | Tutorial: - https://www.aka.ms/themedesigner
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | Theme for Microsoft Fluent UI, which is built into the project.
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/docs/scripts/custom.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/docs/scripts/custom.js
--------------------------------------------------------------------------------
/docs/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | /*global document */
2 | (function() {
3 | var source = document.getElementsByClassName('prettyprint source linenums');
4 | var i = 0;
5 | var lineNumber = 0;
6 | var lineId;
7 | var lines;
8 | var totalLines;
9 | var anchorHash;
10 |
11 | if (source && source[0]) {
12 | anchorHash = document.location.hash.substring(1);
13 | lines = source[0].getElementsByTagName('li');
14 | totalLines = lines.length;
15 |
16 | for (; i < totalLines; i++) {
17 | lineNumber++;
18 | lineId = 'line' + lineNumber;
19 | lines[i].id = lineId;
20 | if (lineId === anchorHash) {
21 | lines[i].className += ' selected';
22 | }
23 | }
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/docs/scripts/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/docs/scripts/search.js:
--------------------------------------------------------------------------------
1 |
2 | (function () {
3 | var nav = document.querySelector("nav");
4 | var searchBar = nav.querySelector(".search");
5 | var input = searchBar.querySelector("input");
6 | // var submit = searchBar.querySelector("button");
7 | var groups = Array.prototype.slice.call(document.querySelectorAll("nav>ul .parent")).map(function (group) {
8 | var items = Array.prototype.slice.call(group.querySelectorAll("a"));
9 | var strings = items.map(function (a) {
10 | return a.innerText.toLowerCase();
11 | });
12 |
13 | return {el: group, items: items, strings, strings};
14 | });
15 | input.addEventListener("keyup", function (e) {
16 | var value = input.value.toLowerCase();
17 |
18 | if (value) {
19 | utils.addClass(nav, "searching");
20 | } else {
21 | utils.removeClass(nav, "searching");
22 | return;
23 | }
24 | groups.forEach(function (group) {
25 | var isSearch = false;
26 | var items = group.items;
27 |
28 | group.strings.forEach(function (v, i) {
29 | var item = items[i];
30 | if (utils.hasClass(item.parentNode, "parent")) {
31 | item = item.parentNode;
32 | }
33 | if (v.indexOf(value) > -1) {
34 | utils.addClass(item, "targeting");
35 | isSearch = true;
36 | } else {
37 | utils.removeClass(item, "targeting");
38 | }
39 | });
40 | if (isSearch) {
41 | utils.addClass(group.el, "module-targeting");
42 | } else {
43 | utils.removeClass(group.el, "module-targeting");
44 | }
45 | });
46 | });
47 | })();
--------------------------------------------------------------------------------
/docs/scripts/utils.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2018 Daybrush
3 | @name: @daybrush/utils
4 | license: MIT
5 | author: Daybrush
6 | repository: https://github.com/daybrush/utils
7 | @version 0.4.0
8 | */
9 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.utils=t()}(this,function(){"use strict";var u="rgb",c="rgba",f="hsl",l="hsla",e=[u,c,f,l],t="function",n="object",r="string",i="undefined",a=typeof window!==i,o=["webkit","ms","moz","o"],s=function(e){if(typeof document===i)return"";var t=(document.body||document.documentElement).style,n=o.length;if(typeof t[e]!==i)return e;for(var r=0;r
2 |
3 |
4 |
5 | scripts/build.js - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
scripts/build.js
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | const { spawnSync } = require('child_process');
46 | const spawnOptions = { detached: false, shell: true, stdio: 'inherit' };
47 |
48 | /**
49 | * @namespace Builder
50 | * @description - Builds React & Python builds of project so Electron can be used.
51 | */
52 | class Builder {
53 |
54 | /**
55 | * @description - Creates React and Python production builds.
56 | * @memberof Builder
57 | */
58 | buildAll = () => {
59 | const { buildPython, buildReact } = this;
60 |
61 | buildPython();
62 | buildReact();
63 | }
64 |
65 | /**
66 | * @description - Creates production build of Python back end.
67 | * @memberof Builder
68 | */
69 | buildPython = () => {
70 | console.log('Creating Python distribution files...');
71 |
72 | const app = 'app.py';
73 | const icon = './public/favicon.ico';
74 |
75 | const options = [
76 | '--noconsole', // No shell
77 | '--noconfirm', // Don't confirm overwrite
78 | '--distpath ./resources', // Dist (out) path
79 | `--icon ${icon}` // Icon to use
80 | ].join(' ');
81 | // TODO: Check if python is installed.. If not, prompt user
82 | // "Python is required but not installed, install it? (y/n)"
83 | spawnSync(`pyinstaller ${options} ${app}`, spawnOptions);
84 | }
85 |
86 | /**
87 | * @description - Creates production build of React front end.
88 | * @memberof Builder
89 | */
90 | buildReact = () => {
91 | console.log('Creating React distribution files...');
92 | spawnSync(`react-scripts build`, spawnOptions);
93 | }
94 | }
95 |
96 | module.exports.Builder = Builder;
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/docs/scripts_clean.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | scripts/clean.js - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
scripts/clean.js
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | const {
46 | existsSync,
47 | readdirSync,
48 | rmdirSync,
49 | statSync,
50 | unlinkSync
51 | } = require('fs');
52 |
53 | /**
54 | * @namespace Cleaner
55 | * @description - Cleans project by removing several files & folders.
56 | * @see scripts\dispatch.js cleanProject() for complete list
57 | */
58 | class Cleaner {
59 | removePath = (pathToRemove) => {
60 |
61 | if (existsSync(pathToRemove)) {
62 | console.log(`Removing: ${pathToRemove}`);
63 |
64 | if (statSync(pathToRemove).isFile()) unlinkSync(pathToRemove);
65 | else {
66 | const files = readdirSync(pathToRemove);
67 |
68 | files.forEach((file) => {
69 | const filePath = `${pathToRemove}/${file}`;
70 |
71 | if (statSync(filePath).isDirectory()) this.removePath(filePath);
72 | else unlinkSync(filePath);
73 | });
74 | rmdirSync(pathToRemove);
75 | }
76 | }
77 | };
78 | }
79 |
80 | module.exports.Cleaner = Cleaner;
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/docs/src_components_titlebar_Titlebar.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | src/components/titlebar/Titlebar.js - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
src/components/titlebar/Titlebar.js
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | import {
46 | CloseButton,
47 | ContractButton,
48 | MaximizeButton,
49 | MinimizeButton
50 | } from 'components/titlebar/TitlebarButtons';
51 | import React, { useState } from 'react';
52 |
53 | import { app } from 'utils/services';
54 |
55 | import favicon from 'components/titlebar/img/favicon.png';
56 | import styles from 'components/titlebar/scss/Titlebar.module.scss';
57 |
58 |
59 | /**
60 | * @namespace Titlebar
61 | * @description Title Component to use as an Electron customized titlebar.
62 | * electron-window-title-text used in main.js to set opacity on/off focus.
63 | * electron-window-title-buttons used in main.js to set opacity on/off focus.
64 | */
65 |
66 | const Titlebar = () => {
67 |
68 | const [ maximized, setMaximized ] = useState(false);
69 |
70 | const handleMaximizeToggle = () => {
71 | !maximized ? app.maximize() : app.unmaximize();
72 | setMaximized(!maximized);
73 | };
74 |
75 | return (
76 | <section className={ styles.titlebar }>
77 | <div>
78 | <img src={ favicon } alt="favicon" />
79 | <span id="electron-window-title-text">{ document.title }</span>
80 | </div>
81 |
82 | <div id="electron-window-title-buttons">
83 | <MinimizeButton onClick={ app.minimize } />
84 | {
85 | maximized
86 | ? <ContractButton onClick={ handleMaximizeToggle } />
87 | : <MaximizeButton onClick={ handleMaximizeToggle } />
88 | }
89 | <CloseButton onClick={ app.quit } />
90 | </div>
91 | </section>
92 | );
93 | };
94 |
95 | export default Titlebar;
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/docs/src_components_titlebar_TitlebarButtons.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | src/components/titlebar/TitlebarButtons.js - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
src/components/titlebar/TitlebarButtons.js
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | import React from 'react';
46 |
47 | import styles from 'components/titlebar/scss/TitlebarButtons.module.scss';
48 |
49 | /**
50 | * @description Titlebar minimize button.
51 | * @memberof Titlebar
52 | */
53 | export const MinimizeButton = (props) => (
54 | <button
55 | { ...props }
56 | aria-label="Minimize"
57 | className={ styles['minimize-button'] }
58 | title="Minimize"
59 | type="button"
60 | >
61 | <span />
62 | </button>
63 | );
64 |
65 | /**
66 | * @description Titlebar maximize button.
67 | * @memberof Titlebar
68 | */
69 | export const MaximizeButton = (props) => (
70 | <button
71 | { ...props }
72 | aria-label="Maximize"
73 | className={ styles['maximize-button'] }
74 | title="Maximize"
75 | type="button"
76 | >
77 | <span />
78 | </button>
79 | );
80 |
81 | /**
82 | * @description Titlebar contract (unmaximize) button.
83 | * @memberof Titlebar
84 | */
85 | export const ContractButton = (props) => (
86 | <button
87 | { ...props }
88 | aria-label="Contract"
89 | className={ styles['contract-button'] }
90 | title="Contract"
91 | type="button"
92 | >
93 | <span />
94 | <span />
95 | </button>
96 | );
97 |
98 | /**
99 | * @description Titlebar close button.
100 | * @memberof Titlebar
101 | */
102 | export const CloseButton = (props) => (
103 | <button
104 | { ...props }
105 | aria-label="Close"
106 | className={ styles['close-button'] }
107 | title="Close"
108 | type="button"
109 | >
110 | <span />
111 | <span />
112 | </button>
113 | );
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/docs/src_theme_palette.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | src/theme/palette.js - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
src/theme/palette.js
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | /**
46 | * @namespace Theme
47 | * @description - Theme for Microsoft Fluent UI, which is built into the project.
48 | *
49 | * @tutorial - https://www.aka.ms/themedesigner
50 | */
51 |
52 | export const customTheme = {
53 | themePrimary: '#57a9a9',
54 | themeLighterAlt: '#030707',
55 | themeLighter: '#0e1b1b',
56 | themeLight: '#1a3232',
57 | themeTertiary: '#336565',
58 | themeSecondary: '#4c9494',
59 | themeDarkAlt: '#63b1b1',
60 | themeDark: '#77bdbd',
61 | themeDarker: '#96cece',
62 | neutralLighterAlt: '#eeeeee',
63 | neutralLighter: '#eaeaea',
64 | neutralLight: '#e1e1e1',
65 | neutralQuaternaryAlt: '#d1d1d1',
66 | neutralQuaternary: '#c8c8c8',
67 | neutralTertiaryAlt: '#c0c0c0',
68 | neutralTertiary: '#b5b5b5',
69 | neutralSecondary: '#9d9d9d',
70 | neutralPrimaryAlt: '#868686',
71 | neutralPrimary: '#252525',
72 | neutralDark: '#565656',
73 | black: '#3e3e3e',
74 | white: '#f5f5f5'
75 | };
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/src_utils_services.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | src/utils/services.js - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
src/utils/services.js
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | // Electron Inter Process Communication and dialog
46 | const { ipcRenderer } = window.require('electron');
47 |
48 | /**
49 | * @namespace Services
50 | * @description - Methods from Electron Inter Process Communication.
51 | * @property {function} maximize - Function to maximize the screen size of the program.
52 | * @property {function} minimize - Function to minimize the screen size of the program.
53 | * @property {function} quit - Function to close and exit the program.
54 | * @property {function} unmaximize - Function to contract (unmaximize) the screen size of the program.
55 | */
56 | export const app = {
57 | maximize: () => ipcRenderer.send('app-maximize'),
58 | minimize: () => ipcRenderer.send('app-minimize'),
59 | quit: () => ipcRenderer.send('app-quit'),
60 | unmaximize: () => ipcRenderer.send('app-unmaximize')
61 | };
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/docs/styles/custom.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/docs/styles/custom.css
--------------------------------------------------------------------------------
/docs/styles/daybrush.css:
--------------------------------------------------------------------------------
1 | .readme table {
2 | border-spacing: 0;
3 | border-collapse: collapse;
4 | }
5 | .readme * {
6 | box-sizing: border-box;
7 | }
8 | .readme table th, .readme table td {
9 | padding: 6px 13px;
10 | border: 1px solid #ddd;
11 | }
12 |
13 | nav>ul>li:after {
14 | content: "";
15 | position: absolute;
16 | right: 10px;
17 | top: 0;
18 | bottom: 0;
19 | width: 0;
20 | height: 0;
21 | margin: auto 0px;
22 | border-top: 7px solid #ccc;
23 | border-left: 6px solid transparent;
24 | border-right: 6px solid transparent;
25 | }
26 | nav li h4, nav li ul {
27 | display: none;
28 | }
29 |
30 | .name.typescript {
31 | background: #374E79;
32 | font-size: 14px;
33 | }
34 | .name.typescript .signature {
35 | color: #21de60;
36 | }
37 | .ts-params.typescript table .last {
38 | display: none;
39 | }
40 | table.params th, table.params tr td , table.params tr td.type{
41 | word-break: break-word;
42 | white-space: normal;
43 | }
44 |
45 | nav .search {
46 | position: relative;
47 | margin: 0px 10px;
48 | border: 3px solid #333;
49 | height: 43px;
50 | }
51 | nav .search .input-area {
52 | position: absolute;
53 | left: 0;
54 | top: 0;
55 | right: 35px;
56 | height: 35px;
57 | }
58 | nav .search input {
59 | position: relative;
60 | width: 100%;
61 | height: 100%;
62 | border: 0;
63 | padding: 0;
64 | text-indent: 10px;
65 | font-weight: bold;
66 | font-size: 14px;
67 | outline: none;
68 | }
69 | nav .search button {
70 | position: absolute;
71 | top: 0;
72 | right: 0px;
73 | width: 35px;
74 | height: 35px;
75 | border: 0;
76 | padding: 0;
77 | outline: none;
78 | cursor: pointer;
79 | }
80 | nav .search button:before {
81 | position: absolute;
82 | content: "";
83 | width: 18px;
84 | height: 18px;
85 | top: 7px;
86 | left: 7px;
87 | border: 3px solid #333;
88 | border-radius: 50%;
89 | box-sizing: border-box;
90 | }
91 | nav .search button:after {
92 | position: absolute;
93 | content: "";
94 | width: 3px;
95 | height: 11px;
96 | top: 21px;
97 | left: 18px;
98 | background: #333;
99 | transform-origin: 50% 0%;
100 | -ms-transform-origin: 50% 0%;
101 | -webkit-transform-origin: 50% 0%;
102 | transform: rotate(-45deg);
103 | -ms-transform: rotate(-45deg);
104 | -webkit-transform: rotate(-45deg);
105 | }
106 |
107 | nav.searching li:after {
108 | display: none!important;
109 | }
110 | nav.searching li h4, nav.searching li ul {
111 | display: block!important;
112 | }
113 |
114 | nav.searching .parent {
115 | display: none;
116 | }
117 | nav.searching .parent ul li a {
118 | display: none;
119 | }
120 |
121 | nav.searching .parent.module-targeting {
122 | display: block;
123 | }
124 | nav.searching .parent.module-targeting ul li a {
125 | display: none;
126 | }
127 | nav.searching .parent.module-targeting ul li a.targeting {
128 | display: block;
129 | }
130 | nav.searching .parent.targeting ul li a {
131 | display: block;
132 | }
133 |
134 | nav>h2.custom>a {
135 | margin:12px 10px;
136 | }
--------------------------------------------------------------------------------
/docs/styles/prettify.css:
--------------------------------------------------------------------------------
1 | .pln {
2 | color: #ddd;
3 | }
4 |
5 | /* string content */
6 | .str {
7 | color: #61ce3c;
8 | }
9 |
10 | /* a keyword */
11 | .kwd {
12 | color: #fbde2d;
13 | }
14 |
15 | /* a comment */
16 | .com {
17 | color: #aeaeae;
18 | }
19 |
20 | /* a type name */
21 | .typ {
22 | color: #8da6ce;
23 | }
24 |
25 | /* a literal value */
26 | .lit {
27 | color: #fbde2d;
28 | }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #ddd;
33 | }
34 |
35 | /* lisp open bracket */
36 | .opn {
37 | color: #000000;
38 | }
39 |
40 | /* lisp close bracket */
41 | .clo {
42 | color: #000000;
43 | }
44 |
45 | /* a markup tag name */
46 | .tag {
47 | color: #8da6ce;
48 | }
49 |
50 | /* a markup attribute name */
51 | .atn {
52 | color: #fbde2d;
53 | }
54 |
55 | /* a markup attribute value */
56 | .atv {
57 | color: #ddd;
58 | }
59 |
60 | /* a declaration */
61 | .dec {
62 | color: #EF5050;
63 | }
64 |
65 | /* a variable name */
66 | .var {
67 | color: #c82829;
68 | }
69 |
70 | /* a function name */
71 | .fun {
72 | color: #4271ae;
73 | }
74 |
75 | /* Specify class=linenums on a pre to get line numbering */
76 | ol.linenums {
77 | margin-top: 0;
78 | margin-bottom: 0;
79 | }
80 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "src"
4 | },
5 | "include": ["src"]
6 | }
--------------------------------------------------------------------------------
/jsdoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "source": {
3 | "include": ["main.js", "scripts", "src"],
4 | "includePattern": ".js$",
5 | "excludePattern": "(node_modules/|docs)"
6 | },
7 | "plugins": ["plugins/markdown"],
8 | "templates": {
9 | "cleverLinks": true,
10 | "monospaceLinks": true
11 | },
12 | "opts": {
13 | "recurse": true,
14 | "destination": "docs",
15 | "template": "utilities/jsdoc",
16 | "readme": "readme.md"
17 | }
18 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Daniel Wade",
3 | "description": "Started template for Electron, React, Python app",
4 | "dependencies": {
5 | "@reduxjs/toolkit": "^1.1.0",
6 | "axios": "^0.21.1",
7 | "electron-is-dev": "^1.2.0",
8 | "get-port": "^5.1.1",
9 | "prop-types": "^15.7.2",
10 | "react": "^16.13.1",
11 | "react-dom": "^16.13.1",
12 | "react-redux": "^7.2.0",
13 | "react-scripts": "3.4.1"
14 | },
15 | "devDependencies": {
16 | "@testing-library/jest-dom": "^4.2.4",
17 | "@testing-library/react": "^9.3.2",
18 | "@testing-library/user-event": "^7.1.2",
19 | "babel-eslint": "^10.1.0",
20 | "cross-env": "^7.0.3",
21 | "electron": "^13.0.1",
22 | "electron-devtools-installer": "^3.2.0",
23 | "electron-installer-dmg": "^3.0.0",
24 | "electron-packager": "^15.0.0",
25 | "electron-wix-msi": "^3.0.4",
26 | "eslint-config-airbnb": "^18.2.1",
27 | "eslint-plugin-import": "^2.23.4",
28 | "eslint-plugin-jsx-a11y": "^6.4.1",
29 | "eslint-plugin-react": "^7.24.0",
30 | "eslint-plugin-standard": "^5.0.0",
31 | "jsdoc": "^3.6.5",
32 | "sass": "^1.26.5"
33 | },
34 | "optionalDependencies": {
35 | "electron-installer-debian": "^3.1.0"
36 | },
37 | "browserslist": {
38 | "production": [
39 | ">0.2%",
40 | "not dead",
41 | "not op_mini all"
42 | ],
43 | "development": [
44 | "last 1 chrome version",
45 | "last 1 firefox version",
46 | "last 1 safari version"
47 | ]
48 | },
49 | "build": {
50 | "extraResources": [
51 | "./resources/app"
52 | ]
53 | },
54 | "homepage": "./",
55 | "license": "MIT",
56 | "main": "main.js",
57 | "name": "electron-react-python-template",
58 | "private": true,
59 | "scripts": {
60 | "build": "node ./scripts/dispatch build all",
61 | "build:all": "node ./scripts/dispatch build all",
62 | "build:react": "node ./scripts/dispatch build react",
63 | "build:python": "node ./scripts/dispatch build python",
64 | "build:docs": "jsdoc -c jsdoc.json",
65 | "build:package:linux": "node ./scripts/dispatch package linux",
66 | "build:package:mac": "node ./scripts/dispatch package mac",
67 | "build:package:windows": "node ./scripts/dispatch package windows",
68 | "clean": "node ./scripts/dispatch clean",
69 | "eject": "react-scripts eject",
70 | "start": "node ./scripts/dispatch start",
71 | "start:electron": "electron .",
72 | "start:react": "react-scripts start",
73 | "test": "react-scripts test"
74 | },
75 | "version": "1.0.0"
76 | }
77 |
--------------------------------------------------------------------------------
/preload.js:
--------------------------------------------------------------------------------
1 | // All of the Node.js APIs are available in the preload process.
2 | // It has the same sandbox as a Chrome extension.
3 | window.addEventListener('DOMContentLoaded', () => {
4 |
5 | process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = true;
6 |
7 | const replaceText = (selector, text) => {
8 | const element = document.getElementById(selector);
9 | if (element) element.innerText = text;
10 | };
11 |
12 | for (const type of ['chrome', 'node', 'electron']) {
13 | replaceText(`${type}-version`, process.versions[type]);
14 | }
15 | });
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Electron, React & Python App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/renderer.js:
--------------------------------------------------------------------------------
1 | // This file is required by the index.html file and will
2 | // be executed in the renderer process for that window.
3 | // No Node.js APIs are available in this process because
4 | // `nodeIntegration` is turned off. Use `preload.js` to
5 | // selectively enable features needed in the rendering
6 | // process.
7 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask
2 | flask-cors
3 | pyinstaller
--------------------------------------------------------------------------------
/scripts/build.js:
--------------------------------------------------------------------------------
1 | const { spawnSync } = require('child_process');
2 | const spawnOptions = { detached: false, shell: true, stdio: 'inherit' };
3 |
4 | /**
5 | * @namespace Builder
6 | * @description - Builds React & Python builds of project so Electron can be used.
7 | */
8 | class Builder {
9 |
10 | /**
11 | * @description - Creates React and Python production builds.
12 | * @memberof Builder
13 | */
14 | buildAll = () => {
15 | const { buildPython, buildReact } = this;
16 |
17 | buildPython();
18 | buildReact();
19 | }
20 |
21 | /**
22 | * @description - Creates production build of Python back end.
23 | * @memberof Builder
24 | */
25 | buildPython = () => {
26 | console.log('Creating Python distribution files...');
27 |
28 | const app = 'app.py';
29 | const icon = './public/favicon.ico';
30 |
31 | const options = [
32 | '--noconsole', // No shell
33 | '--noconfirm', // Don't confirm overwrite
34 | '--distpath ./resources', // Dist (out) path
35 | `--icon ${icon}` // Icon to use
36 | ].join(' ');
37 | // TODO: Check if python is installed.. If not, prompt user
38 | // "Python is required but not installed, install it? (y/n)"
39 | spawnSync(`pyinstaller ${options} ${app}`, spawnOptions);
40 | }
41 |
42 | /**
43 | * @description - Creates production build of React front end.
44 | * @memberof Builder
45 | */
46 | buildReact = () => {
47 | console.log('Creating React distribution files...');
48 | spawnSync(`react-scripts build`, spawnOptions);
49 | }
50 | }
51 |
52 | module.exports.Builder = Builder;
--------------------------------------------------------------------------------
/scripts/clean.js:
--------------------------------------------------------------------------------
1 | const {
2 | existsSync,
3 | readdirSync,
4 | rmdirSync,
5 | statSync,
6 | unlinkSync
7 | } = require('fs');
8 |
9 | /**
10 | * @namespace Cleaner
11 | * @description - Cleans project by removing several files & folders.
12 | * @see scripts\dispatch.js cleanProject() for complete list
13 | */
14 | class Cleaner {
15 | removePath = (pathToRemove) => {
16 |
17 | if (existsSync(pathToRemove)) {
18 | console.log(`Removing: ${pathToRemove}`);
19 |
20 | if (statSync(pathToRemove).isFile()) unlinkSync(pathToRemove);
21 | else {
22 | const files = readdirSync(pathToRemove);
23 |
24 | files.forEach((file) => {
25 | const filePath = `${pathToRemove}/${file}`;
26 |
27 | if (statSync(filePath).isDirectory()) this.removePath(filePath);
28 | else unlinkSync(filePath);
29 | });
30 | rmdirSync(pathToRemove);
31 | }
32 | }
33 | };
34 | }
35 |
36 | module.exports.Cleaner = Cleaner;
37 |
--------------------------------------------------------------------------------
/scripts/dispatch.js:
--------------------------------------------------------------------------------
1 | const [ , , script, command ] = process.argv;
2 | const { existsSync, readdirSync } = require('fs');
3 | const path = require('path');
4 |
5 | const { Builder } = require('./build');
6 | const { Cleaner } = require('./clean');
7 | const { Packager } = require('./package');
8 | const { Starter } = require('./start');
9 |
10 |
11 | /**
12 | * @namespace Dispatcher
13 | * @description - Dispatches script commands to various scripts.
14 | * @argument script - Script manager to use (e.g., build or package).
15 | * @argument command - Command argument describing exact script to run.
16 | */
17 |
18 | switch (script) {
19 | case 'build':
20 | return buildApp();
21 |
22 | case 'clean':
23 | return cleanProject();
24 |
25 | case 'package':
26 | return packageApp();
27 |
28 | case 'start':
29 | return startDeveloperMode();
30 |
31 | // no default
32 | }
33 |
34 |
35 | /**
36 | * @description - Builds various production builds (e.g., Python, React).
37 | * @memberof Dispatcher
38 | */
39 | function buildApp() {
40 | const builder = new Builder();
41 |
42 | switch (command) {
43 | case 'react':
44 | return builder.buildReact();
45 |
46 | case 'python':
47 | return builder.buildPython();
48 |
49 | case 'all':
50 | return builder.buildAll();
51 |
52 | // no default
53 | }
54 | }
55 |
56 |
57 | /**
58 | * @description - Cleans project by removing various files and folders.
59 | * @memberof Dispatcher
60 | */
61 | function cleanProject() {
62 | const cleaner = new Cleaner();
63 | const getPath = (...filePaths) => path.join(__dirname, '..', ...filePaths);
64 |
65 | // Files to remove during cleaning
66 | [
67 | // Cache
68 | getPath('app.pyc'),
69 | getPath('app.spec'),
70 | getPath('__pycache__'),
71 |
72 | // Debug
73 | getPath('npm-debug.log'),
74 | getPath('yarn-debug.log'),
75 | getPath('yarn-error.log'),
76 |
77 | // Dependencies
78 | getPath('.pnp'),
79 | getPath('.pnp.js'),
80 | getPath('node_modules'),
81 | getPath('package-lock.json'),
82 | getPath('yarn.lock'),
83 |
84 | // Testing
85 | getPath('coverage'),
86 |
87 | // Production
88 | getPath('build'),
89 | getPath('dist'),
90 | getPath('docs'),
91 |
92 | // Misc
93 | getPath('.DS_Store')
94 | ]
95 | // Iterate and remove process
96 | .forEach(cleaner.removePath);
97 |
98 |
99 | /**
100 | * Remove resources/app if it exists, then if the resources
101 | * folder isn't used for any other Python modules, delete it too.
102 | */
103 | const resourcesDir = getPath('resources');
104 | const isResourcesDirExist = existsSync(resourcesDir);
105 |
106 | if (isResourcesDirExist) {
107 |
108 | // Remove 'resources/app' directory if it exists
109 | const resourcesAppDir = path.join(resourcesDir, 'app');
110 | const isResourcesAppDir = existsSync(resourcesAppDir);
111 |
112 | if (isResourcesAppDir) cleaner.removePath(resourcesAppDir);
113 |
114 | // Remove 'resources' directory if it's empty
115 | const isResourcesDirEmpty = Boolean(!readdirSync(resourcesDir).length);
116 | if (isResourcesDirEmpty) cleaner.removePath(resourcesDir);
117 | }
118 |
119 | console.log('Project is clean.');
120 | }
121 |
122 |
123 | /**
124 | * @description - Builds various installers (e.g., DMG, MSI).
125 | * @memberof Dispatcher
126 | */
127 | function packageApp() {
128 | const packager = new Packager();
129 |
130 | switch (command) {
131 | case 'linux':
132 | return packager.packageLinux();
133 |
134 | case 'mac':
135 | return packager.packageMacOS();
136 |
137 | case 'windows':
138 | return packager.packageWindows();
139 |
140 | // no default
141 | }
142 | }
143 |
144 |
145 | /**
146 | * @description - Starts developer mode of app.
147 | * Including; React, Electron, and Python/Flask.
148 | * @memberof Dispatcher
149 | */
150 | function startDeveloperMode() {
151 | const start = new Starter();
152 | start.developerMode();
153 | }
--------------------------------------------------------------------------------
/scripts/package.js:
--------------------------------------------------------------------------------
1 | const { spawnSync } = require('child_process');
2 | const { Builder } = require('./build');
3 |
4 | const builder = new Builder();
5 |
6 | // Define input and output directories
7 | const path = (directory) => {
8 | return require('path').resolve(__dirname, directory);
9 | };
10 |
11 | /**
12 | * @namespace Packager
13 | * @description - Packages app for various operating systems.
14 | */
15 | class Packager {
16 |
17 | /**
18 | * @description - Creates DEB installer for linux.
19 | * @memberof Packager
20 | *
21 | * @tutorial https://github.com/electron-userland/electron-installer-debian
22 | */
23 | packageLinux = () => {
24 |
25 | // Build Python & React distribution files
26 | builder.buildAll();
27 |
28 | const options = {
29 | build: [
30 | 'app',
31 | '--extra-resource=./resources',
32 | '--icon ./public/favicon.ico',
33 | '--platform linux',
34 | '--arch x64',
35 | '--out',
36 | './dist/linux',
37 | '--overwrite'
38 | ].join(' '),
39 |
40 | package: [
41 | `--src ${path('../dist/linux/app-linux-x64/')}`,
42 | 'electron-react-python-template',
43 | `--dest ${path('../dist/linux/setup')}`,
44 | '--arch amd64',
45 | `--icon ${path('../utilities/deb/images/icon.ico')}`,
46 | `--background ${path('../utilities/deb/images/background.png')}`,
47 | '--title "Example app"',
48 | '--overwrite'
49 | ].join(' '),
50 |
51 | spawn: { detached: false, shell: true, stdio: 'inherit' }
52 | };
53 |
54 | spawnSync(`electron-packager . ${options.build}`, options.spawn);
55 | spawnSync(`electron-installer-debian ${options.package}`, options.spawn);
56 | };
57 |
58 |
59 | /**
60 | * @description - Creates DMG installer for macOS.
61 | * @memberof Packager
62 | *
63 | * @tutorial https://github.com/electron-userland/electron-installer-dmg
64 | */
65 | packageMacOS = () => {
66 |
67 | // Build Python & React distribution files
68 | builder.buildAll();
69 |
70 | const options = {
71 | build: [
72 | 'app',
73 | '--extra-resource=./resources',
74 | '--icon ./public/favicon.ico',
75 | '--win32',
76 | '--out',
77 | './dist/mac',
78 | '--overwrite'
79 | ].join(' '),
80 |
81 | package: [
82 | path('../dist/mac/app-darwin-x64/app.app'),
83 | 'electron-react-python-template',
84 | `--out=${path('../dist/mac/setup')}`,
85 | `--icon=${path('../utilities/dmg/images/icon.icns')}`,
86 | `--background=${path('../utilities/dmg/images/background.png')}`,
87 | '--title="Example app"',
88 | '--overwrite'
89 | ].join(' '),
90 |
91 | spawn: { detached: false, shell: true, stdio: 'inherit' }
92 | };
93 |
94 | spawnSync(`electron-packager . ${options.build}`, options.spawn);
95 | spawnSync(`electron-installer-dmg ${options.package}`, options.spawn);
96 | };
97 |
98 |
99 | /**
100 | * @description - Creates MSI installer for Windows.
101 | * @memberof Packager
102 | *
103 | * @tutorial https://github.com/felixrieseberg/electron-wix-msi
104 | */
105 | packageWindows = () => {
106 |
107 | // eslint-disable-next-line no-console
108 | console.log('Building windows package...');
109 |
110 | // Build Python & React distribution files
111 | builder.buildAll();
112 |
113 | const options = {
114 | app: [
115 | 'app',
116 | '--asar',
117 | '--extra-resource=./resources/app',
118 | '--icon ./public/favicon.ico',
119 | '--win32',
120 | '--out',
121 | './dist/windows',
122 | '--overwrite'
123 | ].join(' '),
124 |
125 | spawn: { detached: false, shell: true, stdio: 'inherit' }
126 | };
127 |
128 | spawnSync(`electron-packager . ${options.app}`, options.spawn);
129 |
130 | const { MSICreator } = require('electron-wix-msi');
131 |
132 | const msiCreator = new MSICreator({
133 | appDirectory: path('../dist/windows/app-win32-x64'),
134 | appIconPath: path('../utilities/msi/images/icon.ico'),
135 | description: 'Example app',
136 | exe: 'app',
137 | manufacturer: 'Example Manufacturer',
138 | name: 'electron-react-python-template',
139 | outputDirectory: path('../dist/windows/setup'),
140 | ui: {
141 | chooseDirectory: true,
142 | images: {
143 | background: path('../utilities/msi/images/background.png'),
144 | banner: path('../utilities/msi/images/banner.png')
145 | }
146 | },
147 | version: '1.0.0'
148 | });
149 |
150 | // Customized MSI template
151 | msiCreator.wixTemplate = msiCreator.wixTemplate
152 | .replace(/ \(Machine - MSI\)/gi, '')
153 | .replace(/ \(Machine\)/gi, '');
154 |
155 |
156 | // Create .wxs template and compile MSI
157 | msiCreator.create().then(() => msiCreator.compile());
158 | };
159 |
160 | }
161 |
162 | module.exports.Packager = Packager;
--------------------------------------------------------------------------------
/scripts/start.js:
--------------------------------------------------------------------------------
1 | const { spawn, spawnSync } = require('child_process');
2 | const getPort = require('get-port');
3 | const { get } = require('axios');
4 |
5 | /**
6 | * @namespace Starter
7 | * @description - Scripts to start Electron, React, and Python.
8 | */
9 | class Starter {
10 | /**
11 | * @description - Starts developer mode.
12 | * @memberof Starter
13 | */
14 | developerMode = async () => {
15 | // Child spawn options for console
16 | const spawnOptions = {
17 | hideLogs: { detached: false, shell: true, stdio: 'pipe' },
18 | showLogs: { detached: false, shell: true, stdio: 'inherit' }
19 | };
20 |
21 | /**
22 | * Method to get first port in range of 3001-3999,
23 | * Remains unused here so will be the same as the
24 | * port used in main.js
25 | */
26 | const port = await getPort({
27 | port: getPort.makeRange(3001, 3999)
28 | });
29 |
30 | // Kill anything that might using required React port
31 | spawnSync('npx kill-port 3000', spawnOptions.hideLogs);
32 |
33 | // Start & identify React & Electron processes
34 | spawn('cross-env BROWSER=none react-scripts start', spawnOptions.showLogs);
35 | spawn('electron .', spawnOptions.showLogs);
36 |
37 | // Kill processes on exit
38 | const exitOnEvent = (event) => {
39 | process.once(event, () => {
40 | try {
41 | // These errors are expected since the connection is closing
42 | const expectedErrors = ['ECONNRESET', 'ECONNREFUSED'];
43 |
44 | // Send command to Flask server to quit and close
45 | get(`http://localhost:${port}/quit`).catch(
46 | (error) => !expectedErrors.includes(error.code) && console.log(error)
47 | );
48 | } catch (error) {
49 | // This errors is expected since the process is closing
50 | if (error.code !== 'ESRCH') console.error(error);
51 | }
52 | });
53 | };
54 |
55 | // Set exit event handlers
56 | [
57 | 'exit',
58 | 'SIGINT',
59 | 'SIGTERM',
60 | 'SIGUSR1',
61 | 'SIGUSR2',
62 | 'uncaughtException'
63 | ].forEach(exitOnEvent);
64 | };
65 | }
66 |
67 | module.exports = { Starter };
68 |
--------------------------------------------------------------------------------
/src/components/App.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment, useEffect } from 'react';
2 | import { get } from 'utils/requests';
3 |
4 | import { Counter } from 'components/counter/Counter';
5 | import Titlebar from 'components/titlebar/Titlebar';
6 |
7 | import logo from 'logo.svg';
8 | import styles from 'components/App.module.scss';
9 |
10 | function App() {
11 |
12 | useEffect(() => {
13 |
14 | /**
15 | * Example call to Flask
16 | * @see /src/utils/requests.js
17 | * @see /app.py
18 | */
19 | setTimeout(() => get(
20 | 'example', // Route
21 | (response) => alert(response), // Response callback
22 | (error) => console.error(error) // Error callback
23 | ), 3000);
24 | }, []);
25 |
26 | return (
27 |
28 |
29 |
30 |
82 |
83 | );
84 | }
85 |
86 | export default App;
87 |
--------------------------------------------------------------------------------
/src/components/App.module.scss:
--------------------------------------------------------------------------------
1 | .app {
2 | text-align: center;
3 | }
4 |
5 | .app-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .app-logo {
12 | animation: app-logo-float infinite 3s ease-in-out;
13 | }
14 | }
15 |
16 | .app-header {
17 | min-height: 100vh;
18 | display: flex;
19 | flex-direction: column;
20 | align-items: center;
21 | justify-content: center;
22 | font-size: calc(10px + 2vmin);
23 | }
24 |
25 | .app-link {
26 | color: rgb(112, 76, 182);
27 | }
28 |
29 | @keyframes app-logo-float {
30 | 0% {
31 | transform: translateY(0);
32 | }
33 | 50% {
34 | transform: translateY(10px)
35 | }
36 | 100% {
37 | transform: translateY(0px)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/counter/Counter.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import {
3 | decrement,
4 | increment,
5 | incrementAsync,
6 | incrementByAmount,
7 | selectCount
8 | } from 'components/counter/counterSlice';
9 | import { useDispatch, useSelector } from 'react-redux';
10 |
11 | import styles from 'components/counter/Counter.module.scss';
12 |
13 | export function Counter() {
14 | const count = useSelector(selectCount);
15 | const dispatch = useDispatch();
16 | const [incrementAmount, setIncrementAmount] = useState('2');
17 |
18 | return (
19 |
20 |
21 | dispatch(increment()) }
25 | >
26 | +
27 |
28 | {count}
29 | dispatch(decrement()) }
33 | >
34 | -
35 |
36 |
37 |
38 | setIncrementAmount(e.target.value) }
43 | />
44 |
47 | dispatch(incrementByAmount(Number(incrementAmount) || 0)) }
48 | >
49 | Add Amount
50 |
51 | dispatch(incrementAsync(Number(incrementAmount) || 0)) }
54 | >
55 | Add Async
56 |
57 |
58 |
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/src/components/counter/Counter.module.scss:
--------------------------------------------------------------------------------
1 | .row {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | }
6 |
7 | .row:not(:last-child) {
8 | margin-bottom: 16px;
9 | }
10 |
11 | .value {
12 | font-size: 78px;
13 | padding-left: 16px;
14 | padding-right: 16px;
15 | margin-top: 2px;
16 | font-family: 'Courier New', Courier, monospace;
17 | }
18 |
19 | .button {
20 | appearance: none;
21 | background: none;
22 | font-size: 32px;
23 | padding-left: 12px;
24 | padding-right: 12px;
25 | outline: none;
26 | border: 2px solid transparent;
27 | color: rgb(112, 76, 182);
28 | padding-bottom: 4px;
29 | cursor: pointer;
30 | background-color: rgba(112, 76, 182, 0.1);
31 | border-radius: 2px;
32 | transition: all 0.15s;
33 | }
34 |
35 | .textbox {
36 | font-size: 32px;
37 | padding: 2px;
38 | width: 64px;
39 | text-align: center;
40 | margin-right: 8px;
41 | }
42 |
43 | .button:hover, .button:focus {
44 | border: 2px solid rgba(112, 76, 182, 0.4);
45 | }
46 |
47 | .button:active {
48 | background-color: rgba(112, 76, 182, 0.2);
49 | }
50 |
51 | .asyncButton {
52 | composes: button;
53 | position: relative;
54 | margin-left: 8px;
55 | }
56 |
57 | .asyncButton:after {
58 | content: "";
59 | background-color: rgba(112, 76, 182, 0.15);
60 | display: block;
61 | position: absolute;
62 | width: 100%;
63 | height: 100%;
64 | left: 0;
65 | top: 0;
66 | opacity: 0;
67 | transition: width 1s linear, opacity 0.5s ease 1s;
68 | }
69 |
70 | .asyncButton:active:after {
71 | width: 0%;
72 | opacity: 1;
73 | transition: 0s
74 | }
75 |
--------------------------------------------------------------------------------
/src/components/counter/counterSlice.js:
--------------------------------------------------------------------------------
1 | import { createSlice } from '@reduxjs/toolkit';
2 |
3 | export const counterSlice = createSlice({
4 | name: 'counter',
5 | initialState: {
6 | value: 0
7 | },
8 | reducers: {
9 | increment: (state) => {
10 | // Redux Toolkit allows us to write "mutating" logic in reducers. It
11 | // doesn't actually mutate the state because it uses the Immer library,
12 | // which detects changes to a "draft state" and produces a brand new
13 | // immutable state based off those changes
14 | state.value += 1;
15 | },
16 | decrement: (state) => {
17 | state.value -= 1;
18 | },
19 | incrementByAmount: (state, action) => {
20 | state.value += action.payload;
21 | }
22 | }
23 | });
24 |
25 | export const { increment, decrement, incrementByAmount } = counterSlice.actions;
26 |
27 | // The function below is called a thunk and allows us to perform async logic. It
28 | // can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This
29 | // will call the thunk with the `dispatch` function as the first argument. Async
30 | // code can then be executed and other actions can be dispatched
31 | export const incrementAsync = (amount) => (dispatch) => {
32 | setTimeout(() => {
33 | dispatch(incrementByAmount(amount));
34 | }, 1000);
35 | };
36 |
37 | // The function below is called a selector and allows us to select a value from
38 | // the state. Selectors can also be defined inline where they're used instead of
39 | // in the slice file. For example: `useSelector((state) => state.counter.value)`
40 | export const selectCount = (state) => state.counter.value;
41 |
42 | export default counterSlice.reducer;
43 |
--------------------------------------------------------------------------------
/src/components/titlebar/Titlebar.js:
--------------------------------------------------------------------------------
1 | import {
2 | CloseButton,
3 | ContractButton,
4 | MaximizeButton,
5 | MinimizeButton
6 | } from 'components/titlebar/TitlebarButtons';
7 | import React, { useState } from 'react';
8 |
9 | import { app } from 'utils/services';
10 |
11 | import favicon from 'components/titlebar/img/favicon.png';
12 | import styles from 'components/titlebar/scss/Titlebar.module.scss';
13 |
14 |
15 | /**
16 | * @namespace Titlebar
17 | * @description Title Component to use as an Electron customized titlebar.
18 | * electron-window-title-text used in main.js to set opacity on/off focus.
19 | * electron-window-title-buttons used in main.js to set opacity on/off focus.
20 | */
21 |
22 | const Titlebar = () => {
23 |
24 | const [ maximized, setMaximized ] = useState(false);
25 |
26 | const handleMaximizeToggle = () => {
27 | !maximized ? app.maximize() : app.unmaximize();
28 | setMaximized(!maximized);
29 | };
30 |
31 | return (
32 |
33 |
34 |
35 |
{ document.title }
36 |
37 |
38 |
39 |
40 | {
41 | maximized
42 | ?
43 | :
44 | }
45 |
46 |
47 |
48 | );
49 | };
50 |
51 | export default Titlebar;
--------------------------------------------------------------------------------
/src/components/titlebar/TitlebarButtons.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import styles from 'components/titlebar/scss/TitlebarButtons.module.scss';
4 |
5 | /**
6 | * @description Titlebar minimize button.
7 | * @memberof Titlebar
8 | */
9 | export const MinimizeButton = (props) => (
10 |
17 |
18 |
19 | );
20 |
21 | /**
22 | * @description Titlebar maximize button.
23 | * @memberof Titlebar
24 | */
25 | export const MaximizeButton = (props) => (
26 |
33 |
34 |
35 | );
36 |
37 | /**
38 | * @description Titlebar contract (unmaximize) button.
39 | * @memberof Titlebar
40 | */
41 | export const ContractButton = (props) => (
42 |
49 |
50 |
51 |
52 | );
53 |
54 | /**
55 | * @description Titlebar close button.
56 | * @memberof Titlebar
57 | */
58 | export const CloseButton = (props) => (
59 |
66 |
67 |
68 |
69 | );
--------------------------------------------------------------------------------
/src/components/titlebar/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/src/components/titlebar/img/favicon.png
--------------------------------------------------------------------------------
/src/components/titlebar/scss/Titlebar.module.scss:
--------------------------------------------------------------------------------
1 | body section.titlebar {
2 | display: flex;
3 | justify-content: space-between;
4 | align-items: center;
5 | height: 32px;
6 | padding: 0;
7 | position: fixed;
8 | top: 0;
9 | left: 0;
10 | width: 100vw;
11 | max-width: 100vw;
12 | -webkit-user-select: none;
13 | -webkit-app-region: drag;
14 | background-color: #eaeaea;
15 |
16 | div {
17 | display: flex;
18 | align-items: center;
19 |
20 | span {
21 | font-size: 14px;
22 | font-family: 'Roboto', sans-serif;
23 | color: #252525;
24 | }
25 |
26 | img {
27 | width: 20px;
28 | padding: 5px;
29 | }
30 |
31 | }
32 | }
--------------------------------------------------------------------------------
/src/components/titlebar/scss/TitlebarButtons.module.scss:
--------------------------------------------------------------------------------
1 | .button {
2 | padding: 0 25px;
3 | -webkit-app-region: no-drag;
4 | color: #252525;
5 | border-radius: 0;
6 |
7 | &:hover {
8 | background-color: rgb(225, 225, 225);
9 | color: #252525;
10 | }
11 |
12 | &:last-child {
13 | &:hover {
14 | background-color: #ff0000;
15 | span {
16 | color: #f5f5f5;
17 | }
18 | }
19 | }
20 |
21 | span i {
22 | font-size: 12px;
23 | }
24 | }
25 |
26 | %button {
27 | -webkit-app-region: no-drag;
28 | border: none;
29 | background-color: transparent;
30 | height: 32px;
31 | width: 50px;
32 | cursor: pointer;
33 | display: flex;
34 | justify-content: center;
35 | align-items: center;
36 |
37 | &:hover {
38 | background-color: rgb(225, 225, 225);
39 | color: #252525;
40 | }
41 | }
42 |
43 | .minimize-button {
44 | @extend %button;
45 |
46 | span {
47 | width: 11px;
48 | border-top: solid 1px #252525;
49 | }
50 | }
51 |
52 | .maximize-button {
53 | @extend %button;
54 |
55 | span {
56 | width: 10px;
57 | height: 10px;
58 | border: solid 1px #252525;
59 | }
60 | }
61 |
62 | .contract-button {
63 | @extend %button;
64 |
65 | span {
66 | width: 7px;
67 | height: 7px;
68 | border: solid 1px #252525;
69 |
70 | &:first-child {
71 | margin-bottom: -4px;
72 | margin-right: -2.5px;
73 | background-color: #eaeaea;
74 | z-index: 2;
75 | }
76 |
77 | &:last-child {
78 | margin-top: -4px;
79 | margin-left: -2.5px;
80 | z-index: 1;
81 | }
82 | }
83 |
84 | &:hover {
85 | span:first-child {
86 | background-color: rgb(225, 225, 225);
87 | }
88 | }
89 | }
90 |
91 | .close-button {
92 | @extend %button;
93 |
94 | span {
95 | width: 15px;
96 | height: 1px;
97 | border-top: solid 1px #252525;
98 |
99 | &:first-child {
100 | transform: rotate(45deg);
101 | margin-right: -7px;
102 | }
103 |
104 | &:last-child {
105 | transform: rotate(-45deg);
106 | margin-left: -7px;
107 | }
108 | }
109 |
110 | &:hover {
111 | background-color: #ff0000;
112 | span {
113 | border-top: solid 2px #f5f5f5;
114 | }
115 | }
116 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import 'index.scss';
2 |
3 | import * as serviceWorker from 'serviceWorker';
4 |
5 | import App from 'components/App';
6 | import { Provider } from 'react-redux';
7 | import React from 'react';
8 | import ReactDOM from 'react-dom';
9 | import store from 'state/store';
10 |
11 | ReactDOM.render(
12 |
13 |
14 |
15 |
16 | ,
17 | document.getElementById('root')
18 | );
19 |
20 | // If you want your app to work offline and load faster, you can change
21 | // unregister() to register() below. Note this comes with some pitfalls.
22 | // Learn more about service workers: https://bit.ly/CRA-PWA
23 | serviceWorker.unregister();
24 |
--------------------------------------------------------------------------------
/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | overflow: hidden;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost'
15 | // [::1] is the IPv6 localhost address.
16 | || window.location.hostname === '[::1]'
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | || window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service '
46 | + 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then((registration) => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all '
74 | + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch((error) => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl, {
104 | headers: { 'Service-Worker': 'script' }
105 | })
106 | .then((response) => {
107 | // Ensure service worker exists, and that we really are getting a JS file.
108 | const contentType = response.headers.get('content-type');
109 | if (
110 | response.status === 404
111 | || (contentType != null && contentType.indexOf('javascript') === -1)
112 | ) {
113 | // No service worker found. Probably a different app. Reload the page.
114 | navigator.serviceWorker.ready.then((registration) => {
115 | registration.unregister().then(() => {
116 | window.location.reload();
117 | });
118 | });
119 | } else {
120 | // Service worker found. Proceed as normal.
121 | registerValidSW(swUrl, config);
122 | }
123 | })
124 | .catch(() => {
125 | console.log(
126 | 'No internet connection found. App is running in offline mode.'
127 | );
128 | });
129 | }
130 |
131 | export function unregister() {
132 | if ('serviceWorker' in navigator) {
133 | navigator.serviceWorker.ready.then((registration) => {
134 | registration.unregister();
135 | });
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/state/store.js:
--------------------------------------------------------------------------------
1 | import { configureStore } from '@reduxjs/toolkit';
2 | import counterReducer from 'components/counter/counterSlice';
3 |
4 | export default configureStore({
5 | reducer: {
6 | counter: counterReducer
7 | }
8 | });
9 |
--------------------------------------------------------------------------------
/src/tests/App.test.js:
--------------------------------------------------------------------------------
1 | import App from 'components/App';
2 | import { Provider } from 'react-redux';
3 | import React from 'react';
4 | import { render } from '@testing-library/react';
5 | import store from 'state/store';
6 |
7 | test('renders learn react link', () => {
8 | const { getByText } = render(
9 |
10 |
11 |
12 | );
13 |
14 | expect(getByText(/learn/i)).toBeInTheDocument();
15 | });
16 |
--------------------------------------------------------------------------------
/src/tests/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/src/theme/palette.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @namespace Theme
3 | * @description - Theme for Microsoft Fluent UI, which is built into the project.
4 | *
5 | * @tutorial - https://www.aka.ms/themedesigner
6 | */
7 |
8 | export const customTheme = {
9 | themePrimary: '#57a9a9',
10 | themeLighterAlt: '#030707',
11 | themeLighter: '#0e1b1b',
12 | themeLight: '#1a3232',
13 | themeTertiary: '#336565',
14 | themeSecondary: '#4c9494',
15 | themeDarkAlt: '#63b1b1',
16 | themeDark: '#77bdbd',
17 | themeDarker: '#96cece',
18 | neutralLighterAlt: '#eeeeee',
19 | neutralLighter: '#eaeaea',
20 | neutralLight: '#e1e1e1',
21 | neutralQuaternaryAlt: '#d1d1d1',
22 | neutralQuaternary: '#c8c8c8',
23 | neutralTertiaryAlt: '#c0c0c0',
24 | neutralTertiary: '#b5b5b5',
25 | neutralSecondary: '#9d9d9d',
26 | neutralPrimaryAlt: '#868686',
27 | neutralPrimary: '#252525',
28 | neutralDark: '#565656',
29 | black: '#3e3e3e',
30 | white: '#f5f5f5'
31 | };
--------------------------------------------------------------------------------
/src/theme/variables.scss:
--------------------------------------------------------------------------------
1 | $black: #252525;
2 | $grey: #565656;
--------------------------------------------------------------------------------
/src/utils/requests.js:
--------------------------------------------------------------------------------
1 | // Electron Inter Process Communication and dialog
2 | const { ipcRenderer } = window.require('electron');
3 |
4 | // Dynamically generated TCP (open) port between 3000-3999
5 | const port = ipcRenderer.sendSync('get-port-number');
6 |
7 | /**
8 | * @namespace Requests
9 | * @description - Helper functions for network requests (e.g., get, post, put, delete, etc..)
10 | */
11 |
12 | /**
13 | * @description - Helper GET method for sending requests to and from the Python/Flask services.
14 | * @param {string} route - Path of the Python/Flask service you want to use.
15 | * @param {Function} callback - Callback function which uses the returned data as an argument.
16 | * @return response data from Python/Flask service.
17 | * @memberof Requests
18 | */
19 | export const get = (route, callback, errorCallback) => {
20 | fetch(`http://localhost:${port}/${route}`)
21 | .then((response) => response.json())
22 | .then(callback)
23 | .catch((error) => (errorCallback ? errorCallback(error) : console.error(error)));
24 | };
25 |
26 |
27 | /**
28 | * @description - Helper POST method for sending requests to and from the Python/Flask services.
29 | * @param body - request body of data that you want to pass.
30 | * @param route - URL route of the Python/Flask service you want to use.
31 | * @param callback - optional callback function to be invoked if provided.
32 | * @return response data from Python/Flask service.
33 | * @memberof Requests
34 | */
35 | export const post = (
36 | body,
37 | route,
38 | callback,
39 | errorCallback
40 | ) => {
41 | fetch(`http://localhost:${port}/${route}`, {
42 | body,
43 | method: 'POST',
44 | headers: { 'Content-type': 'application/json' }
45 | })
46 | .then((response) => response.json())
47 | .then(callback)
48 | .catch((error) => (errorCallback ? errorCallback(error) : console.error(error)));
49 | };
--------------------------------------------------------------------------------
/src/utils/services.js:
--------------------------------------------------------------------------------
1 | // Electron Inter Process Communication and dialog
2 | const { ipcRenderer } = window.require('electron');
3 |
4 | /**
5 | * @namespace Services
6 | * @description - Methods from Electron Inter Process Communication.
7 | * @property {function} maximize - Function to maximize the screen size of the program.
8 | * @property {function} minimize - Function to minimize the screen size of the program.
9 | * @property {function} quit - Function to close and exit the program.
10 | * @property {function} unmaximize - Function to contract (unmaximize) the screen size of the program.
11 | */
12 | export const app = {
13 | maximize: () => ipcRenderer.send('app-maximize'),
14 | minimize: () => ipcRenderer.send('app-minimize'),
15 | quit: () => ipcRenderer.send('app-quit'),
16 | unmaximize: () => ipcRenderer.send('app-unmaximize')
17 | };
--------------------------------------------------------------------------------
/utilities/deb/images/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/deb/images/background.png
--------------------------------------------------------------------------------
/utilities/deb/images/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/deb/images/banner.png
--------------------------------------------------------------------------------
/utilities/deb/images/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/deb/images/icon.ico
--------------------------------------------------------------------------------
/utilities/dmg/images/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/dmg/images/background.png
--------------------------------------------------------------------------------
/utilities/dmg/images/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/dmg/images/icon.icns
--------------------------------------------------------------------------------
/utilities/jsdoc/LICENSE.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | Docdash is free software, licensed under the Apache License, Version 2.0 (the
4 | "License"). Commercial and non-commercial use are permitted in compliance with
5 | the License.
6 |
7 | Copyright (c) 2016 Clement Moron and the
8 | [contributors to docdash](https://github.com/clenemt/docdash/graphs/contributors).
9 | All rights reserved.
10 |
11 | You may obtain a copy of the License at:
12 | http://www.apache.org/licenses/LICENSE-2.0
13 |
14 | In addition, a copy of the License is included with this distribution.
15 |
16 | As stated in Section 7, "Disclaimer of Warranty," of the License:
17 |
18 | > Licensor provides the Work (and each Contributor provides its Contributions)
19 | > on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
20 | > express or implied, including, without limitation, any warranties or
21 | > conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
22 | > PARTICULAR PURPOSE. You are solely responsible for determining the
23 | > appropriateness of using or redistributing the Work and assume any risks
24 | > associated with Your exercise of permissions under this License.
25 |
26 | The source code for docdash is available at:
27 | https://github.com/clenemt/docdash
28 |
29 | # Third-Party Software
30 |
31 | Docdash includes or depends upon the following third-party software, either in
32 | whole or in part. Each third-party software package is provided under its own
33 | license.
34 |
35 | ## JSDoc 3
36 |
37 | JSDoc 3 is free software, licensed under the Apache License, Version 2.0 (the
38 | "License"). Commercial and non-commercial use are permitted in compliance with
39 | the License.
40 |
41 | Copyright (c) 2011-2016 Michael Mathews and the
42 | [contributors to JSDoc](https://github.com/jsdoc3/jsdoc/graphs/contributors).
43 | All rights reserved.
44 |
45 | You may obtain a copy of the License at:
46 | http://www.apache.org/licenses/LICENSE-2.0
47 |
48 | In addition, a copy of the License is included with this distribution.
49 |
50 | As stated in Section 7, "Disclaimer of Warranty," of the License:
51 |
52 | > Licensor provides the Work (and each Contributor provides its Contributions)
53 | > on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
54 | > express or implied, including, without limitation, any warranties or
55 | > conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
56 | > PARTICULAR PURPOSE. You are solely responsible for determining the
57 | > appropriateness of using or redistributing the Work and assume any risks
58 | > associated with Your exercise of permissions under this License.
59 |
60 | The source code for JSDoc 3 is available at:
61 | https://github.com/jsdoc3/jsdoc
62 |
--------------------------------------------------------------------------------
/utilities/jsdoc/README.md:
--------------------------------------------------------------------------------
1 | # daybrush-jsdoc-template
2 | [](https://www.npmjs.com/package/daybrush-jsdoc-template) [](LICENSE.md)
3 |
4 | **daybrush-jsdoc-template** is a template based on the [**docdash**](https://github.com/clenemt/docdash) template.
5 |
6 | * [Demo](http://daybrush.github.io/scenejs/release/latest/doc/)
7 |
8 | ## Install
9 |
10 | ```bash
11 | $ npm install daybrush-jsdoc-template
12 | ```
13 |
14 | ## Usage
15 | Clone repository to your designated `jsdoc` template directory, then:
16 |
17 | ```bash
18 | $ jsdoc entry-file.js -t path/to/daybrush-jsdoc-template
19 | ```
20 |
21 | ### scene.js
22 | ```bash
23 | $ jsdoc ./outjs ./README.md -d doc -t ./node_modules/daybrush-jsdoc-template
24 | ```
25 |
26 | ## Usage (npm)
27 | In your projects `package.json` file add a new script:
28 |
29 | ```json
30 | "script": {
31 | "generate-docs": "node_modules/.bin/jsdoc -c jsdoc.json"
32 | }
33 | ```
34 |
35 | In your `jsdoc.json` file, add a template option.
36 |
37 | ```json
38 | "opts": {
39 | "template": "node_modules/daybrush-jsdoc-template"
40 | }
41 | ```
42 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/base/chains.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @fileOverview The chains define the primary composition elements (functions) that determine the order of execution.
4 | *
5 | * @module base/chains
6 | * @requires dcl
7 | */
8 | var dcl = require( "dcl" );
9 | /**
10 | * @classDesc Chains define the primary composition elements (functions) that determine the order of execution.
11 | * @exports base/chains
12 | * @constructor
13 | */
14 | var Chains = dcl( null, {declaredClass : "base/chains"} );
15 | /**
16 | * The `close` method asks an object to shut itself down in a way that will allow it to be reopened, unlike the
17 | * [end method]{@link base/chains#end} which will call the destroy method which should make the object unusable, but also
18 | * devoid of all resources whereas `close` may still keep some resources open.
19 | *
20 | * | Heading 1 | Heading 2 | Heading 3 |
21 | * |-----------|-----------|-----------------|
22 | * | Bar | Food | This is a table |
23 | *
24 | * This uses the `before` chain which means the last one defined in the first one destroyed
25 | * @memberOf base/chains#
26 | * @name close
27 | * @see base/chains#open
28 | */
29 | dcl.chainBefore( Chains, "close" );
30 | /**
31 | * The `end` method will call the destroy method which should make the object unusable and
32 | * devoid of all resources, unlike the
33 | * [close method]{@link base/chains#close} asks an object to shut itself down in a way that will allow it to be reopened.
34 | *
35 | * This uses the `before` chain which means the last one defined in the first one destroyed
36 | * @memberOf base/chains#
37 | * @name end
38 | *
39 | * @example Add *this* to your application.properties.
40 | * {@lang bash}
41 | * foo=bar
42 | *
43 | */
44 | dcl.chainBefore( Chains, "end" );
45 | /**
46 | * Destroy is called by the end method and it is here that you should clean up after yourself. The difference between
47 | * `destroy` and [end]{@link base/chains#end} is the `end` is the verb that you raise on an object to ask it to go away
48 | * and `destroy` is where you actually do the work to clean up. Think of this as the counterpart of `constructor` yet
49 | * not called automatically.
50 | *
51 | * This uses the `before` chain which means the last one defined is the first one destroyed
52 | * @private
53 | * @memberOf base/chains#
54 | * @name destroy
55 | */
56 | dcl.chainBefore( Chains, "destroy" );
57 |
58 | /**
59 | * If you are using the open/close paradigm for an object that can kind of go dormant on {@link base/chains#close} and can be "reopened"
60 | * again later, here is where the "open" code will go.
61 | *
62 | * This used the `after` chain which means that the first one defined is the first one destroyed.
63 | *
64 | * @memberOf base/chains#
65 | * @name open
66 | * @see base/chains#close
67 | */
68 | dcl.chainAfter( Chains, "open" );
69 |
70 | module.exports = Chains;
71 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/base/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @fileOverview This is base definition for all composed classes defined by the system
4 | * @module base
5 | * @requires base/chains
6 | * @requires dcl
7 | */
8 |
9 | var dcl = require( "dcl" );
10 | var chains = require( "./chains" );
11 |
12 | /**
13 | * @classdesc The base of all classes in the system, this is one of the few pure "classes" in core the of the system. It is a
14 | * pretty clean little class whose primary purpose is to surface the composition chains and a basis for storing
15 | * options on mixin and subclass instances. Options are handled at the instance rather than the prototype level
16 | * so that multiple instances don't compete for default values.
17 | *
18 | * @exports base
19 | * @constructor
20 | * @extends base/chains
21 | */
22 | var Base = dcl( [chains], /** @lends base# */{
23 | declaredClass : "Base",
24 | /**
25 | * Add an option to a class. If any members of the hash already exist in `this.options`, they will be overwritten.
26 | * @param {hash} options A hash of options you want to set
27 | * @see {base#addDefaultOptions}
28 | */
29 | addOptions : function ( options ) {
30 | options = options || {};
31 | if ( this.options ) {options = sys.extend( {}, sys.result( this, 'options' ), options );}
32 | this.options = options;
33 | },
34 | /**
35 | * Add a default option to a class. The default options are only set if there is not already a
36 | * value for the option.
37 | * @param {hash} options A hash of options you want to set
38 | * @see {base#addOptions}
39 | */
40 | addDefaultOptions : function ( options ) {
41 | options = options || {};
42 | if ( this.options ) {options = sys.defaults( {}, sys.result( this, 'options' ), options );}
43 | this.options = options;
44 | },
45 |
46 | /**
47 | * Call this to close your object and dispose of all maintained resources. You can define this method on your
48 | * own classes without having to call the superclass instance, however it is reccomended that you put
49 | * all disposal code in `destroy()`. You must be disciplined about calling this on your instances.
50 | * @see {base/chains#end}
51 | * @see {base/chains#destroy}
52 | */
53 | end : function () {
54 | this.destroy()
55 | },
56 |
57 | /**
58 | * Called when it is time to get rid of all of your instance level references and objects and events. You can
59 | * define this method on your own classes without having to call the superclass instance. It is called by
60 | * `instance.end()` automatically
61 | * @see {base/chains#end}
62 | * @see {base/chains#destroy}
63 | */
64 | destroy : function () {
65 |
66 | }
67 |
68 |
69 | } );
70 |
71 | Base.compose = dcl;
72 | Base.mixin = dcl.mix;
73 | module.exports = Base;
74 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/documents/model.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @fileOverview A model is the first level if usable data-bearing entity in the system. It does NOT include any verbs for saving or anything like
4 | * that, it is a pure, in memory data container
5 | * @module documents/model
6 | * @require base
7 | * @require documents/probe
8 | * @require lodash
9 | */
10 |
11 | var Base = require( "../base" );
12 | var probe = require( "./probe" );
13 | var sys = require( "lodash" );
14 | /**
15 | * A model is the first level if usable data-bearing entity in the system. It does NOT include any verbs for saving or anything like
16 | * that, it is a pure, in memory data container
17 | * @exports documents/model
18 | * @constructor
19 | * @borrows module:documents/probe.get as get
20 | * @borrows module:documents/probe.set as set
21 | * @borrows module:documents/probe.any as any
22 | * @borrows module:documents/probe.all as all
23 | * @borrows module:documents/probe.remove as remove
24 | * @borrows module:documents/probe.seekKey as seekKey
25 | * @borrows module:documents/probe.seek as seek
26 | * @borrows module:documents/probe.findOne as findOne
27 | * @borrows module:documents/probe.findOneKey as findOneKey
28 | * @borrows module:documents/probe.findKeys as findKeys
29 | * @borrows module:documents/probe.find as find
30 | * @borrows module:documents/probe.update as update
31 | * @borrows module:documents/probe.some as some
32 | * @borrows module:documents/probe.every as every
33 | */
34 | var Model = Base.compose( [Base], /** @lends documents/model# */{
35 | constructor : function () {
36 | var that = this;
37 | probe.mixin( this );
38 |
39 | var idField = "_id";
40 | /**
41 | * The name of the field that uniquely identifies a record. When provided, some operations will take advantage of it
42 | *
43 | * @name _idField
44 | * @memberOf documents/model#
45 | * @type {string}
46 | * @private
47 | */
48 | Object.defineProperty( this, "_idField", {
49 | get : function () {
50 | return idField;
51 | },
52 | set : function ( val ) {
53 | idField = val;
54 | },
55 | configurable : false,
56 | enumerable : true,
57 | writable : true
58 | } );
59 |
60 | /**
61 | * The value of the primary key if {@link documents/model#_idField} is filled in. It will be null if none found
62 | *
63 | * @name _pkey
64 | * @memberOf documents/model#
65 | * @type {*}
66 | * @private
67 | */
68 | Object.defineProperty( this, "_pkey", {
69 | get : function () {
70 | var val;
71 | if ( !sys.isEmpty( that._idField ) ) {
72 | val = that[that._idField];
73 | }
74 | return val;
75 | },
76 | set : function ( val ) {
77 | if ( !sys.isEmpty( that._idField ) ) {
78 | that[that._idField] = val;
79 | }
80 | },
81 | configurable : false,
82 | enumerable : true,
83 | writable : true
84 | } );
85 |
86 | /**
87 | * If {@link documents/model#_idField} is filled in and it's value is empty this will be true.
88 | * @type {boolean}
89 | * @name isNew
90 | * @memberOf documents/model#
91 | */
92 | Object.defineProperty( this, "isNew", {
93 | get : function () {
94 | return !sys.isEmpty( that._idField ) && !sys.isEmpty( that[that._idField] )
95 | },
96 | configurable : false,
97 | enumerable : true,
98 | writable : false
99 | } );
100 |
101 | /**
102 | * Returns true if this instance is empty
103 | * @type {boolean}
104 | * @name isEmpty
105 | * @memberOf documents/model#
106 | */
107 | Object.defineProperty( this, "isEmpty", {
108 | get : function () {
109 | return sys.isEmpty( that );
110 | },
111 | configurable : false,
112 | enumerable : true,
113 | writable : false
114 | } );
115 | }
116 | } );
117 | module.exports = Model;
118 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/fixtures.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "tags": {
3 | "allowUnknownTags": true
4 | },
5 | "source": {
6 | "include": [
7 | "fixtures/",
8 | "./README.md"
9 | ]
10 | },
11 | "plugins": ["plugins/markdown"],
12 | "opts": {
13 | "encoding": "utf8",
14 | "template": "../",
15 | "destination": "../fixtures-doc/",
16 | "recurse": true,
17 | "verbose": true
18 | },
19 | "markdown": {
20 | "parser": "gfm",
21 | "hardwrap": true
22 | },
23 | "templates": {
24 | "cleverLinks": false,
25 | "monospaceLinks": false,
26 | "default": {
27 | "outputSourceFiles": true,
28 | "includeDate": false
29 | }
30 | },
31 | "docdash": {
32 | "static": false,
33 | "sort": true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/mixins/bussable.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @fileOverview Provides easy access to the system bus and provides some helper methods for doing so
4 | * @module mixins/bussable
5 | * @requires postal
6 | * @requires lodash
7 | * @requires base
8 | */
9 | var bus = require( "postal" );
10 | var Base = require( "../base" );
11 | var sys = require( "lodash" );
12 |
13 | /**
14 | * @classDesc Provides easy access to the system bus and provides some helper methods for doing so
15 | * @exports mixins/bussable
16 | * @mixin
17 | */
18 | var Bussable = Base.compose( [Base], /** @lends mixins/bussable# */{
19 | declaredClass : "mixins/Bussable",
20 | constructor : function () {
21 | /**
22 | * The list of subscriptions maintained by the mixin
23 | * @type {Array}
24 | * @memberof mixins/bussable#
25 | * @name _subscriptions
26 | * @private
27 | */
28 | this._subscriptions = {};
29 |
30 | this.log.trace( "Bussable constructor" );
31 | },
32 |
33 | /**
34 | * Subscribe to an event
35 | * @param {string} channel The channel to subscribe to
36 | * @param {string} topic The topic to subscribe to
37 | * @param {callback} callback What to do when you get the event
38 | * @returns {object} The subscription definition
39 | */
40 | subscribe : function ( channel, topic, callback ) {
41 | this.log.trace( "Bussable subscribe" );
42 | var sub = bus.subscribe( {channel : channel, topic : topic, callback : callback} );
43 | this.subscriptions[channel + "." + topic] = sub;
44 | return sub;
45 | },
46 |
47 | /**
48 | * Subscribe to an event once
49 | * @param {string} channel The channel to subscribe to
50 | * @param {string} topic The topic to subscribe to
51 | * @param {callback} callback What to do when you get the event
52 | * @returns {object} The subscription definition
53 | */
54 | once : function ( channel, topic, callback ) {
55 | this.log.trace( "Bussable once" );
56 | var sub = this.subscribe( channel, topic, callback );
57 | this.subscriptions[channel + "." + topic] = sub;
58 | sub.disposeAfter( 1 );
59 | return sub;
60 | },
61 |
62 | /**
63 | * Publish an event on the system bus
64 | * @param {string} channel The channel to publish to
65 | * @param {string} topic The topic to publish to
66 | * @param {object=} options What to pass to the event
67 | */
68 | publish : function ( channel, topic, options ) {
69 | this.log.trace( "Bussable publish" );
70 | bus.publish( {channel : channel, topic : topic, data : options} );
71 | },
72 |
73 | /**
74 | * Get a subscription definition
75 | *
76 | * @param {string} channel
77 | * @param {string} topic
78 | * @returns {object=} The subscription definition
79 | */
80 | getSubscription : function ( channel, topic ) {
81 | this.log.trace( "Bussable getSubscription" );
82 | return this.subscriptions[channel + "." + topic];
83 | },
84 |
85 | /**
86 | * Gets rid of all subscriptions for this object.
87 | * @private
88 | */
89 | destroy : function () {
90 | this.log.trace( "Bussable destroy" );
91 |
92 | sys.each( this.subscriptions, function ( sub ) {
93 | sub.unsubscribe();
94 | } );
95 | }
96 | } );
97 |
98 | module.exports = Bussable;
99 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/strings/format.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @fileOverview String helper methods
4 | *
5 | * @module strings/format
6 | */
7 |
8 | /**
9 | * Format a string quickly and easily using .net style format strings
10 | * @param {string} format A string format like "Hello {0}, now take off your {1}!"
11 | * @param {...?} args One argument per `{}` in the string, positionally replaced
12 | * @returns {string}
13 | *
14 | * @example
15 | * var strings = require("papyrus/strings");
16 | * var s = strings.format("Hello {0}", "Madame Vastra");
17 | * // s = "Hello Madame Vastra"
18 | *
19 | * @example {@lang xml}
20 | *
21 | * <%= strings.format("Hello {0}", "Madame Vastra") %>
22 | *
23 | */
24 | module.exports = function ( format ) {
25 | var args = Array.prototype.slice.call( arguments, 1 );
26 | return format.replace( /{(\d+)}/g, function ( match, number ) {
27 | return typeof args[number] != 'undefined'
28 | ? args[number]
29 | : match
30 | ;
31 | } );
32 | };
33 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/tutorials/Brush Teeth.md:
--------------------------------------------------------------------------------
1 | #Lorem ipsum dolor sit amet
2 |
3 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec viverra, tellus et fermentum tincidunt, massa ligula dignissim augue, ut aliquam tortor odio in odio. In faucibus metus metus. Curabitur est mi, fermentum lacinia tincidunt vitae, mattis sit amet neque. Quisque diam nisl, accumsan ac porta tincidunt, iaculis facilisis ipsum. Nulla facilisi. Aenean a metus tortor. Pellentesque congue, mauris vitae viverra varius, elit nunc dictum nisl, rhoncus ultrices nulla sapien at leo. Duis ultricies porttitor diam. Nulla facilisi. Nullam elementum, lorem eu imperdiet laoreet, est turpis sollicitudin velit, in porttitor justo dolor vel urna. Mauris in ante magna. Curabitur vitae lacus in magna mollis commodo.
4 |
5 | | Fusce lacinia | mauris ac aliquam | consequat | lacus urna feugiat erat | id viverra mi mi sit amet tortor |
6 | |---------------|-------------------|-------------|-------------------------------|---------------------------------------|
7 | | Etiam ac | 1 | 3 | 4.5 | 6.78910 |
8 | | Pellentesque e| 2 | 2 | 3 | 4 |
9 |
10 | neque lacus, quis posuere orci. Fusce molestie blandit velit, sit amet dictum eros pharetra vitae. In erat urna, condimentum ac feugiat id, rutrum et nisi. Cras ac velit lorem. Nulla facilisi. Maecenas dignissim nulla in turpis tempus sed rhoncus augue dapibus. Nulla feugiat, urna non sagittis laoreet, dolor metus rhoncus justo, sed semper ante lacus eget quam. Sed ac ligula magna. Sed tincidunt pulvinar neque in porta. Nullam quis lacus orci. Pellentesque ornare viverra lacus, id aliquam magna venenatis a.
11 |
12 | Sed id tristique lorem. Ut sodales turpis nec mauris gravida interdum. Cras pellentesque, purus at suscipit euismod, elit nunc cursus nisi, ut venenatis metus sapien id velit. Sed lectus orci, pharetra non pulvinar vel, ullamcorper id lorem. Donec vulputate tincidunt ipsum, ut lacinia tortor sollicitudin id. Nunc nec nibh ut felis venenatis egestas. Proin risus mauris, eleifend eget interdum in, venenatis sed velit. Praesent sodales elit ut odio viverra posuere. Donec sapien lorem, molestie in egestas eget, vulputate sed orci. Aenean elit sapien, pellentesque vitae tempor sit amet, sagittis et ligula. Mauris aliquam sapien sit amet lacus ultrices rutrum. Curabitur nec dolor sed elit varius dignissim a a lacus. Aliquam ac convallis enim.
13 |
14 | Suspendisse orci massa, hendrerit sagittis lacinia consectetur, sagittis vitae purus. Aliquam id eros diam, eget elementum turpis. Nullam tellus magna, mollis in molestie id, venenatis rhoncus est. Proin id diam justo. Nunc tempus gravida justo at lobortis. Nam vitae venenatis nisi. Donec vel odio massa. Quisque interdum metus sit amet est iaculis tincidunt. Donec bibendum blandit purus, id semper orci aliquam quis. Nam tincidunt dolor eu felis ultricies tempor. Nulla non consectetur erat.
15 |
16 | Nunc faucibus lacus eget odio ultricies nec ullamcorper risus pharetra. Nunc nec consequat urna. Curabitur condimentum ante vitae erat tristique vitae gravida quam dapibus. Cras ac justo dui, at faucibus urna. Nunc tristique, velit id feugiat fermentum, dolor enim egestas erat, at vestibulum ante ipsum vel orci. Duis quis ante id justo vehicula eleifend sed et urna. Sed sapien tortor, rutrum id ultrices eu, tincidunt tincidunt mi. Etiam blandit, neque eget interdum dignissim, lacus ante facilisis dolor, non viverra dui lorem vitae nibh. Morbi volutpat augue eget nulla luctus eu aliquam sem facilisis. Pellentesque sollicitudin commodo dolor sit amet vestibulum. Nam dictum posuere quam, in tincidunt erat rutrum eu.
17 |
18 | Etiam nec turpis purus, at lacinia sem. In commodo lacinia euismod. Curabitur tincidunt congue leo, eget iaculis orci volutpat pharetra. Fusce dignissim lacus lacus. Integer consectetur lacus rutrum risus malesuada at consectetur erat rutrum. Sed magna ipsum, fringilla eget auctor non, fringilla nec massa. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum nec tortor id nisi luctus aliquam. Maecenas cursus tincidunt ornare. Nulla a vestibulum odio. Mauris malesuada commodo justo quis mattis. Suspendisse mauris ligula, placerat at egestas in, tincidunt quis nibh. Aliquam ullamcorper elit at augue cursus quis pellentesque purus viverra.
19 |
20 | Nulla ultricies justo ac nisi consectetur posuere. Donec ornare pharetra erat, nec facilisis dui cursus quis. Quisque porttitor porttitor orci, sed facilisis urna facilisis sed. Sed tincidunt adipiscing turpis et hendrerit. Cras posuere orci ut mauris ullamcorper vitae laoreet nisi luctus. In rutrum tristique augue. Nam eleifend dignissim dui.
21 |
22 | Donec viverra egestas tellus non viverra. Aenean est ante, egestas sed scelerisque quis, aliquet sed lacus. Praesent non mauris neque, et adipiscing ante. Vestibulum quis quam vitae ipsum aliquet blandit. Vivamus condimentum euismod orci, in tincidunt justo rutrum faucibus. Phasellus nec lorem arcu. Donec tortor dui, facilisis in rutrum sit amet, pulvinar vitae lacus. Nam sodales sem eu nunc scelerisque vitae ullamcorper dolor facilisis. Duis imperdiet nisi in magna tempor convallis. Fusce at metus augue. Quisque dictum tempus mauris, in mattis ligula dignissim ut.
23 |
24 | Proin sodales, mi at tincidunt ornare, mi dui sagittis velit, sed dictum risus orci eu erat. Sed nunc leo, congue sed rutrum eget, lobortis ac lectus. Etiam non arcu nulla. Vestibulum rutrum dolor pulvinar lorem posuere blandit. Sed quis sapien dui. Nunc sagittis erat commodo quam porta cursus in non erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin a molestie neque. Aliquam iaculis lacus sed neque hendrerit at dignissim ligula imperdiet. Suspendisse venenatis, lorem at luctus scelerisque, sem purus pellentesque sapien, vitae ornare ipsum quam nec dui. Mauris neque est, interdum nec pulvinar eget, dapibus eleifend tellus. Fusce non lorem tortor. Nullam eget nunc quis felis aliquam consectetur. Aliquam tristique, turpis in feugiat blandit, lectus erat condimentum tortor, non egestas nisl sapien eget nibh.
25 |
26 | Aliquam elit turpis, faucibus et porta et, egestas nec nibh. Sed nisl est, pharetra a eleifend a, pretium ac eros. Sed leo eros, pulvinar vel faucibus dictum, aliquet ut quam. Maecenas et felis non ligula fringilla pretium fringilla sit amet ante. Nam varius imperdiet interdum. Ut non metus mauris, vel volutpat lorem. Nullam sagittis est quis lacus feugiat fringilla. Quisque orci lorem, semper ac accumsan vitae, blandit quis velit. Proin luctus sodales ultrices. Fusce mauris erat, facilisis ut consectetur at, fringilla feugiat orci. Aliquam a nisi a neque interdum suscipit id eget purus. Pellentesque tincidunt justo ut urna posuere non molestie quam auctor.
27 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/tutorials/Drive Car.md:
--------------------------------------------------------------------------------
1 | #Lorem ipsum dolor sit amet
2 |
3 | Curabitur est mi, fermentum lacinia tincidunt vitae, mattis sit amet neque. Quisque diam nisl, accumsan ac porta tincidunt, iaculis facilisis ipsum. Nulla facilisi. Aenean a metus tortor. Pellentesque congue, mauris vitae viverra varius, elit nunc dictum nisl, rhoncus ultrices nulla sapien at leo. Duis ultricies porttitor diam. Nulla facilisi. Nullam elementum, lorem eu imperdiet laoreet, est turpis sollicitudin velit, in porttitor justo dolor vel urna. Mauris in ante magna. Curabitur vitae lacus in magna mollis commodo.
4 |
5 | ##Fusce lacinia, mauris ac aliquam consequat
6 | Fusce molestie blandit velit, sit amet dictum eros pharetra vitae. In erat urna, condimentum ac feugiat id, rutrum et nisi. Cras ac velit lorem. Nulla facilisi. Maecenas dignissim nulla in turpis tempus sed rhoncus augue dapibus. Nulla feugiat, urna non sagittis laoreet, dolor metus rhoncus justo, sed semper ante lacus eget quam. Sed ac ligula magna. Sed tincidunt pulvinar neque in porta. Nullam quis lacus orci. Pellentesque ornare viverra lacus, id aliquam magna venenatis a.
7 |
8 | Sed id tristique lorem. Ut sodales turpis nec mauris gravida interdum. Cras pellentesque, purus at suscipit euismod, elit nunc cursus nisi, ut venenatis metus sapien id velit. Sed lectus orci, pharetra non pulvinar vel, ullamcorper id lorem. Donec vulputate tincidunt ipsum, ut lacinia tortor sollicitudin id. Nunc nec nibh ut felis venenatis egestas. Proin risus mauris, eleifend eget interdum in, venenatis sed velit. Praesent sodales elit ut odio viverra posuere. Donec sapien lorem, molestie in egestas eget, vulputate sed orci. Aenean elit sapien, pellentesque vitae tempor sit amet, sagittis et ligula. Mauris aliquam sapien sit amet lacus ultrices rutrum. Curabitur nec dolor sed elit varius dignissim a a lacus. Aliquam ac convallis enim.
9 |
10 | Suspendisse orci massa, hendrerit sagittis lacinia consectetur, sagittis vitae purus. Aliquam id eros diam, eget elementum turpis. Nullam tellus magna, mollis in molestie id, venenatis rhoncus est. Proin id diam justo. Nunc tempus gravida justo at lobortis. Nam vitae venenatis nisi. Donec vel odio massa. Quisque interdum metus sit amet est iaculis tincidunt. Donec bibendum blandit purus, id semper orci aliquam quis. Nam tincidunt dolor eu felis ultricies tempor. Nulla non consectetur erat.
11 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/tutorials/Fence Test.md:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur non libero tristique, interdum quam in, fermentum massa. Aenean vestibulum velit eu massa faucibus accumsan. Aenean tempus quam ornare ligula gravida adipiscing. Suspendisse vestibulum diam quis quam lacinia convallis. Nunc rhoncus a elit ut dictum. Maecenas porta mi et risus convallis commodo. In hac habitasse platea dictumst. Morbi placerat sem nec eleifend hendrerit. Donec hendrerit pulvinar tristique. Pellentesque at nunc blandit, fringilla elit nec, dignissim arcu. Quisque sit amet enim urna. Nunc adipiscing lacinia justo. Pellentesque euismod nisi id elit auctor porttitor. Phasellus rutrum viverra felis, ac cursus ante vulputate ut. Donec laoreet felis ac risus vulputate sodales.
2 |
3 | Mauris sit amet risus non ligula lacinia iaculis. Sed ornare tellus velit, vel elementum quam porttitor tempus. Duis vestibulum augue eu diam malesuada auctor. Maecenas dignissim odio ut elit fermentum, id mollis leo mattis. Phasellus posuere augue sed interdum vestibulum. Etiam ac pharetra est. Integer tortor ligula, pharetra ac nisi nec, faucibus laoreet dolor. Nunc vehicula, enim et cursus tincidunt, nulla purus mollis urna, vel ultricies nisl mi a risus. Vestibulum sed urna sodales, pretium nisi sed, pretium sapien. Vivamus et massa tincidunt, semper nibh nec, eleifend urna. Integer auctor, eros at pharetra blandit, erat nibh mattis turpis, rhoncus elementum nisi mi vitae purus.
4 |
5 | Quisque elementum sapien id neque volutpat cursus non mattis velit.
6 |
7 |
8 | ```
9 | $mod : function ( qu, value ) {
10 | var operands = sys.flatten( qu.operands );
11 | if ( operands.length !== 2 ) {
12 | throw new Error( "$mod requires two operands" );
13 | }
14 | var mod = operands[0];
15 | var rem = operands[1];
16 | return value % mod === rem;
17 | },
18 |
19 | ```
20 |
21 |
22 | ```
23 | {@lang bash}
24 | #!/bin/bash
25 | echo Please, enter your firstname and lastname
26 | read FN LN
27 | echo "Hi! $LN, $FN !"
28 | ```
29 |
30 | ```bash
31 | #!/bin/bash
32 | echo Please, enter your firstname and lastname
33 | read FN LN
34 | echo "Hi! $LN, $FN !"
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/utilities/jsdoc/fixtures/utils/logger.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @fileOverview The logging system for papyrus is based on [http://pimterry.github.io/loglevel/](loglevel) and slightly decorated
4 | * @module utils/logger
5 | * @requires dcl
6 | * @requires loglevel
7 | */
8 |
9 | var dcl = require( "dcl" );
10 | var log = require( 'loglevel' );
11 |
12 | /**
13 | * A logger class that you can mix into your classes to handle logging settings and state at an object level.
14 | * See {@link utils/logger} for the members of this class
15 | *
16 | * @exports utils/logger.Logger
17 | * @class
18 | * @see utils/logger
19 | */
20 | var Logger = dcl( null, /** @lends utils/logger.Logger# */{
21 | declaredClass : "utils/Logger",
22 |
23 | /**
24 | * Turn off all logging. If you log something, it will not error, but will not do anything either
25 | * and the cycles are minimal.
26 | *
27 | */
28 | silent : function () {
29 | log.disableAll();
30 | },
31 | /**
32 | * Turns on all logging levels
33 | *
34 | */
35 | all : function () {
36 | log.enableAll();
37 | },
38 | /**
39 | * Sets the logging level to one of `trace`, `debug`, `info`, `warn`, `error`.
40 | * @param {string} lvl The level to set it to. Can be one of `trace`, `debug`, `info`, `warn`, `error`.
41 | *
42 | */
43 | level : function ( lvl ) {
44 | if ( lvl.toLowerCase() === "none" ) {
45 | log.disableAll();
46 | } else {
47 | log.setLevel( lvl );
48 | }
49 | },
50 | /**
51 | * Log a `trace` call
52 | * @method
53 | * @param {string} The value to log
54 | */
55 | trace : log.trace,
56 | /**
57 | * Log a `debug` call
58 | * @method
59 | * @param {string} The value to log
60 | */
61 | debug : log.debug,
62 | /**
63 | * Log a `info` call
64 | * @method
65 | * @param {string} The value to log
66 | */
67 | info : log.info,
68 | /**
69 | * Log a `warn` call
70 | * @method
71 | * @param {string} The value to log
72 | */
73 | warn : log.warn,
74 | /**
75 | * Log a `error` call
76 | * @method
77 | * @param {string} The value to log
78 | */
79 | error : log.error
80 | } );
81 |
82 | module.exports = new Logger();
83 | /**
84 | * The system global, cross-platform logger
85 | * @name utils/logger
86 | * @static
87 | * @type {utils/logger.Logger}
88 | */
89 | module.exports.Logger = Logger;
90 |
--------------------------------------------------------------------------------
/utilities/jsdoc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "daybrush-jsdoc-template",
3 | "version": "1.6.0",
4 | "description": "A clean, responsive documentation template theme for JSDoc 3 inspired by lodash and minami",
5 | "main": "publish.js",
6 | "scripts": {
7 | "test": "jsdoc -c fixtures/fixtures.conf.json",
8 | "sync": "browser-sync start -s ../fixtures-doc -f ../fixtures-doc --reload-delay 1000 --no-ui --no-notify",
9 | "watch": "watch-run -d 1000 -p tmpl/**,static/** \"npm run test\""
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/daybrush/daybrush-jsdoc-template.git"
14 | },
15 | "devDependencies": {
16 | "jsdoc": "latest",
17 | "browser-sync": "latest",
18 | "watch-run": "latest"
19 | },
20 | "author": "Daybrush ",
21 | "license": "Apache-2.0",
22 | "keywords": [
23 | "jsdoc",
24 | "template",
25 | "tsdoc",
26 | "javascript",
27 | "typescript"
28 | ],
29 | "dependencies": {
30 | "@daybrush/utils": "^0.10.0"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/utilities/jsdoc/static/scripts/custom.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/jsdoc/static/scripts/custom.js
--------------------------------------------------------------------------------
/utilities/jsdoc/static/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | /*global document */
2 | (function() {
3 | var source = document.getElementsByClassName('prettyprint source linenums');
4 | var i = 0;
5 | var lineNumber = 0;
6 | var lineId;
7 | var lines;
8 | var totalLines;
9 | var anchorHash;
10 |
11 | if (source && source[0]) {
12 | anchorHash = document.location.hash.substring(1);
13 | lines = source[0].getElementsByTagName('li');
14 | totalLines = lines.length;
15 |
16 | for (; i < totalLines; i++) {
17 | lineNumber++;
18 | lineId = 'line' + lineNumber;
19 | lines[i].id = lineId;
20 | if (lineId === anchorHash) {
21 | lines[i].className += ' selected';
22 | }
23 | }
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/utilities/jsdoc/static/scripts/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/utilities/jsdoc/static/scripts/search.js:
--------------------------------------------------------------------------------
1 |
2 | (function () {
3 | var nav = document.querySelector("nav");
4 | var searchBar = nav.querySelector(".search");
5 | var input = searchBar.querySelector("input");
6 | // var submit = searchBar.querySelector("button");
7 | var groups = Array.prototype.slice.call(document.querySelectorAll("nav>ul .parent")).map(function (group) {
8 | var items = Array.prototype.slice.call(group.querySelectorAll("a"));
9 | var strings = items.map(function (a) {
10 | return a.innerText.toLowerCase();
11 | });
12 |
13 | return {el: group, items: items, strings, strings};
14 | });
15 | input.addEventListener("keyup", function (e) {
16 | var value = input.value.toLowerCase();
17 |
18 | if (value) {
19 | utils.addClass(nav, "searching");
20 | } else {
21 | utils.removeClass(nav, "searching");
22 | return;
23 | }
24 | groups.forEach(function (group) {
25 | var isSearch = false;
26 | var items = group.items;
27 |
28 | group.strings.forEach(function (v, i) {
29 | var item = items[i];
30 | if (utils.hasClass(item.parentNode, "parent")) {
31 | item = item.parentNode;
32 | }
33 | if (v.indexOf(value) > -1) {
34 | utils.addClass(item, "targeting");
35 | isSearch = true;
36 | } else {
37 | utils.removeClass(item, "targeting");
38 | }
39 | });
40 | if (isSearch) {
41 | utils.addClass(group.el, "module-targeting");
42 | } else {
43 | utils.removeClass(group.el, "module-targeting");
44 | }
45 | });
46 | });
47 | })();
--------------------------------------------------------------------------------
/utilities/jsdoc/static/scripts/utils.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2018 Daybrush
3 | @name: @daybrush/utils
4 | license: MIT
5 | author: Daybrush
6 | repository: https://github.com/daybrush/utils
7 | @version 0.4.0
8 | */
9 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.utils=t()}(this,function(){"use strict";var u="rgb",c="rgba",f="hsl",l="hsla",e=[u,c,f,l],t="function",n="object",r="string",i="undefined",a=typeof window!==i,o=["webkit","ms","moz","o"],s=function(e){if(typeof document===i)return"";var t=(document.body||document.documentElement).style,n=o.length;if(typeof t[e]!==i)return e;for(var r=0;rul>li:after {
14 | content: "";
15 | position: absolute;
16 | right: 10px;
17 | top: 0;
18 | bottom: 0;
19 | width: 0;
20 | height: 0;
21 | margin: auto 0px;
22 | border-top: 7px solid #ccc;
23 | border-left: 6px solid transparent;
24 | border-right: 6px solid transparent;
25 | }
26 | nav li h4, nav li ul {
27 | display: none;
28 | }
29 |
30 | .name.typescript {
31 | background: #374E79;
32 | font-size: 14px;
33 | }
34 | .name.typescript .signature {
35 | color: #21de60;
36 | }
37 | .ts-params.typescript table .last {
38 | display: none;
39 | }
40 | table.params th, table.params tr td , table.params tr td.type{
41 | word-break: break-word;
42 | white-space: normal;
43 | }
44 |
45 | nav .search {
46 | position: relative;
47 | margin: 0px 10px;
48 | border: 3px solid #333;
49 | height: 43px;
50 | }
51 | nav .search .input-area {
52 | position: absolute;
53 | left: 0;
54 | top: 0;
55 | right: 35px;
56 | height: 35px;
57 | }
58 | nav .search input {
59 | position: relative;
60 | width: 100%;
61 | height: 100%;
62 | border: 0;
63 | padding: 0;
64 | text-indent: 10px;
65 | font-weight: bold;
66 | font-size: 14px;
67 | outline: none;
68 | }
69 | nav .search button {
70 | position: absolute;
71 | top: 0;
72 | right: 0px;
73 | width: 35px;
74 | height: 35px;
75 | border: 0;
76 | padding: 0;
77 | outline: none;
78 | cursor: pointer;
79 | }
80 | nav .search button:before {
81 | position: absolute;
82 | content: "";
83 | width: 18px;
84 | height: 18px;
85 | top: 7px;
86 | left: 7px;
87 | border: 3px solid #333;
88 | border-radius: 50%;
89 | box-sizing: border-box;
90 | }
91 | nav .search button:after {
92 | position: absolute;
93 | content: "";
94 | width: 3px;
95 | height: 11px;
96 | top: 21px;
97 | left: 18px;
98 | background: #333;
99 | transform-origin: 50% 0%;
100 | -ms-transform-origin: 50% 0%;
101 | -webkit-transform-origin: 50% 0%;
102 | transform: rotate(-45deg);
103 | -ms-transform: rotate(-45deg);
104 | -webkit-transform: rotate(-45deg);
105 | }
106 |
107 | nav.searching li:after {
108 | display: none!important;
109 | }
110 | nav.searching li h4, nav.searching li ul {
111 | display: block!important;
112 | }
113 |
114 | nav.searching .parent {
115 | display: none;
116 | }
117 | nav.searching .parent ul li a {
118 | display: none;
119 | }
120 |
121 | nav.searching .parent.module-targeting {
122 | display: block;
123 | }
124 | nav.searching .parent.module-targeting ul li a {
125 | display: none;
126 | }
127 | nav.searching .parent.module-targeting ul li a.targeting {
128 | display: block;
129 | }
130 | nav.searching .parent.targeting ul li a {
131 | display: block;
132 | }
133 |
134 | nav>h2.custom>a {
135 | margin:12px 10px;
136 | }
--------------------------------------------------------------------------------
/utilities/jsdoc/static/styles/prettify.css:
--------------------------------------------------------------------------------
1 | .pln {
2 | color: #ddd;
3 | }
4 |
5 | /* string content */
6 | .str {
7 | color: #61ce3c;
8 | }
9 |
10 | /* a keyword */
11 | .kwd {
12 | color: #fbde2d;
13 | }
14 |
15 | /* a comment */
16 | .com {
17 | color: #aeaeae;
18 | }
19 |
20 | /* a type name */
21 | .typ {
22 | color: #8da6ce;
23 | }
24 |
25 | /* a literal value */
26 | .lit {
27 | color: #fbde2d;
28 | }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #ddd;
33 | }
34 |
35 | /* lisp open bracket */
36 | .opn {
37 | color: #000000;
38 | }
39 |
40 | /* lisp close bracket */
41 | .clo {
42 | color: #000000;
43 | }
44 |
45 | /* a markup tag name */
46 | .tag {
47 | color: #8da6ce;
48 | }
49 |
50 | /* a markup attribute name */
51 | .atn {
52 | color: #fbde2d;
53 | }
54 |
55 | /* a markup attribute value */
56 | .atv {
57 | color: #ddd;
58 | }
59 |
60 | /* a declaration */
61 | .dec {
62 | color: #EF5050;
63 | }
64 |
65 | /* a variable name */
66 | .var {
67 | color: #c82829;
68 | }
69 |
70 | /* a function name */
71 | .fun {
72 | color: #4271ae;
73 | }
74 |
75 | /* Specify class=linenums on a pre to get line numbering */
76 | ol.linenums {
77 | margin-top: 0;
78 | margin-bottom: 0;
79 | }
80 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/augments.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/container.tmpl:
--------------------------------------------------------------------------------
1 | 0) return;
7 | ?>
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
Example 1? 's':'' ?>
65 |
66 |
67 |
68 |
69 |
70 |
71 | Extends
72 |
73 |
74 |
75 |
76 |
77 | Requires
78 |
79 |
82 |
83 |
84 |
88 | Classes
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
100 | Mixins
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
112 | Namespaces
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
131 | Members
132 |
133 |
134 |
135 |
136 |
137 |
138 |
142 | Methods
143 |
144 |
145 |
146 |
147 |
148 |
149 |
153 | Type Definitions
154 |
155 |
158 |
159 |
163 |
164 |
167 |
168 |
169 |
173 | Events
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
206 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/details.tmpl:
--------------------------------------------------------------------------------
1 | " + data.defaultvalue + "
";
13 | defaultObjectClass = ' class="object-value"';
14 | }
15 | ?>
16 |
17 |
18 |
19 |
20 | Source:
21 |
24 |
25 |
26 |
27 | Version:
28 |
29 |
30 |
31 |
32 | Since:
33 |
34 |
35 |
36 |
37 | Inherited From:
38 |
41 |
42 |
43 |
44 | Overrides:
45 |
48 |
49 |
50 |
51 | Implementations:
52 |
57 |
58 |
59 |
60 | Implements:
61 |
66 |
67 |
68 |
69 | Mixes In:
70 |
71 |
76 |
77 |
78 |
79 | Deprecated:
83 |
84 |
85 |
86 | Author:
87 |
88 |
91 |
92 |
93 |
94 |
95 | Copyright:
96 |
97 |
98 |
99 |
100 | License:
101 |
102 |
103 |
104 |
105 | Default Value:
106 |
109 |
110 |
111 |
112 | Tutorials:
113 |
114 |
117 |
118 |
119 |
120 |
121 | See:
122 |
123 |
126 |
127 |
128 |
129 |
130 | To Do:
131 |
132 |
135 |
136 |
137 |
138 |
139 |
143 |
144 | Properties:
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/example.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/examples.tmpl:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/exceptions.tmpl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Type
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/layout.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - Documentation
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/mainpage.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/members.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Type:
21 |
26 |
27 |
28 |
29 | Fires:
30 |
33 |
34 |
35 |
36 | Example 1? 's':'' ?>
37 |
38 |
39 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/method.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | Constructor
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Extends:
28 |
29 |
30 |
31 |
32 | Type:
33 |
38 |
39 |
40 |
41 | This:
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
56 |
57 | ()
58 | → {}
59 |
60 |
61 |
62 |
63 |
67 |
68 |
69 | Example 1? 's':'' ?>
70 |
71 |
72 |
73 |
74 |
75 | Requires:
76 |
79 |
80 |
81 |
82 | Fires:
83 |
86 |
87 |
88 |
89 | Listens to Events:
90 |
93 |
94 |
95 |
96 | Listeners of This Event:
97 |
100 |
101 |
102 |
103 | Throws:
104 | 1) { ?>
110 |
111 |
113 |
114 |
115 | Returns:
116 | 1) { ?>
122 |
123 |
125 |
126 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/params.tmpl:
--------------------------------------------------------------------------------
1 |
52 |
53 |
54 |
55 |
56 |
57 | Name
58 |
59 |
60 | Type
61 |
62 |
63 | Attributes
64 |
65 |
66 |
67 | Default
68 |
69 |
70 | Description
71 |
72 |
73 |
74 |
75 |
80 |
81 |
82 |
83 |
?
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | <nullable>
97 |
98 |
99 |
100 | <repeatable>
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | Properties
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/properties.tmpl:
--------------------------------------------------------------------------------
1 |
41 |
42 |
43 |
44 |
45 |
46 | Name
47 |
48 |
49 | Type
50 |
51 |
52 | Attributes
53 |
54 |
55 |
56 | Default
57 |
58 |
59 | Description
60 |
61 |
62 |
63 |
64 |
69 |
70 |
71 |
72 |
?
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | <nullable>
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | Properties
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/returns.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Type
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/source.tmpl:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/tutorial.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 0) { ?>
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/utilities/jsdoc/tmpl/type.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 | |
7 |
--------------------------------------------------------------------------------
/utilities/loaders/react/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/utilities/loaders/react/assets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | min-height: 100vh;
3 | text-align: center;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | font-size: calc(10px + 2vmin);
9 | overflow: hidden;
10 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
11 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
12 | sans-serif;
13 | -webkit-font-smoothing: antialiased;
14 | -moz-osx-font-smoothing: grayscale;
15 | background-color: #252525;
16 | }
17 |
18 | .app-logo {
19 | height: 48vmin;
20 | pointer-events: none;
21 | animation-name: rotate;
22 | animation-duration: 15s;
23 | animation-iteration-count: infinite;
24 | animation-timing-function: linear;
25 | }
26 |
27 | .loading-header {
28 | margin-top: -10px;
29 | color: #6adefc;
30 | }
31 |
32 | @keyframes rotate {
33 | from {
34 | -webkit-transform: rotate(0deg);
35 | }
36 | to {
37 | -webkit-transform: rotate(360deg);
38 | }
39 | }
--------------------------------------------------------------------------------
/utilities/loaders/react/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Loading Screen
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/utilities/loaders/redux/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/utilities/loaders/redux/assets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | min-height: 100vh;
3 | text-align: center;
4 | display: flex;
5 | flex-direction: column;
6 | justify-content: center;
7 | align-items: center;
8 | font-size: calc(10px + 2vmin);
9 | overflow: hidden;
10 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
11 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
12 | sans-serif;
13 | -webkit-font-smoothing: antialiased;
14 | -moz-osx-font-smoothing: grayscale;
15 | }
16 |
17 | .app-logo {
18 | height: 40vmin;
19 | pointer-events: none;
20 | }
21 |
22 | .loading-header {
23 | color: rgb(112, 76, 182);
24 | }
25 |
26 | @media (prefers-reduced-motion: no-preference) {
27 | .app-logo {
28 | animation: app-logo-float infinite 3s ease-in-out;
29 | }
30 | }
31 |
32 | @keyframes app-logo-float {
33 | 0% {
34 | transform: translateY(0);
35 | }
36 | 50% {
37 | transform: translateY(10px)
38 | }
39 | 100% {
40 | transform: translateY(0px)
41 | }
42 | }
--------------------------------------------------------------------------------
/utilities/loaders/redux/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Loading Screen
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/utilities/msi/images/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/msi/images/background.png
--------------------------------------------------------------------------------
/utilities/msi/images/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/msi/images/banner.png
--------------------------------------------------------------------------------
/utilities/msi/images/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iPzard/electron-react-python-template/c78c0d0578bf6e6b0c96564fe7291ca6871d29ae/utilities/msi/images/icon.ico
--------------------------------------------------------------------------------