├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── index.js
├── jest.config.js
├── package.json
├── packages
└── TinyPagination
│ ├── index.js
│ └── src
│ └── main.vue
├── rollup.config.js
├── tests
└── unit
│ ├── .eslintrc.js
│ ├── TinyPagination.spec.js
│ └── __snapshots__
│ └── TinyPagination.spec.js.snap
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", { "modules": false }]
4 | ],
5 | "env": {
6 | "test": {
7 | "presets": [
8 | ["env", { "targets": { "node": "current" } }]
9 | ]
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/
2 | node_modules/
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true,
5 | },
6 | extends: [
7 | 'plugin:vue/essential',
8 | 'airbnb-base',
9 | ],
10 | rules: {
11 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
12 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
13 | },
14 | parserOptions: {
15 | parser: 'babel-eslint',
16 | },
17 | };
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Issue report
2 |
3 | ## Current behavior
4 |
5 |
6 | ## Input Code
7 |
8 | ```js
9 | const your = (code) => here;
10 | ```
11 |
12 | ## Expected behavior
13 |
14 |
15 | ## Posible solution
16 |
17 |
18 | ## Environment
19 |
20 | Plugin version: X.Y.Z
21 |
22 |
23 | For tooling issue:
24 | - Node version: XX
25 | - Platform:
26 |
27 | Others:
28 |
29 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## PR Checklist
2 | Please check if your PR fulfills the following requirements:
3 |
4 | - [ ] The commit message follows our guidelines: https://github.com/coderdiaz/vue-tiny-pagination/blob/master/CONTRIBUTING.md
5 | - [ ] Tests for the changes have been added (for bug fixes / features).
6 | - [ ] Docs have been added / updated (for bug fixes / features).
7 |
8 | ## PR Type
9 | What kind of change does this PR introduce?
10 |
11 |
12 | ```
13 | [ ] Bugfixes
14 | [ ] Feature
15 | [ ] Code style update (formatting, local variables)
16 | [ ] Refactoring (no functional changes, no api changes)
17 | [ ] Build related changes
18 | [ ] CI related changes
19 | [ ] Other... Please describe:
20 | ```
21 |
22 | ## What is the current behavior?
23 |
24 |
25 | ## What is the new behaviour?
26 |
27 | ## Does this PR introduce a breaking change?
28 | ```
29 | [ ] Yes
30 | [ ] No
31 | ```
32 |
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | coverage/
4 | yarn-error.log
5 | npm-debug.log
6 | .DS_Store
7 |
8 | # Editor directories
9 | .idea
10 | *.suo
11 | *.ntvs*
12 | *.njsproj
13 | *.sln
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 8
4 | - 10
5 | cache:
6 | yarn: true
7 | directories: node_modules
8 | install:
9 | - yarn
10 | script:
11 | - yarn test:unit
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contribute
2 | We would love for you to contribute and help make it even better than it is todat! As a contributor, here are the guidelines we would like you to follow:
3 |
4 | ## Development Setup
5 | You will need Node.js version +8.9.0.
6 | 1. After clonning the repo, run:
7 | ```bash
8 | $ npm i # or yarn install
9 | ```
10 |
11 | ### Commonly use NPM scripts
12 | ```bash
13 | # build all packages
14 | $ npm run build
15 |
16 | # run full unit-tests suite
17 | $ npm run test:unit
18 |
19 | # run linter
20 | $ npm run lint
21 | ```
22 |
23 | ## Found a Bug?
24 | If you find a bug in source code, you can help us by submitting an issue to our GitHub repository. Even better, you can submit a Pull Request with a fix.
25 |
26 | ## Missing a Feature?
27 | You can request a new feature by submitting an issue to our GitHub repository. If you would like to implement a new feature, please submit an issue with a proposal for your work first, to be sure that we can use it. Please consider what kind of change it is:
28 | - For a **Major Feature**, first open an issue and outline your proposal so that it can be discussed. This will also allow us to better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted in the project. For your issue name, please prefix your proposal with `[discussion]`, for example "[discussion]: your feature idea".
29 | - **Small Features** can be crafted and firectly submitted as a Pull Request.
30 |
31 | ## Coding Rules
32 | To ensure consistency throughout the source code, keep these rules in mind as you are working:
33 | - All feature or bug fixes **must be tested** by one or more specs (unit-tests).
34 | - We follow [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript), but wrap all code at **100 characters**.
35 |
36 | ## Commit Message Guidelines
37 | We have very precise rules over how our git commit messages can be formatted. This leads to **more readable messages** that are easy to follow when looking through the **project history**. But also, we use git commit messages to **generate the change log**.
38 |
39 | ### Type
40 | Must be one of the following:
41 | - **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm).
42 | - **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs).
43 | - **docs**: Documentation only changes.
44 | - **feature**: A new feature.
45 | - **bugfix**: A bug fix.
46 | - **refactor**: A code change that neither fixes a bug nor adds a feature.
47 | - **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc).
48 | - **test**: Adding missing tests or correcting existing tests.
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-2019 Javier Diaz Chamorro
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Tiny Pagination](https://github.com/coderdiaz/vue-tiny-pagination) · [](http://npmjs.com/package/vue-tiny-pagination) [](https://github.com/coderdiaz/vue-tiny-pagination/stargazers) [](https://travis-ci.org/coderdiaz/vue-tiny-pagination) [](https://npmjs.com/package/vue-tiny-pagination)
2 | A Vue component for create a tiny paginate with Flexbox
3 |
4 | ## Install/Usage
5 |
6 | ```sh
7 | # Install with npm
8 | $ npm i -S vue-tiny-pagination
9 |
10 | # or yarn
11 | $ yarn add vue-tiny-pagination
12 | ```
13 |
14 | ```html
15 |
16 |
19 |
20 | ```
21 |
22 | You can use **Local Registration**:
23 | ```js
24 | import { TinyPagination } from 'vue-tiny-pagination';
25 | new Vue({
26 | el: '#app',
27 | data() {
28 | return {
29 | currentTotal: 100,
30 | currentPage: 1,
31 | };
32 | },
33 | methods: {
34 | changePage (pagination) {
35 | this.currentPage = pagination.page;
36 | },
37 | },
38 | components: {
39 | TinyPagination,
40 | },
41 | });
42 | ```
43 |
44 | or **Global Registration**:
45 | ```js
46 | import TinyPagination from 'vue-tiny-pagination';
47 | Vue.use(TinyPagination);
48 |
49 | // or with a custom component name
50 | import { TinyPagination } from 'vue-tiny-pagination';
51 | Vue.component('custom-name', TinyPagination);
52 | ```
53 |
54 | ### Usage in browser
55 |
56 | In browser you can use Unpkg, Jsdelivr, CDN.js, etc.
57 | ```sh
58 | # Unpkg
59 | https://unpkg.com/vue-tiny-pagination@latest/dist/vue-tiny-pagination.js
60 |
61 | # JSDelivr
62 | https://cdn.jsdelivr.net/npm/vue-tiny-pagination@latest/dist/vue-tiny-pagination.min.js
63 | ```
64 |
65 | ## Documentation
66 |
67 | ### Props
68 | |Name|Description|Type|Default|Required|
69 | |---|---|---|---|---|
70 | |total|A number of total items|Number|-|true|
71 | |page|Prop to set a default page|Number|1|false|
72 | |lang|Default language to show (Available: en, es)|String|en|false|
73 | |customClass|Prop to set a custom class.|String|""|false|
74 | |limits|Prop to set a default limits to page sizes.|Array|[10, 15, 20,50,100]|false|
75 | |showLimit|Prop to disable the limit selector|Boolean|true|false|
76 |
77 | ### Events
78 | |Event|Description|
79 | |---|---|
80 | |tiny:change-page|Get the current page from pagination `payload: { page: 1 }`|
81 | |tiny:change-limit|Get the current limit from pagination `payload: { limit: 1 }`|
82 |
83 | ## Community
84 | All feedback and suggestions are welcome!
85 |
86 | ## License
87 | This is a open-source software licensed under the [MIT license](https://raw.githubusercontent.com/coderdiaz/vue-tiny-pagination/master/LICENSE)
88 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import TinyPagination from './packages/TinyPagination/index';
2 |
3 | const components = [
4 | TinyPagination,
5 | ];
6 |
7 | export function install(Vue) {
8 | if (install.installed) return;
9 | install.installed = true;
10 | components.forEach((component) => {
11 | Vue.component(component.name, component);
12 | });
13 | }
14 |
15 | const plugin = {
16 | install,
17 | };
18 |
19 | let GlobalVue = null;
20 | if (typeof window !== 'undefined') {
21 | GlobalVue = window.Vue;
22 | } else if (typeof global !== 'undefined') {
23 | GlobalVue = global.Vue;
24 | }
25 | if (GlobalVue) {
26 | GlobalVue.use(plugin);
27 | }
28 |
29 | export {
30 | TinyPagination,
31 | };
32 |
33 | export default plugin;
34 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | moduleFileExtensions: [
3 | 'js',
4 | 'jsx',
5 | 'json',
6 | 'vue',
7 | ],
8 | transform: {
9 | '.*\\.(vue)$': 'vue-jest',
10 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
11 | '^.+\\.js$': '/node_modules/babel-jest',
12 | },
13 | transformIgnorePatterns: [
14 | '/node_modules/',
15 | ],
16 | snapshotSerializers: [
17 | 'jest-serializer-vue',
18 | ],
19 | testMatch: [
20 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)',
21 | ],
22 | };
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-tiny-pagination",
3 | "version": "0.3.6",
4 | "description": "A Vue component for create a tiny pagination with Flexbox",
5 | "license": "MIT",
6 | "private": false,
7 | "plugin": {
8 | "name": "VueTinyPagination",
9 | "entryFile": "./index.js"
10 | },
11 | "author": {
12 | "name": "Javier Diaz Chamorro",
13 | "email": "hello@coderdiaz.me",
14 | "url": "https://github.com/coderdiaz"
15 | },
16 | "scripts": {
17 | "build": "rimraf dist && rollup -c --environment BUILD:production",
18 | "prepare": "yarn lint && yarn test:unit && yarn build",
19 | "lint": "eslint -c .eslintrc.js . --ext .js,.vue",
20 | "test:unit": "jest -c"
21 | },
22 | "style": "dist/vue-tiny-pagination.css",
23 | "main": "dist/vue-tiny-pagination.cjs.js",
24 | "module": "dist/vue-tiny-pagination.esm.js",
25 | "unpkg": "dist/vue-tiny-pagination.js",
26 | "jsdelivr": "dist/vue-tiny-pagination.js",
27 | "cdn": "dist/vue-tiny-pagination.js",
28 | "files": [
29 | "dist"
30 | ],
31 | "repository": {
32 | "type": "git",
33 | "url": "git+https://github.com/coderdiaz/vue-tiny-pagination.git"
34 | },
35 | "bugs": {
36 | "url": "https://github.com/coderdiaz/vue-tiny-pagination/issues"
37 | },
38 | "keywords": [
39 | "vue",
40 | "vuejs",
41 | "vue-component",
42 | "component",
43 | "vue.js",
44 | "pagination",
45 | "paginate",
46 | "tiny-paginate",
47 | "tiny",
48 | "small",
49 | "vue-paginate"
50 | ],
51 | "devDependencies": {
52 | "@vue/test-utils": "^1.0.0-beta.29",
53 | "babel-core": "^6.26.3",
54 | "babel-eslint": "^10.0.2",
55 | "babel-jest": "^24.8.0",
56 | "babel-preset-env": "^1.7.0",
57 | "eslint": "^6.0.1",
58 | "eslint-config-airbnb-base": "^13.2.0",
59 | "eslint-plugin-import": "^2.18.0",
60 | "eslint-plugin-vue": "^5.2.3",
61 | "jest": "^24.8.0",
62 | "jest-serializer-vue": "^2.0.2",
63 | "jest-transform-stub": "^2.0.0",
64 | "rimraf": "^2.6.3",
65 | "rollup": "^1.16.3",
66 | "rollup-plugin-commonjs": "^10.0.1",
67 | "rollup-plugin-css-only": "^1.0.0",
68 | "rollup-plugin-node-resolve": "^5.2.0",
69 | "rollup-plugin-terser": "^5.0.0",
70 | "rollup-plugin-vue": "^5.0.1",
71 | "vue-jest": "^3.0.4",
72 | "vue-template-compiler": "^2.6.10"
73 | },
74 | "dependencies": {
75 | "vue": "^2.6.10"
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/packages/TinyPagination/index.js:
--------------------------------------------------------------------------------
1 | import TinyPagination from './src/main.vue';
2 |
3 | TinyPagination.install = (Vue) => {
4 | Vue.component(TinyPagination.name, TinyPagination);
5 | };
6 |
7 | export default TinyPagination;
8 |
--------------------------------------------------------------------------------
/packages/TinyPagination/src/main.vue:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
131 |
221 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import vue from 'rollup-plugin-vue';
2 | import commonjs from 'rollup-plugin-commonjs';
3 | import resolve from 'rollup-plugin-node-resolve';
4 | import { terser } from 'rollup-plugin-terser';
5 | import css from 'rollup-plugin-css-only';
6 | import pckg from './package.json';
7 |
8 | // Dynamic module config
9 | const inputFile = pckg.plugin.entryFile;
10 | const BrowserNamePackage = pckg.plugin.name;
11 | const ModuleNamePackage = pckg.name;
12 |
13 | const config = [
14 | // ESM build to be used with webpack/rollup.
15 | {
16 | input: inputFile,
17 | output: {
18 | format: 'esm',
19 | exports: 'named',
20 | name: ModuleNamePackage,
21 | file: `dist/${ModuleNamePackage}.esm.js`,
22 | },
23 | plugins: [
24 | resolve({
25 | extensions: ['.js', '.vue'],
26 | }),
27 | commonjs(),
28 | vue(),
29 | ],
30 | },
31 | // Common Js
32 | {
33 | input: inputFile,
34 | output: {
35 | format: 'cjs',
36 | exports: 'named',
37 | name: ModuleNamePackage,
38 | file: `dist/${ModuleNamePackage}.cjs.js`,
39 | },
40 | plugins: [
41 | resolve({
42 | extensions: ['.js', '.vue'],
43 | }),
44 | commonjs(),
45 | vue(),
46 | ],
47 | },
48 | // SSR Build
49 | {
50 | input: inputFile,
51 | output: {
52 | format: 'cjs',
53 | exports: 'named',
54 | name: ModuleNamePackage,
55 | file: `dist/${ModuleNamePackage}.ssr.js`,
56 | },
57 | plugins: [
58 | resolve({
59 | extensions: ['.js', '.vue'],
60 | }),
61 | commonjs(),
62 | vue({ template: { optimizeSSR: true } }),
63 | ],
64 | },
65 | // Browser build
66 | {
67 | input: inputFile,
68 | output: {
69 | format: 'iife',
70 | exports: 'named',
71 | name: BrowserNamePackage,
72 | file: `dist/${ModuleNamePackage}.js`,
73 | },
74 | plugins: [
75 | resolve({
76 | extensions: ['.js', '.vue'],
77 | }),
78 | commonjs(),
79 | css(),
80 | vue({ css: false }),
81 | terser(),
82 | ],
83 | },
84 | ];
85 |
86 | export default config;
87 |
--------------------------------------------------------------------------------
/tests/unit/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | jest: true,
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/tests/unit/TinyPagination.spec.js:
--------------------------------------------------------------------------------
1 | import { shallowMount } from '@vue/test-utils';
2 | import TinyPagination from '../../packages/TinyPagination/src/main.vue';
3 |
4 | const vm = shallowMount(TinyPagination, {
5 | propsData: {
6 | total: 100,
7 | },
8 | });
9 |
10 | // Helper function to create a component
11 | const createComponent = propsData => shallowMount(TinyPagination, { propsData });
12 |
13 | describe('TinyPagination.vue', () => {
14 | let cmp;
15 | it('has a created hook', () => {
16 | expect(typeof TinyPagination.created).toBe('function');
17 | });
18 |
19 | it('should match the snapshot', () => {
20 | expect(vm.$el).toMatchSnapshot();
21 | });
22 |
23 | describe('Properties', () => {
24 | it('when the component is created without page prop, Page 1 is the page by default', () => {
25 | cmp = createComponent({ total: 300 });
26 | expect(cmp.vm.page).toBe(1);
27 | });
28 |
29 | it('when the page property is set, the currentPage is equals', () => {
30 | cmp = createComponent({ total: 300, page: 2 });
31 | expect(cmp.vm.currentPage).toBe(2);
32 | });
33 |
34 | it('when the component is created, English is the language by default', () => {
35 | cmp = createComponent({ total: 300 });
36 | expect(cmp.vm.lang).toBe('en');
37 | expect(cmp.vm.translation.title).toBe('Page');
38 | });
39 |
40 | it('when the lang prop is set to spanish, the component is translated', () => {
41 | cmp = createComponent({ total: 300, lang: 'es' });
42 | expect(cmp.vm.lang).toBe('es');
43 | expect(cmp.vm.translation.title).toBe('Página');
44 | });
45 |
46 | it('when the lang prop is set to not available language, English is the language by default', () => {
47 | cmp = createComponent({ total: 300, lang: 'fr' });
48 | expect(cmp.vm.translation.title).toBe('Page');
49 | });
50 |
51 | it('when the show limit is not set, true is by default', () => {
52 | cmp = createComponent({ total: 100 });
53 | expect(cmp.vm.showLimit).toBe(true);
54 | });
55 |
56 | it('when the showLimit is set, prop is same', () => {
57 | const showLimit = true;
58 | cmp = createComponent({ total: 100, showLimit });
59 | expect(cmp.vm.showLimit).toBe(showLimit);
60 | });
61 | });
62 |
63 | // describe('Watchers', () => {
64 | // it('currentPage watcher is called with the new value', () => {
65 | // cmp = createComponent({ total: 100 });
66 | // cmp.setData({ currentPage: 3 });
67 | // expect(cmp.emitted()['tiny:change-page']).toBeTruthy();
68 | // });
69 |
70 | // it('currentLimit watcher is called with the new value', () => {
71 | // cmp = createComponent({ total: 200 });
72 | // cmp.setData({ currentLimit: 20 });
73 | // expect(cmp.emitted()['tiny:change-limit']).toBeTruthy();
74 | // });
75 |
76 | // it('when the currentPage watcher is called, the tiny:change-page event is emitted', () => {
77 | // const stub = jest.fn();
78 | // cmp = createComponent({ total: 100 });
79 | // cmp.vm.$on('tiny:change-page', stub);
80 |
81 | // cmp.setData({ currentPage: 3 });
82 | // expect(stub).toBeCalledWith({ page: 3 });
83 | // });
84 |
85 | // it('when the currentLimit watcher is called, the tiny:change-limit event is emitted', () => {
86 | // const stub = jest.fn();
87 | // cmp = createComponent({ total: 100 });
88 | // cmp.vm.$on('tiny:change-limit', stub);
89 |
90 | // cmp.setData({ currentLimit: 20 });
91 | // expect(stub).toBeCalledWith({ limit: 20 });
92 | // });
93 | // });
94 |
95 | describe('Events', () => {
96 | beforeEach(() => {
97 | cmp = createComponent({ total: 20 });
98 | });
99 |
100 | it('calls nextPage when click on next button', () => {
101 | cmp.vm.nextPage = jest.fn();
102 |
103 | cmp.find('.btn-next-page').trigger('click');
104 | expect(cmp.vm.nextPage).toBeCalled();
105 | });
106 |
107 | it('call lastPage when click on prev button', () => {
108 | cmp.vm.lastPage = jest.fn();
109 |
110 | cmp.find('.btn-prev-page').trigger('click');
111 | expect(cmp.vm.lastPage).toBeCalled();
112 | });
113 | });
114 | });
115 |
--------------------------------------------------------------------------------
/tests/unit/__snapshots__/TinyPagination.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`TinyPagination.vue should match the snapshot 1`] = `undefined`;
4 |
--------------------------------------------------------------------------------