Full Code of baianat/vuse for AI

master e6678f2f6ba8 cached
64 files
185.6 KB
60.1k tokens
58 symbols
1 requests
Download .txt
Showing preview only (201K chars total). Download the full file or copy to clipboard to get everything.
Repository: baianat/vuse
Branch: master
Commit: e6678f2f6ba8
Files: 64
Total size: 185.6 KB

Directory structure:
gitextract_7xlm9eti/

├── .babelrc
├── .eslintrc.json
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── demo/
│   ├── App.vue
│   ├── Uploader.vue
│   ├── app.js
│   ├── index.html
│   ├── render.html
│   ├── sections/
│   │   ├── forms/
│   │   │   └── newsletter.vue
│   │   ├── hero/
│   │   │   ├── hero1.vue
│   │   │   └── hero2.vue
│   │   ├── section/
│   │   │   ├── section1.vue
│   │   │   └── section2.vue
│   │   └── social/
│   │       ├── social1.vue
│   │       ├── social2.vue
│   │       ├── social3.vue
│   │       └── social4.vue
│   ├── style/
│   │   ├── _demo.styl
│   │   ├── colors.styl
│   │   ├── header.styl
│   │   ├── helper.styl
│   │   ├── main.styl
│   │   ├── scrolling.styl
│   │   ├── section.styl
│   │   ├── social.styl
│   │   ├── transition.styl
│   │   ├── user.styl
│   │   └── variables.styl
│   └── webpack.config.js
├── docs/
│   ├── .vuepress/
│   │   ├── config.js
│   │   ├── enhanceApp.js
│   │   └── public/
│   │       └── style.css
│   ├── API.md
│   ├── README.md
│   ├── example.md
│   ├── exporting.md
│   ├── getting-started.md
│   ├── section.md
│   └── styler.md
├── package.json
├── scripts/
│   ├── build.js
│   ├── config.js
│   └── deploy.sh
└── src/
    ├── components/
    │   ├── VuseBuilder.vue
    │   ├── VuseIcon.js
    │   ├── VuseRenderer.vue
    │   └── VuseStyler.vue
    ├── index.esm.js
    ├── index.js
    ├── mixin.js
    ├── plugins/
    │   ├── pwa.js
    │   └── scrolling.js
    ├── section.js
    ├── seeder.js
    ├── styler.js
    ├── stylus/
    │   ├── _app.styl
    │   ├── colors.styl
    │   └── variables.styl
    ├── types.js
    ├── util.js
    └── vuse.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": [
    ["@babel/preset-env", { "modules": false }]
  ],
  "env": {
    "test": {
      "presets": [
        ["@babel/preset-env", { "targets": { "node": "current" }}]
      ]
    }
  }
}

================================================
FILE: .eslintrc.json
================================================
{
    "extends": [
        "standard",
        "plugin:vue/recommended"
    ],

    "rules": {
        "semi": "off",
        "no-new": "off",
        "vue/valid-template-root": "off"
    }
}

================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Dependency directories
node_modules/
jspm_packages/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# visual studio code
.vscode

# macOS custom Icon
Icon/

# vuepress output
docs/.vuepress/dist

# dist folders
dist

================================================
FILE: .npmignore
================================================
/docs
/dev
/src
/static
/scripts
.*
yarn.lock

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 Baianat

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Vuse

<p align="center">
  <a href="https://github.com/baianat/vuse" target="_blank">
    <img width="450" src="https://github.com/baianat/vuse/blob/master/Logo/Vuse_Logo_Horizontal_Gradient.png">
  </a>
</p>

> Logo by [chimzycash](https://github.com/chimzycash)

**WIP: Vuse active development is now halted.**

Advanced page/email builder based on [Vue.js](https://vuejs.org/).

[documentation](https://baianat.github.io/vuse/)

## Credits

- Logo by [chimzycash](https://github.com/chimzycash).

## License

MIT


================================================
FILE: demo/App.vue
================================================
<template>
  <VuseBuilder @saved="onSave" />
</template>

<script>
export default {
  name: 'App',
  methods: {
    onSave (vuse) {
      vuse.export('preview');
      vuse.export('pwa');
    }
  }
}
</script>


================================================
FILE: demo/Uploader.vue
================================================
<template lang="pug">
  div.uploader
    img(:src="src")
    input.uploader-input(
      type="file"
      ref="uploader"
      @change="updateImage"
      v-if="$builder.isEditing && mode === 'input'"
    )
</template>

<script>
export default {
  name: 'Uploader',
  inject: ['$builder', '$section'],
  props: {
    path: {
      type: String,
      required: true
    },
    mode: {
      default: 'input',
      type: String
    }
  },
  data: () => ({
    src: ''
  }),
  created () {
    this.src = this.$section.get(this.path);
  },
  methods: {
    updateImage () {
      const file = this.$refs.uploader.files[0];
      if (!file) return;
      const imageURL = URL.createObjectURL(file);

      this.src = imageURL;
      this.$section.set(this.path, imageURL);
    }
  }
}
</script>

<style lang="stylus">
@import '../src/stylus/_app.styl'

.uploader
  position: relative
  cursor: pointer
  outline: none
  &-input
    position: absolute
    top: 0
    right: 0
    bottom: 0
    left: 0
    width: 100%
    opacity: 0
    z-index: 100
    cursor: pointer
  >img
    width: 100%
    display: block
  &:hover
    box-shadow: 0 0 0 2px $gray
</style>


================================================
FILE: demo/app.js
================================================
// Vuse scripts
import Vue from 'vue';
import pwa from '../src/plugins/pwa';
import Vuse from '../src';

// demo scripts
import './style/_demo.styl';
import App from './App.vue';
import Uploader from './Uploader'
import hero1 from './sections/hero/hero1';
import hero2 from './sections/hero/hero2';
import section1 from './sections/section/section1';
import section2 from './sections/section/section2';
import social1 from './sections/social/social1';
import social2 from './sections/social/social2';
import social3 from './sections/social/social3';
import social4 from './sections/social/social4';
import newsletter from './sections/forms/newsletter';

// add the uploader to the list of sub-components.
Vuse.mix({
  components: {
    Uploader
  }
});

// register components.
Vuse.component(hero1);
Vuse.component(hero2);
Vuse.component(section1);
Vuse.component(section2);
Vuse.component(social1);
Vuse.component(social2);
Vuse.component(social3);
Vuse.component(social4);
Vuse.component(newsletter);

// install pwa plugin.
Vuse.use(pwa);

// install the builder
Vue.use(Vuse, {
  // main css file
  assets: {
    css: 'css/style.css'
  },
  // builder default themes
  themes: [{
    name: 'Theme 1',
    sections: [hero1, section1, social1, social3, newsletter]
  }, {
    name: 'Theme 2',
    sections: [hero2, section2, social3, social4, newsletter]
  }]
});

new Vue({
  el: '#app',
  render: h => h(App)
});


================================================
FILE: demo/index.html
================================================
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
    <title>Vuse</title>
  </head>
  <body>
    <div id="app">
    </div>
  </body>
</html>


================================================
FILE: demo/render.html
================================================
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Vuse</title>
  </head>

  <body>
    <div id="app">
      <VuseRenderer :data="{ title: 'My title', sections: [{ name: 'social2', data: { classes: ['is-dark'], content: 'This is my content yo!', images: ['static/img/avatar.png'] } },{ name: 'social2', data: { classes: ['is-red'], content: 'This is my content yo boi!', images: ['static/img/avatar.png'] } }] }"></VuseRenderer>
    </div>
  </body>
</html>

================================================
FILE: demo/sections/forms/newsletter.vue
================================================
<template lang="pug">
  section.header(
    v-styler:section="$sectionData.classes"
    :class="$sectionData.classes"
  )
    .container
      .grid.is-center
        .row
          h3.header-title Sign up for our newsletter

        form.row(@submit.prevent="onSubmit")
          .column.is-desktop-4
            .input-group.has-itemAfter
              input.input(type="text" name="email" placeholder="Email address" v-model="$sectionData.form.email")
              a.button(
                @click.prevent="onSubmit"
                :class="$sectionData.action.classes"
                :href="$sectionData.action.href"
                v-html="$sectionData.action.text"
                v-styler="$sectionData.action"
                )
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Newsletter',
  cover: 'img/covers/newsletter.png',
  group: 'forms',
  $schema: {
    classes: types.ClassList,
    action: types.Button,
    form: {
      email: ''
    }
  },
  props: {
    id: {
      type: Number,
      required: true
    }
  },
  methods: {
    onSubmit () {
      if (this.$builder.isEditing) return;

      const endpoint = this.$sectionData.action.href;
      console.log(`Pinging ${endpoint} with ${this.$sectionData.form.email}`);
      // SEND DATA TO ENDPOINT
    }
  }
};
</script>


================================================
FILE: demo/sections/hero/hero1.vue
================================================
<template lang="pug">
  section.header(
    v-styler="$sectionData.classes"
    :class="$sectionData.classes"
    )
    .container
      .grid
        .column.is-desktop-6.add-center-vertical
          h3.header-title(
            v-html="$sectionData.title"
            v-styler="$sectionData.title"
          )
          p.header-content(
            v-html="$sectionData.content"
            v-styler="$sectionData.content"
          )
          a.button(
            :class="$sectionData.button.classes"
            :href="$sectionData.button.href"
            v-html="$sectionData.button.text"
            v-styler="$sectionData.button"
          )
        .column.is-desktop-6
          uploader(
            class="header-image"
            path="$sectionData.images[0]"
          )
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Hero1',
  cover: 'img/covers/hero1.png',
  group: 'hero',
  $schema: {
    title: types.Title,
    content: types.Text,
    images: [types.Image],
    button: types.Button,
    classes: types.ClassList
  },
  props: {
    id: {
      type: Number,
      required: true
    }
  }
};
</script>


================================================
FILE: demo/sections/hero/hero2.vue
================================================
<template lang="pug">
  section.header(
    v-styler="$sectionData.classes"
    :class="$sectionData.classes"
    )
    .container
      .grid
        .column.is-desktop-6.is-offset-screen-3.add-center-horizontal.add-padding.add-text-center
          h3.header-title(
            v-html="$sectionData.title"
            v-styler="$sectionData.title"
            )
          p.header-content(
            v-html="$sectionData.content"
            v-styler="$sectionData.content"
            )
          a.button(
            :class="$sectionData.button.classes"
            :href="$sectionData.button.href"
            v-html="$sectionData.button.text"
            v-styler="$sectionData.button"
            )
        .column.is-desktop-8.is-offset-screen-2
          uploader(
            class="header-image"
            path="$sectionData.images[0]"
          )
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Hero2',
  cover: 'img/covers/hero2.png',
  group: 'hero',
  $schema: {
    title: types.Title,
    content: types.Text,
    images: [types.Image],
    button: types.Button,
    classes: types.ClassList
  },
  props: {
    id: {
      type: Number,
      required: true
    }
  }
};
</script>


================================================
FILE: demo/sections/section/section1.vue
================================================
<template lang="pug">
  section.section(
    v-styler="$sectionData.classes"
    :class="$sectionData.classes"
  )
    .container
      .grid.is-center
        .column(
          :class="gridClasses[0]"
          v-styler:grid="$sectionData.columns[0].grid"
        )
          h2.section-title(
            v-html="$sectionData.columns[0].title"
            v-styler="$sectionData.columns[0].title"
          )
          p.section-paragraph(
            v-html="$sectionData.columns[0].content"
            v-styler="$sectionData.columns[0].content"
          )
        .column.is-offset-screen-1(
          :class="gridClasses[1]"
          v-styler:grid="$sectionData.columns[1].grid"
        )
          h2.section-title(
            v-html="$sectionData.columns[1].title"
            v-styler="$sectionData.columns[1].title"
          )
          p.section-paragraph(
            v-html="$sectionData.columns[1].content"
            v-styler="$sectionData.columns[1].content"
          )
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Section1',
  cover: 'img/covers/section1.png',
  group: 'section',
  $schema: {
    classes: types.ClassList,
    columns: [
      {
        title: types.Title,
        content: types.Text,
        grid: {
          mobile: 0,
          desktop: 5
        }
      },
      {
        title: types.Title,
        content: types.Text,
        grid: {
          mobile: 0,
          desktop: 5
        }
      }
    ]
  },
  props: {
    id: {
      type: Number, required: true
    }
  }
};
</script>


================================================
FILE: demo/sections/section/section2.vue
================================================
<template lang="pug">
  section.section(
    v-styler:section="$sectionData.classes"
    :class="$sectionData.classes"
  )
    .container
      .grid.is-center
        .column(
          :class="gridClasses[0]"
          v-styler="$sectionData.columns[0].grid"
        )
          h2.section-title(
            v-html="$sectionData.columns[0].title"
            v-styler="$sectionData.columns[0].title"
          )
          p.section-paragraph(
            v-html="$sectionData.columns[0].content"
            v-styler="$sectionData.columns[0].content"
          )
        .column(
          :class="gridClasses[1]"
          v-styler="$sectionData.columns[1].grid"
        )
          h2.section-title(
            v-html="$sectionData.columns[1].title"
            v-styler="$sectionData.columns[1].title"
          )
          p.section-paragraph(
            v-html="$sectionData.columns[1].content"
            v-styler="$sectionData.columns[1].content"
          )
        .column(
          :class="gridClasses[2]"
          v-styler="$sectionData.columns[2].grid"
        )
          h2.section-title(
            v-html="$sectionData.columns[2].title"
            v-styler="$sectionData.columns[2].title"
          )
          p.section-paragraph(
            v-html="$sectionData.columns[2].content"
            v-styler="$sectionData.columns[2].content"
          )
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Section2',
  cover: 'img/covers/section2.png',
  group: 'section',
  $schema: {
    classes: types.ClassList,
    columns: [
      {
        title: types.Title,
        content: types.Text,
        grid: types.Grid
      }, {
        title: types.Title,
        content: types.Text,
        grid: types.Grid
      }, {
        title: types.Title,
        content: types.Text,
        grid: types.Grid
      }
    ]
  },
  props: {
    id: {
      type: Number, required: true
    }
  }
};
</script>


================================================
FILE: demo/sections/social/social1.vue
================================================
<template lang="pug">
  section.social(
    v-styler:section="$sectionData.classes"
    :class="$sectionData.classes"
  )
    .container
      .grid.is-center
        .column.is-desktop-2.social-item
          h6.social-number(
            v-html="$sectionData.columns[0].content"
            v-styler="$sectionData.columns[0].content"
          )
          b.social-keyword(
            v-html="$sectionData.columns[0].title"
            v-styler="$sectionData.columns[0].title"
          )
        .column.is-desktop-2.social-item
          h6.social-number(
            v-html="$sectionData.columns[1].content"
            v-styler="$sectionData.columns[1].content"
          )
          b.social-keyword(
            v-html="$sectionData.columns[1].title"
            v-styler="$sectionData.columns[1].title"
          )
        .column.is-desktop-2.social-item
          h6.social-number(
            v-html="$sectionData.columns[2].content"
            v-styler="$sectionData.columns[2].content"
          )
          b.social-keyword(
            v-html="$sectionData.columns[2].title"
            v-styler="$sectionData.columns[2].title"
          )
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Social1',
  cover: 'img/covers/social1.png',
  group: 'social',
  $schema: {
    classes: types.ClassList,
    columns: [
      {
        title: types.Title,
        content: Number
      }, {
        title: types.Title,
        content: Number
      }, {
        title: types.Title,
        content: Number
      }
    ]
  },
  props: {
    id: {
      type: Number, required: true
    }
  }
};
</script>


================================================
FILE: demo/sections/social/social2.vue
================================================
<template lang="pug">
  section.social(
    v-styler:section="$sectionData.classes"
    :class="$sectionData.classes"
  )
    .container
      .grid
        .row.is-center
          .column.is-desktop-6
            p.social-quote(
              v-html="$sectionData.content"
              v-styler="$sectionData.content"
            )
        .row.is-center
          .column.is-desktop-2
            .user.is-alt
              uploader(
                class="user-avatar"
                path="$sectionData.images[0]"
              )
              .user-data
                h4.user-name Ahmed
                span.user-caption SEO at Baianat

</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Social2',
  cover: 'img/covers/social2.png',
  group: 'social',
  $schema: {
    classes: types.ClassList,
    content: types.Text,
    images: [types.Avatar]
  },
  props: {
    id: {
      type: Number,
      required: true
    }
  }
};
</script>


================================================
FILE: demo/sections/social/social3.vue
================================================
<template lang="pug">
  section.social(
    v-styler:section="$sectionData.classes"
    :class="$sectionData.classes"
  )
    .container
      .grid
        .row.is-center
          .column.is-12.is-desktop-7
            h3.social-title(
              v-html="$sectionData.title"
              v-styler="$sectionData.title"
            )
          .column.is-12.is-desktop-7
            p.social-content(
              v-html="$sectionData.content"
              v-styler="$sectionData.content"
            )
        .row.is-center
          .column.is-desktop-2(v-for="(logo, index) in $sectionData.images")
            uploader(
              class="social-logo"
              :path="`$sectionData.images[${index}]`"
            )
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Social3',
  cover: 'img/covers/social3.png',
  group: 'social',
  $schema: {
    classes: types.ClassList,
    title: types.Title,
    content: types.Text,
    images: [
      types.Logo,
      types.Logo,
      types.Logo
    ]
  },
  props: {
    id: {
      type: Number, required: true
    }
  }
};
</script>


================================================
FILE: demo/sections/social/social4.vue
================================================
<template lang="pug">
  section.social(
    v-styler:section="$sectionData.classes"
    :class="$sectionData.classes"
  )
    .container
      .grid
        .row.is-center
          .column.is-12
            h3.social-title(
              v-html="$sectionData.title"
              v-styler="$sectionData.title"
            )
        .row.is-center
          .column.is-12.is-desktop-4
            p(
              v-html="$sectionData.columns[0].content"
              v-styler="$sectionData.columns[0].content"
            )
            .user
              uploader(
                class="user-avatar"
                path="$sectionData.images[0]"
              )
              .user-data
                h4.user-name Ahmed
                span.user-caption SEO at Baianat

          .column.is-12.is-desktop-4
              p(
                v-html="$sectionData.columns[1].content"
                v-styler:text="$sectionData.columns[1].content"
              )
              .user
                uploader(
                  class="user-avatar"
                  path="$sectionData.images[1]"
                )
                .user-data
                  h4.user-name Ahmed
                  span.user-caption SEO at Baianat

          .column.is-12.is-desktop-4
            p(
              v-html="$sectionData.columns[2].content"
              v-styler:text="$sectionData.columns[2].content"
            )
            .user
              uploader(
                class="user-avatar"
                path="$sectionData.images[2]"
              )
              .user-data
                h4.user-name Ahmed
                span.user-caption SEO at Baianat
</template>

<script>
import * as types from '../../../src/types';

export default {
  name: 'Social4',
  cover: 'img/covers/social4.png',
  group: 'social',
  $schema: {
    classes: [types.ClassList],
    title: types.Title,
    columns: [
      { content: types.Text },
      { content: types.Text },
      { content: types.Text }
    ],
    images: [
      types.Avatar,
      types.Avatar,
      types.Avatar
    ]
  },
  props: {
    id: {
      type: Number, required: true
    }
  }
};
</script>


================================================
FILE: demo/style/_demo.styl
================================================
@import variables
@import '~@baianat/base.framework/base'

@import main
@import header
@import section
@import social
@import user
@import helper
@import scrolling

.column
  transition: 0.2s


================================================
FILE: demo/style/colors.styl
================================================
/*
 * Color theme
 */
$magenta ?= #eb008b
$blue ?= #0072FF
$cyan ?= #00d4f0
$green ?= #18d88b
$yellow ?= #ffdd57
$orange ?= #ffa557
$red ?= #ff3d3d
$purple ?= #a324ea

/*
 * Graysacle
 */
$black ?= #000
$dark ?= #323c47
$gray ?= #c1c1c1
$gray-dark ?= darken($gray, 10%)
$gray-light ?= lighten($gray, 10%)
$light ?= #f5f5f5
$white ?= #fff


================================================
FILE: demo/style/header.styl
================================================
.header
  width: 100%
  padding: 50px
  color: $white
  &-title
    font-size: 50px
    line-height: 1em
    margin: 20px 0
    font-weight: lighter
  &-content
    font-size: 16px
    margin-bottom: 50px
    font-weight: lighter
  &-image
    >img
      width 100%
  &,
  &.is-red
    background-image: linear-gradient(30deg, $red, $yellow)
  &.is-black
    background-image: linear-gradient(30deg, $black, lighten($black, 30%))
  &.is-green
    background-image: linear-gradient(30deg, $green, $yellow)
  &.is-blue
    background-image: linear-gradient(30deg, $blue, lighten($blue, 30%))
  &.is-white
    background-image: linear-gradient(45deg, darken($white, 10%), $white)

================================================
FILE: demo/style/helper.styl
================================================
+prefix-classes('add-')
  .center-horizontal
    display: flex
    flex-direction: column    
    justify-content: center
    align-items: center
  .center-vertical
    display: flex
    flex-direction: column
    justify-content: center
    align-items: flex-start
  .padding
    padding: 20px
  .text-center
    text-align: center
  .full-width
    width: 100%

================================================
FILE: demo/style/main.styl
================================================
::selection
  color: inherit


.button
  white-space: nowrap

================================================
FILE: demo/style/scrolling.styl
================================================
.is-active
  img
    opacity: 1
    transition: 0.4s
  p
  h1
  h2
  h3
  h6
  b
    opacity: 1
    transform: translate3d(0, 0, 0)
    transition: 0.4s

.is-inactive
  img
    opacity: 0
    transition: 0.4s
  p
  h1
  h2
  h3
  h6
  b
    opacity: 0
    transform: translate3d(0, -200px, 0)
    transition: 0.4s

================================================
FILE: demo/style/section.styl
================================================
.section
  padding: 20px 30px
  &-title
    font-size: 30px
    color: $dark

  &-paragraph
    font-size: 16px
    color: lighten($dark, 20%)

  &.is-red
    background: $red
  &.is-black
    background: $black
  &.is-green
    background: $green
  &.is-blue
    background: $blue
  &.is-white
    background: $white

================================================
FILE: demo/style/social.styl
================================================
.social
  padding: 100px 0
  &-number
    font-size: 50px
    margin: 20px 0 50px
  &-item
    display: flex
    flex-direction: column
    justify-content: center
    align-items: center
  &-title
    font-size: 30px
    margin: 30px 0
    text-align: center
  &-content
    font-size: 20px
    margin: 0 0 40px
    text-align: center
  &-logo
    width: 100%
    margin: 20px 0
    @extend $flexCenter

  &-quote
    font-size: 30px
    color: $black
    quotes: "“" "”" "‘" "’"
    &:before
      content: open-quote
      margin-right: 20px
      font-size: 40px
    &:after
      content: close-quote
      margin-left: 20px
      font-size: 40px
  
  &.is-red
    background: $red
  &.is-black
    background: $black
  &.is-green
    background: $green
  &.is-blue
    background: $blue

================================================
FILE: demo/style/transition.styl
================================================
.fade-enter-active
.fade-leave-active
  transition: all .3s ease
  transform: scaleX(1)

.fade-enter
.fade-leave-to
  transform: scaleX(0)

================================================
FILE: demo/style/user.styl
================================================
.user
  display: flex
  align-items: center
  margin: 10px 0
  &.is-alt
    justify-content: center
    flex-direction: column
  &-avatar
    border-radius: 50%
    width: 60px
    height: 60px
    margin-right: 20px
    flex-shrink: 0
    overflow: hidden
    .is-alt &
      margin: 0 0 20px
  &-data
    text-align: left
    white-space: nowrap
    .is-alt &
      text-align: center
  &-name
    font-size: 16px
    color: $black
    margin: 5px 0
  &-caption
    font-size: 16px
    color: $gray
    margin: 0 0 5px


================================================
FILE: demo/style/variables.styl
================================================

$flexCenter
  display: flex
  justify-content: center
  align-items: center

================================================
FILE: demo/webpack.config.js
================================================
const path = require('path');
const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const env = process.env.NODE_ENV;
const production = env === 'production';

// render page
const page = (name) => {
  return new HtmlWebpackPlugin({
    inject: true,
    template: path.join(__dirname, `./${name}.html`),
    filename: path.join(__dirname, `./dist/${name}.html`)
  });
};

const config = {
  mode: production ? 'production' : 'development',
  devtool: production ? 'source-map' : 'cheap-source-map',
  entry: {
    app: path.join(__dirname, './app.js')
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'js/[name].js'
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/style.css'
    }),
    new CleanWebpackPlugin(['./dist']),
    new VueLoaderPlugin(),
    new webpack.LoaderOptionsPlugin({ options: {} }),
    new FriendlyErrorsWebpackPlugin(),
    new ProgressBarPlugin(),
    new CopyWebpackPlugin([{ from: path.join(__dirname, 'img'), to: './img/' }]),
    page('index'),
    page('render')
  ],
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000
  },
  devServer: {
    historyApiFallback: true,
    hot: true,
    inline: true,
    stats: 'errors-only',
    host: '0.0.0.0',
    port: 8080
  },
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader',
        enforce: 'pre'
      },
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: { babelrc: true }
        }
      },
      {
        test: /\.vue$/,
        loader: 'eslint-loader',
        enforce: 'pre'
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.css$/,
        loader: ['style-loader', 'css-loader']
      },
      {
        test: /\.styl(us)?$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'stylus-loader'
        ]
      },
      {
        test: /\.(ttf|eot|svg)(\?.*)?$/,
        loader: 'file-loader',
        options: {
          name: 'font/[name].[ext]'
        }
      },
      {
        test: /.pug$/,
        exclude: /node_modules/,
        loader: 'pug-plain-loader',
        options: {
          pretty: true
        }
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.vue', '.json']
  }
};

module.exports = config;


================================================
FILE: docs/.vuepress/config.js
================================================
module.exports = {
  title: 'Vuse',
  description: 'Advanced page builder based on Vue.js',
  base: '/vuse/',
  themeConfig: {
    lastUpdated: 'Last Updated',
    repo: 'baianat/vuse',
    docsRepo: 'baianat/vuse',
    docsDir: 'docs',
    docsBranch: 'master',
    editLinks: true,
    sidebar: [
      '/',
      '/getting-started',
      '/section',
      '/styler',
      '/exporting',
      '/API',
    ],
    nav: [
      { text: 'API', link: '/API' },
      { text: 'Example', link: '/example' },
    ]
  }
}

================================================
FILE: docs/.vuepress/enhanceApp.js
================================================
// Vuse scripts
import Vuse from '../../src';

// demo scripts
import '../../demo/style/_demo.styl';
import Uploader from '../../demo/Uploader.vue'
import hero1 from '../../demo/sections/hero/hero1';
import hero2 from '../../demo/sections/hero/hero2';
import section1 from '../../demo/sections/section/section1';
import section2 from '../../demo/sections/section/section2';
import social1 from '../../demo/sections/social/social1';
import social2 from '../../demo/sections/social/social2';
import social3 from '../../demo/sections/social/social3';
import social4 from '../../demo/sections/social/social4';
import newsletter from '../../demo/sections/forms/newsletter';

// add the uploader to the list of sub-components.
Vuse.mix({
  components: {
    Uploader
  }
});

// register components.
Vuse.component(hero1);
Vuse.component(hero2);
Vuse.component(section1);
Vuse.component(section2);
Vuse.component(social1);
Vuse.component(social2);
Vuse.component(social3);
Vuse.component(social4);
Vuse.component(newsletter);

export default ({ Vue }) => {
  // install the builder
  Vue.use(Vuse, {
    // main css file
    assets: {
      css: 'style.css'
    },
    // builder default themes
    themes: [{
      name: 'Theme 1',
      sections: [hero1, section1, social1, social3, newsletter]
    }, {
      name: 'Theme 2',
      sections: [hero2, section2, social3, social4, newsletter]
    }]
  });
}


function normalize (component) {
  component.cover = component.cover.replace('static', '.');
}

================================================
FILE: docs/.vuepress/public/style.css
================================================

.vuse-icon {
  display: block;
  width: 20px;
  height: 20px;
}
.controller-button:hover,
.menu-element:hover {
  cursor: pointer;
  box-shadow: 0 14px 28px rgba(0,0,0,0.125), 0 10px 10px rgba(0,0,0,0.1);
}
.artboard {
  transform-origin: top center;
}
.artboard.is-editable .is-editable {
  outline: none;
}
.artboard.is-editable .is-editable:hover {
  box-shadow: inset 0 0 0 2px #c1c1c1;
}
.controller {
  box-sizing: border-box;
}
.controller-panel {
  position: fixed;
  z-index: 200;
  bottom: 30px;
  right: 40px;
}
.controller-input {
  outline: none;
  border: 1px solid #c1c1c1;
  padding: 0.5em 1em;
  margin: 20px 0;
  border-radius: 40px;
  width: 100%;
  font-size: 16px;
}
.controller-input:focus {
  border-color: #0072ff;
  box-shadow: 0 0 0 2px rgba(0,114,255,0.5);
}
.controller-button {
  transition: 0.2s;
  border: none;
  outline: none;
  border-radius: 20px;
  padding: 5px;
  color: #fff;
  fill: #fff;
  font-size: 16px;
}
.controller-button svg {
  transition: 0.2s;
}
.controller-button:not(:last-child) {
  margin-right: 20px;
}
.controller-button.is-rotated >svg {
  transform: rotate(45deg);
}
.controller-button.is-blue {
  background-color: #0072ff;
}
.controller-button.is-blue:hover {
  background-color: #005bcc;
}
.controller-button.is-red {
  background-color: #ff3d3d;
}
.controller-button.is-red:hover {
  background-color: #fd0000;
}
.controller-button.is-green {
  background-color: #18d88b;
}
.controller-button.is-green:hover {
  background-color: #13ad6f;
}
.controller-button.is-dark {
  background-color: #323c47;
}
.controller-button.is-dark:hover {
  background-color: #283039;
}
.controller-button.is-gray {
  background-color: $gary;
}
.controller-button.is-gray:hover {
  background-color: #9a9a9a;
}
.controller-intro {
  width: 100%;
  max-width: 500px;
  margin: auto;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  padding: 70px 50px;
  text-align: center;
  font-size: 30px;
  color: #323c47;
}
.controller-themes {
  display: flex;
  flex-direction: column;
  width: 100%;
}
.controller-theme {
  background-color: #fff;
  color: #323c47;
  border: 1px solid #c1c1c1;
  margin: 5px;
  padding: 20px;
  border-radius: 4px;
  width: 100%;
  cursor: pointer;
  font-size: 16px;
}
.controller-theme:hover {
  border-color: #0072ff;
}
.menu {
  user-select: none;
  -moz-user-select: none;
  position: fixed;
  z-index: 300;
  top: 0;
  left: 0;
  bottom: 0;
  margin: 0;
  width: 250px;
  background: #fff;
  padding: 20px 10px;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  list-style: none;
  transition: 0.4s;
  box-shadow: 1px 0 10px rgba(50,60,71,0.2);
  transform: translate3d(-100%, 0, 0);
}
.menu.is-visiable {
  transform: translate3d(0, 0, 0);
}
.menu-body {
  display: none;
  padding: 0;
  margin: 0;
  list-style: none;
}
.menu-group .menu-body {
  width: 90%;
  margin: 10px auto;
}
.menu-group.is-visiable .menu-body {
  display: block;
}
.menu-icon {
  width: 24px;
  height: 24px;
  fill: #c1c1c1;
  transition: 0.2s;
}
.menu-group.is-visiable .menu-icon {
  transform: rotate(180deg);
}
.menu-element {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  min-height: 50px;
  border-radius: 5px;
  background: #aeaeae;
  transition: 0.3s;
  cursor: pointer;
  color: #fff;
  overflow: hidden;
  user-select: none;
  -moz-user-select: none;
}
.menu-element:not(:last-child) {
  margin-bottom: 10px;
}
.menu-elementImage {
  max-width: 100%;
  pointer-events: none;
}
.menu-elementTitle {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  text-shadow: 1px 1px 2px rgba(0,0,0,0.8);
  text-align: center;
  padding: 5px;
}
.menu-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 5px;
  border-bottom: 1px solid rgba(0,0,0,0.05);
}
.sortable-ghost {
  opacity: 0.3;
  box-shadow: 0 0 2px 1px #0072ff;
}
.is-editable:hover {
  box-shadow: inset 0 0 0 2px #c1c1c1;
}


.styler {
  position: absolute;
  top: 0;
  z-index: 200;
  visibility: hidden;
  opacity: 0;
  margin: 10px 0;
  padding: 5px;
  background: #323c47;
  border-radius: 26px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.styler-list,
.align,
.colorer {
  display: flex;
  justify-content: center;
  align-items: center;
  list-style: none;
  margin: 0;
  padding: 0;
}
.styler-input {
  background: #fff;
  color: #323c47;
  border: 0;
  outline: 0;
  width: 40px;
  height: 40px;
  border-radius: 42px;
  margin: 0 5px 0 0;
  text-align: center;
  -webkit-appearance: none;
  -moz-appearance: textfield;
  appearance: none;
}
.styler-button {
  display: flex;
  justify-content: center;
  align-items: center;
  outline: 0;
  background: #323c47;
  border: 0;
  fill: #fff;
  color: #fff;
  width: 42px;
  height: 42px;
  border-radius: 42px;
  margin: 0 5px 0 0;
}
.styler-button:hover {
  background: #283039;
}
.styler-button:first-child {
  margin-left: 5px;
}
.styler-selector {
  margin: 0 5px;
}
.styler.is-visible {
  visibility: visible;
  opacity: 1;
}
.styler .input-group {
  margin: 5px;
}
.align {
  height: 42px;
}
.colorer {
  height: 42px;
}
.colorer li >input {
  -webkit-appearance: none;
  -moz-appearance: textfield;
  appearance: none;
  width: 30px;
  height: 30px;
  border-radius: 40px;
  border: 4px solid #283039;
  margin: 0 5px;
  outline: none;
}
.colorer li >input:checked {
  border-color: #526375;
}
.colorer li >input:hover {
  border-color: #526375;
}
.colorer li >input#colorRed {
  background: #ff3d3d;
}
.colorer li >input#colorBlue {
  background: #0072ff;
}
.colorer li >input#colorGreen {
  background: #18d88b;
}
.colorer li >input#colorBlack {
  background: #000;
}
.colorer li >input#colorWhite {
  background: #fff;
}
.is-hidden {
  display: none;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.social-logo {
  display: flex;
  justify-content: center;
  align-items: center;
}
.button.is-tiny,
.buttons.is-tiny >.button,
.label.is-tiny,
.input.is-tiny,
.input-tag.is-tiny,
.input-group.is-tiny >.button,
.input-group.is-tiny >.input,
.input-group.is-tiny >.input-tag,
.checkbox.is-tiny,
.radio.is-tiny,
.switcher.is-tiny,
.textarea.is-tiny,
.select.is-tiny,
.pagination.is-tiny,
.content.is-tiny {
  font-size: calc( 0.253378378378378vw + 8.554054054054054px );
}
@media screen and (max-width: 767px) {
  .button.is-tiny,
  .buttons.is-tiny >.button,
  .label.is-tiny,
  .input.is-tiny,
  .input-tag.is-tiny,
  .input-group.is-tiny >.button,
  .input-group.is-tiny >.input,
  .input-group.is-tiny >.input-tag,
  .checkbox.is-tiny,
  .radio.is-tiny,
  .switcher.is-tiny,
  .textarea.is-tiny,
  .select.is-tiny,
  .pagination.is-tiny,
  .content.is-tiny {
    font-size: 10.5px;
  }
}
@media screen and (min-width: 1360px) {
  .button.is-tiny,
  .buttons.is-tiny >.button,
  .label.is-tiny,
  .input.is-tiny,
  .input-tag.is-tiny,
  .input-group.is-tiny >.button,
  .input-group.is-tiny >.input,
  .input-group.is-tiny >.input-tag,
  .checkbox.is-tiny,
  .radio.is-tiny,
  .switcher.is-tiny,
  .textarea.is-tiny,
  .select.is-tiny,
  .pagination.is-tiny,
  .content.is-tiny {
    font-size: 12px;
  }
}
.button.is-small,
.buttons.is-small >.button,
.label,
.label.is-small,
.input.is-small,
.input-tag.is-small,
.input-group.is-small >.button,
.input-group.is-small >.input,
.input-group.is-small >.input-tag,
.checkbox.is-small,
.radio.is-small,
.switcher.is-small,
.textarea.is-small,
[tooltip]:after,
.select.is-small,
.pagination.is-small,
.content.is-small {
  font-size: calc( 0.295608108108108vw + 9.97972972972973px );
}
@media screen and (max-width: 767px) {
  .button.is-small,
  .buttons.is-small >.button,
  .label,
  .label.is-small,
  .input.is-small,
  .input-tag.is-small,
  .input-group.is-small >.button,
  .input-group.is-small >.input,
  .input-group.is-small >.input-tag,
  .checkbox.is-small,
  .radio.is-small,
  .switcher.is-small,
  .textarea.is-small,
  [tooltip]:after,
  .select.is-small,
  .pagination.is-small,
  .content.is-small {
    font-size: 12.25px;
  }
}
@media screen and (min-width: 1360px) {
  .button.is-small,
  .buttons.is-small >.button,
  .label,
  .label.is-small,
  .input.is-small,
  .input-tag.is-small,
  .input-group.is-small >.button,
  .input-group.is-small >.input,
  .input-group.is-small >.input-tag,
  .checkbox.is-small,
  .radio.is-small,
  .switcher.is-small,
  .textarea.is-small,
  [tooltip]:after,
  .select.is-small,
  .pagination.is-small,
  .content.is-small {
    font-size: 14px;
  }
}
p,
body,
.button,
.button.is-normal,
.buttons.is-normal >.button,
.label,
.label.is-normal,
.input,
.input.is-normal,
.input-tag,
.input-tag.is-normal,
.input-group.is-normal >.button,
.input-group.is-normal >.input,
.input-group.is-normal >.input-tag,
.checkbox,
.checkbox.is-normal,
.radio,
.radio.is-normal,
.switcher,
.switcher.is-normal,
.table,
.textarea,
.textarea.is-normal,
.select,
.select.is-normal,
.modal,
.navbar-item,
.pagination-item,
.pagination-next,
.pagination-prev,
.pagination-first,
.pagination-last,
.pagination,
.pagination.is-normal,
.content,
.content.is-normal {
  font-size: calc( 0.337837837837838vw + 11.405405405405405px );
}
@media screen and (max-width: 767px) {
  p,
  body,
  .button,
  .button.is-normal,
  .buttons.is-normal >.button,
  .label,
  .label.is-normal,
  .input,
  .input.is-normal,
  .input-tag,
  .input-tag.is-normal,
  .input-group.is-normal >.button,
  .input-group.is-normal >.input,
  .input-group.is-normal >.input-tag,
  .checkbox,
  .checkbox.is-normal,
  .radio,
  .radio.is-normal,
  .switcher,
  .switcher.is-normal,
  .table,
  .textarea,
  .textarea.is-normal,
  .select,
  .select.is-normal,
  .modal,
  .navbar-item,
  .pagination-item,
  .pagination-next,
  .pagination-prev,
  .pagination-first,
  .pagination-last,
  .pagination,
  .pagination.is-normal,
  .content,
  .content.is-normal {
    font-size: 14px;
  }
}
@media screen and (min-width: 1360px) {
  p,
  body,
  .button,
  .button.is-normal,
  .buttons.is-normal >.button,
  .label,
  .label.is-normal,
  .input,
  .input.is-normal,
  .input-tag,
  .input-tag.is-normal,
  .input-group.is-normal >.button,
  .input-group.is-normal >.input,
  .input-group.is-normal >.input-tag,
  .checkbox,
  .checkbox.is-normal,
  .radio,
  .radio.is-normal,
  .switcher,
  .switcher.is-normal,
  .table,
  .textarea,
  .textarea.is-normal,
  .select,
  .select.is-normal,
  .modal,
  .navbar-item,
  .pagination-item,
  .pagination-next,
  .pagination-prev,
  .pagination-first,
  .pagination-last,
  .pagination,
  .pagination.is-normal,
  .content,
  .content.is-normal {
    font-size: 16px;
  }
}
.button.is-large,
.buttons.is-large >.button,
.label.is-large,
.input.is-large,
.input-tag.is-large,
.input-group.is-large >.button,
.input-group.is-large >.input,
.input-group.is-large >.input-tag,
.checkbox.is-large,
.radio.is-large,
.switcher.is-large,
.textarea.is-large,
.select.is-large,
.pagination.is-large,
.content.is-large {
  font-size: calc( 0.422297297297297vw + 14.256756756756756px );
}
@media screen and (max-width: 767px) {
  .button.is-large,
  .buttons.is-large >.button,
  .label.is-large,
  .input.is-large,
  .input-tag.is-large,
  .input-group.is-large >.button,
  .input-group.is-large >.input,
  .input-group.is-large >.input-tag,
  .checkbox.is-large,
  .radio.is-large,
  .switcher.is-large,
  .textarea.is-large,
  .select.is-large,
  .pagination.is-large,
  .content.is-large {
    font-size: 17.5px;
  }
}
@media screen and (min-width: 1360px) {
  .button.is-large,
  .buttons.is-large >.button,
  .label.is-large,
  .input.is-large,
  .input-tag.is-large,
  .input-group.is-large >.button,
  .input-group.is-large >.input,
  .input-group.is-large >.input-tag,
  .checkbox.is-large,
  .radio.is-large,
  .switcher.is-large,
  .textarea.is-large,
  .select.is-large,
  .pagination.is-large,
  .content.is-large {
    font-size: 20px;
  }
}
.button.is-massive,
.buttons.is-massive >.button,
.label.is-massive,
.input.is-massive,
.input-tag.is-massive,
.input-group.is-massive >.button,
.input-group.is-massive >.input,
.input-group.is-massive >.input-tag,
.checkbox.is-massive,
.radio.is-massive,
.switcher.is-massive,
.textarea.is-massive,
.select.is-massive,
.pagination.is-massive,
.content.is-massive {
  font-size: calc( 0.506756756756757vw + 17.10810810810811px );
}
@media screen and (max-width: 767px) {
  .button.is-massive,
  .buttons.is-massive >.button,
  .label.is-massive,
  .input.is-massive,
  .input-tag.is-massive,
  .input-group.is-massive >.button,
  .input-group.is-massive >.input,
  .input-group.is-massive >.input-tag,
  .checkbox.is-massive,
  .radio.is-massive,
  .switcher.is-massive,
  .textarea.is-massive,
  .select.is-massive,
  .pagination.is-massive,
  .content.is-massive {
    font-size: 21px;
  }
}
@media screen and (min-width: 1360px) {
  .button.is-massive,
  .buttons.is-massive >.button,
  .label.is-massive,
  .input.is-massive,
  .input-tag.is-massive,
  .input-group.is-massive >.button,
  .input-group.is-massive >.input,
  .input-group.is-massive >.input-tag,
  .checkbox.is-massive,
  .radio.is-massive,
  .switcher.is-massive,
  .textarea.is-massive,
  .select.is-massive,
  .pagination.is-massive,
  .content.is-massive {
    font-size: 24px;
  }
}
html {
  line-height: 1.1875 /* 1 */;
  -ms-text-size-adjust: 100% /* 2 */;
  -webkit-text-size-adjust: 100% /* 2 */;
}
* {
  box-sizing: border-box;
}
body {
  margin: 0;
}
article,
aside,
footer,
header,
nav,
section {
  display: block;
}
figcaption,
figure,
main {
/* 1 */
  display: block;
}
figure {
  margin: 1em 40px;
}
hr {
  overflow: visible /* 2 */;
  box-sizing: content-box /* 1 */;
  height: 0 /* 1 */;
}
pre {
  font-size: 1em /* 2 */;
  font-family: monospace, monospace /* 1 */;
}
a {
  background-color: transparent /* 1 */;
  -webkit-text-decoration-skip: objects /* 2 */;
}
abbr[title] {
  border-bottom: none /* 1 */;
  text-decoration: underline /* 2 */;
  text-decoration: underline dotted /* 2 */;
}
b,
strong {
  font-weight: inherit;
}
b,
strong {
  font-weight: bolder;
}
code,
kbd,
samp {
  font-size: 1em /* 2 */;
  font-family: monospace, monospace /* 1 */;
}
dfn {
  font-style: italic;
}
mark {
  background-color: #ff0;
  color: #000;
}
small {
  font-size: 80%;
}
sub,
sup {
  position: relative;
  vertical-align: baseline;
  font-size: 75%;
  line-height: 0;
}
sub {
  bottom: -0.25em;
}
sup {
  top: -0.5em;
}
audio,
video {
  display: inline-block;
}
audio:not([controls]) {
  display: none;
  height: 0;
}
img {
  border-style: none;
}
svg:not(:root) {
  overflow: hidden;
}
button,
input,
optgroup,
select,
textarea {
  margin: 0 /* 2 */;
  font-size: 100% /* 1 */;
  font-family: sans-serif /* 1 */;
  line-height: 1.15 /* 1 */;
}
button,
input {
/* 1 */
  overflow: visible;
}
button,
select {
/* 1 */
  text-transform: none;
}
button,
html [type='button'],
[type='reset'],
[type='submit'] {
  -webkit-appearance: button /* 2 */;
}
button::-moz-focus-inner,
[type='button']::-moz-focus-inner,
[type='reset']::-moz-focus-inner,
[type='submit']::-moz-focus-inner {
  padding: 0;
  border-style: none;
}
button:-moz-focusring,
[type='button']:-moz-focusring,
[type='reset']:-moz-focusring,
[type='submit']:-moz-focusring {
  outline: 1px dotted ButtonText;
}
fieldset {
  padding: 0.35em 0.75em 0.625em;
}
legend {
  display: table /* 1 */;
  box-sizing: border-box /* 1 */;
  padding: 0 /* 3 */;
  max-width: 100% /* 1 */;
  color: inherit /* 2 */;
  white-space: normal /* 1 */;
}
progress {
  display: inline-block /* 1 */;
  vertical-align: baseline /* 2 */;
}
textarea {
  overflow: auto;
}
[type='checkbox'],
[type='radio'] {
  box-sizing: border-box /* 1 */;
  padding: 0 /* 2 */;
}
[type='number']::-webkit-inner-spin-button,
[type='number']::-webkit-outer-spin-button {
  margin: 0;
  -webkit-appearance: none;
}
[type=number] {
  -moz-appearance: textfield;
}
[type='search'] {
  outline-offset: -2px /* 2 */;
  -webkit-appearance: textfield /* 1 */;
}
[type='search']::-webkit-search-cancel-button,
[type='search']::-webkit-search-decoration {
  -webkit-appearance: none;
}
::-webkit-file-upload-button {
  font: inherit /* 2 */;
  -webkit-appearance: button /* 1 */;
}
details,
menu {
  display: block;
}
summary {
  display: list-item;
}
canvas {
  display: inline-block;
}
template {
  display: none;
}
[hidden] {
  display: none;
}
h1,
.h1,
h2,
.h2,
h3,
.h3,
h4,
.h4,
h5,
.h5,
h6,
.h6 {
  margin-top: 0;
  margin-bottom: 0.5em;
  line-height: 1.1875;
  font-weight: 900;
}
h1,
.h1 {
  font-size: calc( 0.844594594594595vw + 28.513513513513512px );
}
@media screen and (max-width: 767px) {
  h1,
  .h1 {
    font-size: 35px;
  }
}
@media screen and (min-width: 1360px) {
  h1,
  .h1 {
    font-size: 40px;
  }
}
h2,
.h2 {
  font-size: calc( 0.675675675675676vw + 22.81081081081081px );
}
@media screen and (max-width: 767px) {
  h2,
  .h2 {
    font-size: 28px;
  }
}
@media screen and (min-width: 1360px) {
  h2,
  .h2 {
    font-size: 32px;
  }
}
h3,
.h3 {
  font-size: calc( 0.591216216216216vw + 19.95945945945946px );
}
@media screen and (max-width: 767px) {
  h3,
  .h3 {
    font-size: 24.5px;
  }
}
@media screen and (min-width: 1360px) {
  h3,
  .h3 {
    font-size: 28px;
  }
}
h4,
.h4 {
  font-size: calc( 0.506756756756757vw + 17.10810810810811px );
}
@media screen and (max-width: 767px) {
  h4,
  .h4 {
    font-size: 21px;
  }
}
@media screen and (min-width: 1360px) {
  h4,
  .h4 {
    font-size: 24px;
  }
}
h5,
.h5 {
  font-size: calc( 0.422297297297297vw + 14.256756756756756px );
}
@media screen and (max-width: 767px) {
  h5,
  .h5 {
    font-size: 17.5px;
  }
}
@media screen and (min-width: 1360px) {
  h5,
  .h5 {
    font-size: 20px;
  }
}
h6,
.h6 {
  font-size: calc( 0.337837837837838vw + 11.405405405405405px );
}
@media screen and (max-width: 767px) {
  h6,
  .h6 {
    font-size: 14px;
  }
}
@media screen and (min-width: 1360px) {
  h6,
  .h6 {
    font-size: 16px;
  }
}
p,
body {
  margin: 0;
}
::selection {
  background: #0072ff;
  color: #fff;
}
*::placeholder {
  color: #aeaeae;
  opacity: 1;
}
*::placeholder:focus {
  outline: 0;
}
html,
input,
button {
  direction: ltr;
  font-family: 'Graphik', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
  font-weight: 400;
}
a {
  color: #0072ff;
  cursor: pointer;
  text-decoration: none;
}
a:hover {
  color: #eb008b;
}
img {
  max-width: 100%;
  height: auto;
}
strong,
b {
  font-weight: 900;
}
pre {
  direction: ltr;
}
.container {
  width: calc(100% - 22px);
  margin: auto;
  padding-left: 1.5625vw;
  padding-right: 1.5625vw;
}
@media screen and (min-width: 768px) {
  .container {
    width: 724px;
  }
}
@media screen and (min-width: 991px) {
  .container {
    width: 925px;
  }
}
@media screen and (min-width: 1360px) {
  .container {
    width: 1272px;
  }
}
@media screen and (min-width: 1920px) {
  .container {
    width: 1810px;
  }
}
.container-full {
  width: 100%;
  padding-left: 8vw;
  padding-right: 8vw;
}
.column {
  flex: 1 0;
  padding-right: 1.5625vw;
  padding-left: 1.5625vw;
}
.column[class*='is-tablet-'],
.column[class*='is-desktop-'],
.column[class*='is-widescreen-'],
.column[class*='is-ultrawide-'],
.grid[class*='is-tablet-'] >.column:not([class*='is-']),
.grid[class*='is-desktop-'] >.column:not([class*='is-']),
.grid[class*='is-widescreen-'] >.column:not([class*='is-']),
.grid[class*='is-ultrawide-'] >.column:not([class*='is-']),
.row[class*='is-tablet-'] >.column:not([class*='is-']),
.row[class*='is-desktop-'] >.column:not([class*='is-']),
.row[class*='is-widescreen-'] >.column:not([class*='is-']),
.row[class*='is-ultrawide-'] >.column:not([class*='is-']) {
  flex: 1 0 100%;
  min-width: 100%;
}
.column.is-0,
.column.is-mobile-0 {
  flex: 0 0 0%;
  min-width: 0%;
}
.column.is-offset-0,
.column.is-offset-mobile-0 {
  margin-left: 0%;
}
.column.is-1,
.column.is-mobile-1,
.grid.is-1 >.column:not([class*='is-']),
.grid.is-mobile-1 >.column:not([class*='is-']),
.row.is-1 >.column:not([class*='is-']),
.row.is-mobile-1 >.column:not([class*='is-']) {
  flex: 0 0 8.333333333333332%;
  min-width: 8.333333333333332%;
}
.column.is-offset-1,
.column.is-offset-mobile-1 {
  margin-left: 8.333333333333332%;
}
.column.is-2,
.column.is-mobile-2,
.grid.is-2 >.column:not([class*='is-']),
.grid.is-mobile-2 >.column:not([class*='is-']),
.row.is-2 >.column:not([class*='is-']),
.row.is-mobile-2 >.column:not([class*='is-']) {
  flex: 0 0 16.666666666666664%;
  min-width: 16.666666666666664%;
}
.column.is-offset-2,
.column.is-offset-mobile-2 {
  margin-left: 16.666666666666664%;
}
.column.is-3,
.column.is-mobile-3,
.grid.is-3 >.column:not([class*='is-']),
.grid.is-mobile-3 >.column:not([class*='is-']),
.row.is-3 >.column:not([class*='is-']),
.row.is-mobile-3 >.column:not([class*='is-']) {
  flex: 0 0 25%;
  min-width: 25%;
}
.column.is-offset-3,
.column.is-offset-mobile-3 {
  margin-left: 25%;
}
.column.is-4,
.column.is-mobile-4,
.grid.is-4 >.column:not([class*='is-']),
.grid.is-mobile-4 >.column:not([class*='is-']),
.row.is-4 >.column:not([class*='is-']),
.row.is-mobile-4 >.column:not([class*='is-']) {
  flex: 0 0 33.33333333333333%;
  min-width: 33.33333333333333%;
}
.column.is-offset-4,
.column.is-offset-mobile-4 {
  margin-left: 33.33333333333333%;
}
.column.is-5,
.column.is-mobile-5,
.grid.is-5 >.column:not([class*='is-']),
.grid.is-mobile-5 >.column:not([class*='is-']),
.row.is-5 >.column:not([class*='is-']),
.row.is-mobile-5 >.column:not([class*='is-']) {
  flex: 0 0 41.66666666666667%;
  min-width: 41.66666666666667%;
}
.column.is-offset-5,
.column.is-offset-mobile-5 {
  margin-left: 41.66666666666667%;
}
.column.is-6,
.column.is-mobile-6,
.grid.is-6 >.column:not([class*='is-']),
.grid.is-mobile-6 >.column:not([class*='is-']),
.row.is-6 >.column:not([class*='is-']),
.row.is-mobile-6 >.column:not([class*='is-']) {
  flex: 0 0 50%;
  min-width: 50%;
}
.column.is-offset-6,
.column.is-offset-mobile-6 {
  margin-left: 50%;
}
.column.is-7,
.column.is-mobile-7,
.grid.is-7 >.column:not([class*='is-']),
.grid.is-mobile-7 >.column:not([class*='is-']),
.row.is-7 >.column:not([class*='is-']),
.row.is-mobile-7 >.column:not([class*='is-']) {
  flex: 0 0 58.333333333333336%;
  min-width: 58.333333333333336%;
}
.column.is-offset-7,
.column.is-offset-mobile-7 {
  margin-left: 58.333333333333336%;
}
.column.is-8,
.column.is-mobile-8,
.grid.is-8 >.column:not([class*='is-']),
.grid.is-mobile-8 >.column:not([class*='is-']),
.row.is-8 >.column:not([class*='is-']),
.row.is-mobile-8 >.column:not([class*='is-']) {
  flex: 0 0 66.66666666666666%;
  min-width: 66.66666666666666%;
}
.column.is-offset-8,
.column.is-offset-mobile-8 {
  margin-left: 66.66666666666666%;
}
.column.is-9,
.column.is-mobile-9,
.grid.is-9 >.column:not([class*='is-']),
.grid.is-mobile-9 >.column:not([class*='is-']),
.row.is-9 >.column:not([class*='is-']),
.row.is-mobile-9 >.column:not([class*='is-']) {
  flex: 0 0 75%;
  min-width: 75%;
}
.column.is-offset-9,
.column.is-offset-mobile-9 {
  margin-left: 75%;
}
.column.is-10,
.column.is-mobile-10,
.grid.is-10 >.column:not([class*='is-']),
.grid.is-mobile-10 >.column:not([class*='is-']),
.row.is-10 >.column:not([class*='is-']),
.row.is-mobile-10 >.column:not([class*='is-']) {
  flex: 0 0 83.33333333333334%;
  min-width: 83.33333333333334%;
}
.column.is-offset-10,
.column.is-offset-mobile-10 {
  margin-left: 83.33333333333334%;
}
.column.is-11,
.column.is-mobile-11,
.grid.is-11 >.column:not([class*='is-']),
.grid.is-mobile-11 >.column:not([class*='is-']),
.row.is-11 >.column:not([class*='is-']),
.row.is-mobile-11 >.column:not([class*='is-']) {
  flex: 0 0 91.66666666666666%;
  min-width: 91.66666666666666%;
}
.column.is-offset-11,
.column.is-offset-mobile-11 {
  margin-left: 91.66666666666666%;
}
.column.is-12,
.column.is-mobile-12,
.grid.is-12 >.column:not([class*='is-']),
.grid.is-mobile-12 >.column:not([class*='is-']),
.row.is-12 >.column:not([class*='is-']),
.row.is-mobile-12 >.column:not([class*='is-']) {
  flex: 0 0 100%;
  min-width: 100%;
}
.column.is-offset-12,
.column.is-offset-mobile-12 {
  margin-left: 100%;
}
@media screen and (min-width: 768px) {
  .column.is-tablet-0 {
    flex: 0 0 0%;
    min-width: 0%;
  }
  .column.is-offset-tablet-0 {
    margin-left: 0%;
  }
  .column.is-tablet-1,
  .grid.is-tablet-1 >.column:not([class*='is-']),
  .row.is-tablet-1 >.column:not([class*='is-']) {
    flex: 0 0 8.333333333333332%;
    min-width: 8.333333333333332%;
  }
  .column.is-offset-tablet-1 {
    margin-left: 8.333333333333332%;
  }
  .column.is-tablet-2,
  .grid.is-tablet-2 >.column:not([class*='is-']),
  .row.is-tablet-2 >.column:not([class*='is-']) {
    flex: 0 0 16.666666666666664%;
    min-width: 16.666666666666664%;
  }
  .column.is-offset-tablet-2 {
    margin-left: 16.666666666666664%;
  }
  .column.is-tablet-3,
  .grid.is-tablet-3 >.column:not([class*='is-']),
  .row.is-tablet-3 >.column:not([class*='is-']) {
    flex: 0 0 25%;
    min-width: 25%;
  }
  .column.is-offset-tablet-3 {
    margin-left: 25%;
  }
  .column.is-tablet-4,
  .grid.is-tablet-4 >.column:not([class*='is-']),
  .row.is-tablet-4 >.column:not([class*='is-']) {
    flex: 0 0 33.33333333333333%;
    min-width: 33.33333333333333%;
  }
  .column.is-offset-tablet-4 {
    margin-left: 33.33333333333333%;
  }
  .column.is-tablet-5,
  .grid.is-tablet-5 >.column:not([class*='is-']),
  .row.is-tablet-5 >.column:not([class*='is-']) {
    flex: 0 0 41.66666666666667%;
    min-width: 41.66666666666667%;
  }
  .column.is-offset-tablet-5 {
    margin-left: 41.66666666666667%;
  }
  .column.is-tablet-6,
  .grid.is-tablet-6 >.column:not([class*='is-']),
  .row.is-tablet-6 >.column:not([class*='is-']) {
    flex: 0 0 50%;
    min-width: 50%;
  }
  .column.is-offset-tablet-6 {
    margin-left: 50%;
  }
  .column.is-tablet-7,
  .grid.is-tablet-7 >.column:not([class*='is-']),
  .row.is-tablet-7 >.column:not([class*='is-']) {
    flex: 0 0 58.333333333333336%;
    min-width: 58.333333333333336%;
  }
  .column.is-offset-tablet-7 {
    margin-left: 58.333333333333336%;
  }
  .column.is-tablet-8,
  .grid.is-tablet-8 >.column:not([class*='is-']),
  .row.is-tablet-8 >.column:not([class*='is-']) {
    flex: 0 0 66.66666666666666%;
    min-width: 66.66666666666666%;
  }
  .column.is-offset-tablet-8 {
    margin-left: 66.66666666666666%;
  }
  .column.is-tablet-9,
  .grid.is-tablet-9 >.column:not([class*='is-']),
  .row.is-tablet-9 >.column:not([class*='is-']) {
    flex: 0 0 75%;
    min-width: 75%;
  }
  .column.is-offset-tablet-9 {
    margin-left: 75%;
  }
  .column.is-tablet-10,
  .grid.is-tablet-10 >.column:not([class*='is-']),
  .row.is-tablet-10 >.column:not([class*='is-']) {
    flex: 0 0 83.33333333333334%;
    min-width: 83.33333333333334%;
  }
  .column.is-offset-tablet-10 {
    margin-left: 83.33333333333334%;
  }
  .column.is-tablet-11,
  .grid.is-tablet-11 >.column:not([class*='is-']),
  .row.is-tablet-11 >.column:not([class*='is-']) {
    flex: 0 0 91.66666666666666%;
    min-width: 91.66666666666666%;
  }
  .column.is-offset-tablet-11 {
    margin-left: 91.66666666666666%;
  }
  .column.is-tablet-12,
  .grid.is-tablet-12 >.column:not([class*='is-']),
  .row.is-tablet-12 >.column:not([class*='is-']) {
    flex: 0 0 100%;
    min-width: 100%;
  }
  .column.is-offset-tablet-12 {
    margin-left: 100%;
  }
}
@media screen and (min-width: 991px) {
  .column.is-desktop-0 {
    flex: 0 0 0%;
    min-width: 0%;
  }
  .column.is-offset-desktop-0 {
    margin-left: 0%;
  }
  .column.is-desktop-1,
  .grid.is-desktop-1 >.column:not([class*='is-']),
  .row.is-desktop-1 >.column:not([class*='is-']) {
    flex: 0 0 8.333333333333332%;
    min-width: 8.333333333333332%;
  }
  .column.is-offset-desktop-1 {
    margin-left: 8.333333333333332%;
  }
  .column.is-desktop-2,
  .grid.is-desktop-2 >.column:not([class*='is-']),
  .row.is-desktop-2 >.column:not([class*='is-']) {
    flex: 0 0 16.666666666666664%;
    min-width: 16.666666666666664%;
  }
  .column.is-offset-desktop-2 {
    margin-left: 16.666666666666664%;
  }
  .column.is-desktop-3,
  .grid.is-desktop-3 >.column:not([class*='is-']),
  .row.is-desktop-3 >.column:not([class*='is-']) {
    flex: 0 0 25%;
    min-width: 25%;
  }
  .column.is-offset-desktop-3 {
    margin-left: 25%;
  }
  .column.is-desktop-4,
  .grid.is-desktop-4 >.column:not([class*='is-']),
  .row.is-desktop-4 >.column:not([class*='is-']) {
    flex: 0 0 33.33333333333333%;
    min-width: 33.33333333333333%;
  }
  .column.is-offset-desktop-4 {
    margin-left: 33.33333333333333%;
  }
  .column.is-desktop-5,
  .grid.is-desktop-5 >.column:not([class*='is-']),
  .row.is-desktop-5 >.column:not([class*='is-']) {
    flex: 0 0 41.66666666666667%;
    min-width: 41.66666666666667%;
  }
  .column.is-offset-desktop-5 {
    margin-left: 41.66666666666667%;
  }
  .column.is-desktop-6,
  .grid.is-desktop-6 >.column:not([class*='is-']),
  .row.is-desktop-6 >.column:not([class*='is-']) {
    flex: 0 0 50%;
    min-width: 50%;
  }
  .column.is-offset-desktop-6 {
    margin-left: 50%;
  }
  .column.is-desktop-7,
  .grid.is-desktop-7 >.column:not([class*='is-']),
  .row.is-desktop-7 >.column:not([class*='is-']) {
    flex: 0 0 58.333333333333336%;
    min-width: 58.333333333333336%;
  }
  .column.is-offset-desktop-7 {
    margin-left: 58.333333333333336%;
  }
  .column.is-desktop-8,
  .grid.is-desktop-8 >.column:not([class*='is-']),
  .row.is-desktop-8 >.column:not([class*='is-']) {
    flex: 0 0 66.66666666666666%;
    min-width: 66.66666666666666%;
  }
  .column.is-offset-desktop-8 {
    margin-left: 66.66666666666666%;
  }
  .column.is-desktop-9,
  .grid.is-desktop-9 >.column:not([class*='is-']),
  .row.is-desktop-9 >.column:not([class*='is-']) {
    flex: 0 0 75%;
    min-width: 75%;
  }
  .column.is-offset-desktop-9 {
    margin-left: 75%;
  }
  .column.is-desktop-10,
  .grid.is-desktop-10 >.column:not([class*='is-']),
  .row.is-desktop-10 >.column:not([class*='is-']) {
    flex: 0 0 83.33333333333334%;
    min-width: 83.33333333333334%;
  }
  .column.is-offset-desktop-10 {
    margin-left: 83.33333333333334%;
  }
  .column.is-desktop-11,
  .grid.is-desktop-11 >.column:not([class*='is-']),
  .row.is-desktop-11 >.column:not([class*='is-']) {
    flex: 0 0 91.66666666666666%;
    min-width: 91.66666666666666%;
  }
  .column.is-offset-desktop-11 {
    margin-left: 91.66666666666666%;
  }
  .column.is-desktop-12,
  .grid.is-desktop-12 >.column:not([class*='is-']),
  .row.is-desktop-12 >.column:not([class*='is-']) {
    flex: 0 0 100%;
    min-width: 100%;
  }
  .column.is-offset-desktop-12 {
    margin-left: 100%;
  }
}
@media screen and (min-width: 1360px) {
  .column.is-widescreen-0 {
    flex: 0 0 0%;
    min-width: 0%;
  }
  .column.is-offset-widescreen-0 {
    margin-left: 0%;
  }
  .column.is-widescreen-1,
  .grid.is-widescreen-1 >.column:not([class*='is-']),
  .row.is-widescreen-1 >.column:not([class*='is-']) {
    flex: 0 0 8.333333333333332%;
    min-width: 8.333333333333332%;
  }
  .column.is-offset-widescreen-1 {
    margin-left: 8.333333333333332%;
  }
  .column.is-widescreen-2,
  .grid.is-widescreen-2 >.column:not([class*='is-']),
  .row.is-widescreen-2 >.column:not([class*='is-']) {
    flex: 0 0 16.666666666666664%;
    min-width: 16.666666666666664%;
  }
  .column.is-offset-widescreen-2 {
    margin-left: 16.666666666666664%;
  }
  .column.is-widescreen-3,
  .grid.is-widescreen-3 >.column:not([class*='is-']),
  .row.is-widescreen-3 >.column:not([class*='is-']) {
    flex: 0 0 25%;
    min-width: 25%;
  }
  .column.is-offset-widescreen-3 {
    margin-left: 25%;
  }
  .column.is-widescreen-4,
  .grid.is-widescreen-4 >.column:not([class*='is-']),
  .row.is-widescreen-4 >.column:not([class*='is-']) {
    flex: 0 0 33.33333333333333%;
    min-width: 33.33333333333333%;
  }
  .column.is-offset-widescreen-4 {
    margin-left: 33.33333333333333%;
  }
  .column.is-widescreen-5,
  .grid.is-widescreen-5 >.column:not([class*='is-']),
  .row.is-widescreen-5 >.column:not([class*='is-']) {
    flex: 0 0 41.66666666666667%;
    min-width: 41.66666666666667%;
  }
  .column.is-offset-widescreen-5 {
    margin-left: 41.66666666666667%;
  }
  .column.is-widescreen-6,
  .grid.is-widescreen-6 >.column:not([class*='is-']),
  .row.is-widescreen-6 >.column:not([class*='is-']) {
    flex: 0 0 50%;
    min-width: 50%;
  }
  .column.is-offset-widescreen-6 {
    margin-left: 50%;
  }
  .column.is-widescreen-7,
  .grid.is-widescreen-7 >.column:not([class*='is-']),
  .row.is-widescreen-7 >.column:not([class*='is-']) {
    flex: 0 0 58.333333333333336%;
    min-width: 58.333333333333336%;
  }
  .column.is-offset-widescreen-7 {
    margin-left: 58.333333333333336%;
  }
  .column.is-widescreen-8,
  .grid.is-widescreen-8 >.column:not([class*='is-']),
  .row.is-widescreen-8 >.column:not([class*='is-']) {
    flex: 0 0 66.66666666666666%;
    min-width: 66.66666666666666%;
  }
  .column.is-offset-widescreen-8 {
    margin-left: 66.66666666666666%;
  }
  .column.is-widescreen-9,
  .grid.is-widescreen-9 >.column:not([class*='is-']),
  .row.is-widescreen-9 >.column:not([class*='is-']) {
    flex: 0 0 75%;
    min-width: 75%;
  }
  .column.is-offset-widescreen-9 {
    margin-left: 75%;
  }
  .column.is-widescreen-10,
  .grid.is-widescreen-10 >.column:not([class*='is-']),
  .row.is-widescreen-10 >.column:not([class*='is-']) {
    flex: 0 0 83.33333333333334%;
    min-width: 83.33333333333334%;
  }
  .column.is-offset-widescreen-10 {
    margin-left: 83.33333333333334%;
  }
  .column.is-widescreen-11,
  .grid.is-widescreen-11 >.column:not([class*='is-']),
  .row.is-widescreen-11 >.column:not([class*='is-']) {
    flex: 0 0 91.66666666666666%;
    min-width: 91.66666666666666%;
  }
  .column.is-offset-widescreen-11 {
    margin-left: 91.66666666666666%;
  }
  .column.is-widescreen-12,
  .grid.is-widescreen-12 >.column:not([class*='is-']),
  .row.is-widescreen-12 >.column:not([class*='is-']) {
    flex: 0 0 100%;
    min-width: 100%;
  }
  .column.is-offset-widescreen-12 {
    margin-left: 100%;
  }
}
@media screen and (min-width: 1920px) {
  .column.is-ultrawide-0 {
    flex: 0 0 0%;
    min-width: 0%;
  }
  .column.is-offset-ultrawide-0 {
    margin-left: 0%;
  }
  .column.is-ultrawide-1,
  .grid.is-ultrawide-1 >.column:not([class*='is-']),
  .row.is-ultrawide-1 >.column:not([class*='is-']) {
    flex: 0 0 8.333333333333332%;
    min-width: 8.333333333333332%;
  }
  .column.is-offset-ultrawide-1 {
    margin-left: 8.333333333333332%;
  }
  .column.is-ultrawide-2,
  .grid.is-ultrawide-2 >.column:not([class*='is-']),
  .row.is-ultrawide-2 >.column:not([class*='is-']) {
    flex: 0 0 16.666666666666664%;
    min-width: 16.666666666666664%;
  }
  .column.is-offset-ultrawide-2 {
    margin-left: 16.666666666666664%;
  }
  .column.is-ultrawide-3,
  .grid.is-ultrawide-3 >.column:not([class*='is-']),
  .row.is-ultrawide-3 >.column:not([class*='is-']) {
    flex: 0 0 25%;
    min-width: 25%;
  }
  .column.is-offset-ultrawide-3 {
    margin-left: 25%;
  }
  .column.is-ultrawide-4,
  .grid.is-ultrawide-4 >.column:not([class*='is-']),
  .row.is-ultrawide-4 >.column:not([class*='is-']) {
    flex: 0 0 33.33333333333333%;
    min-width: 33.33333333333333%;
  }
  .column.is-offset-ultrawide-4 {
    margin-left: 33.33333333333333%;
  }
  .column.is-ultrawide-5,
  .grid.is-ultrawide-5 >.column:not([class*='is-']),
  .row.is-ultrawide-5 >.column:not([class*='is-']) {
    flex: 0 0 41.66666666666667%;
    min-width: 41.66666666666667%;
  }
  .column.is-offset-ultrawide-5 {
    margin-left: 41.66666666666667%;
  }
  .column.is-ultrawide-6,
  .grid.is-ultrawide-6 >.column:not([class*='is-']),
  .row.is-ultrawide-6 >.column:not([class*='is-']) {
    flex: 0 0 50%;
    min-width: 50%;
  }
  .column.is-offset-ultrawide-6 {
    margin-left: 50%;
  }
  .column.is-ultrawide-7,
  .grid.is-ultrawide-7 >.column:not([class*='is-']),
  .row.is-ultrawide-7 >.column:not([class*='is-']) {
    flex: 0 0 58.333333333333336%;
    min-width: 58.333333333333336%;
  }
  .column.is-offset-ultrawide-7 {
    margin-left: 58.333333333333336%;
  }
  .column.is-ultrawide-8,
  .grid.is-ultrawide-8 >.column:not([class*='is-']),
  .row.is-ultrawide-8 >.column:not([class*='is-']) {
    flex: 0 0 66.66666666666666%;
    min-width: 66.66666666666666%;
  }
  .column.is-offset-ultrawide-8 {
    margin-left: 66.66666666666666%;
  }
  .column.is-ultrawide-9,
  .grid.is-ultrawide-9 >.column:not([class*='is-']),
  .row.is-ultrawide-9 >.column:not([class*='is-']) {
    flex: 0 0 75%;
    min-width: 75%;
  }
  .column.is-offset-ultrawide-9 {
    margin-left: 75%;
  }
  .column.is-ultrawide-10,
  .grid.is-ultrawide-10 >.column:not([class*='is-']),
  .row.is-ultrawide-10 >.column:not([class*='is-']) {
    flex: 0 0 83.33333333333334%;
    min-width: 83.33333333333334%;
  }
  .column.is-offset-ultrawide-10 {
    margin-left: 83.33333333333334%;
  }
  .column.is-ultrawide-11,
  .grid.is-ultrawide-11 >.column:not([class*='is-']),
  .row.is-ultrawide-11 >.column:not([class*='is-']) {
    flex: 0 0 91.66666666666666%;
    min-width: 91.66666666666666%;
  }
  .column.is-offset-ultrawide-11 {
    margin-left: 91.66666666666666%;
  }
  .column.is-ultrawide-12,
  .grid.is-ultrawide-12 >.column:not([class*='is-']),
  .row.is-ultrawide-12 >.column:not([class*='is-']) {
    flex: 0 0 100%;
    min-width: 100%;
  }
  .column.is-offset-ultrawide-12 {
    margin-left: 100%;
  }
}
.column.is-middle {
  align-self: center;
}
.column.is-top {
  align-self: flex-start;
}
.column.is-bottom {
  align-self: flex-end;
}
.column >.row {
  margin: 0 -1.5625vw;
  min-width: calc(100% + 3.125vw);
}
.grid,
.row {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  margin-right: -1.5625vw;
  margin-left: -1.5625vw;
  width: auto;
}
.grid.is-center,
.row.is-center {
  justify-content: center;
}
.grid.is-end,
.row.is-end {
  justify-content: flex-end;
}
.grid.is-start,
.row.is-start {
  justify-content: flex-start;
}
.grid.is-middle,
.row.is-middle {
  align-items: center;
}
.grid.is-top,
.row.is-top {
  align-items: flex-start;
}
.grid.is-bottom,
.row.is-bottom {
  align-items: flex-end;
}
.grid.is-vertical,
.row.is-vertical {
  flex-direction: column;
  align-items: flex-start;
}
.grid.is-shrink >.column:not([class*='is-']),
.row.is-shrink >.column:not([class*='is-']) {
  flex: 0 0 auto;
}
.grid.is-relaxed,
.row.is-relaxed {
  margin-right: 0;
  margin-left: 0;
}
.grid.is-relaxed >.column,
.row.is-relaxed >.column {
  padding: 0;
}
.row {
  width: 100%;
  justify-content: inherit;
  margin: 0;
}
.button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
  padding: 0.5em 0.75em;
  outline: none;
  border-width: 1px;
  border-style: solid;
  border-radius: 4px;
  background-clip: border-box;
  vertical-align: top;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: 0.4s ease-in-out;
  border-color: #0072ff;
  background-color: #0072ff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-inverse {
  background-color: transparent;
  color: #0072ff;
  fill: #0072ff;
  stroke-width: 0;
}
.button:hover,
.button:active,
.button.is-active {
  border-color: #0061d9;
  background-color: #0061d9;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button:focus {
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.button[disabled] {
  border-color: #0072ff;
  background-color: #0072ff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-primary,
.buttons.is-primary >.button,
.input-group.is-primary >.button {
  border-color: #0072ff;
  background-color: #0072ff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-primary.is-inverse,
.buttons.is-primary >.button.is-inverse,
.input-group.is-primary >.button.is-inverse,
.buttons.is-primary.is-inverse >.button {
  background-color: transparent;
  color: #0072ff;
  fill: #0072ff;
  stroke-width: 0;
}
.button.is-primary:hover,
.buttons.is-primary >.button:hover,
.input-group.is-primary >.button:hover,
.button.is-primary:active,
.buttons.is-primary >.button:active,
.input-group.is-primary >.button:active,
.button.is-primary.is-active,
.buttons.is-primary >.button.is-active,
.input-group.is-primary >.button.is-active {
  border-color: #0061d9;
  background-color: #0061d9;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-primary:focus,
.buttons.is-primary >.button:focus,
.input-group.is-primary >.button:focus {
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.button.is-primary[disabled],
.buttons.is-primary >.button[disabled],
.input-group.is-primary >.button[disabled] {
  border-color: #0072ff;
  background-color: #0072ff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-secondary,
.buttons.is-secondary >.button,
.input-group.is-secondary >.button {
  border-color: #c7c7c7;
  background-color: #c7c7c7;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-secondary.is-inverse,
.buttons.is-secondary >.button.is-inverse,
.input-group.is-secondary >.button.is-inverse,
.buttons.is-secondary.is-inverse >.button {
  background-color: transparent;
  color: #c7c7c7;
  fill: #c7c7c7;
  stroke-width: 0;
}
.button.is-secondary:hover,
.buttons.is-secondary >.button:hover,
.input-group.is-secondary >.button:hover,
.button.is-secondary:active,
.buttons.is-secondary >.button:active,
.input-group.is-secondary >.button:active,
.button.is-secondary.is-active,
.buttons.is-secondary >.button.is-active,
.input-group.is-secondary >.button.is-active {
  border-color: #a9a9a9;
  background-color: #a9a9a9;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-secondary:focus,
.buttons.is-secondary >.button:focus,
.input-group.is-secondary >.button:focus {
  box-shadow: 0 0 0 3px rgba(199,199,199,0.25);
}
.button.is-secondary[disabled],
.buttons.is-secondary >.button[disabled],
.input-group.is-secondary >.button[disabled] {
  border-color: #c7c7c7;
  background-color: #c7c7c7;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-info,
.buttons.is-info >.button,
.input-group.is-info >.button {
  border-color: #00d4f0;
  background-color: #00d4f0;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-info.is-inverse,
.buttons.is-info >.button.is-inverse,
.input-group.is-info >.button.is-inverse,
.buttons.is-info.is-inverse >.button {
  background-color: transparent;
  color: #00d4f0;
  fill: #00d4f0;
  stroke-width: 0;
}
.button.is-info:hover,
.buttons.is-info >.button:hover,
.input-group.is-info >.button:hover,
.button.is-info:active,
.buttons.is-info >.button:active,
.input-group.is-info >.button:active,
.button.is-info.is-active,
.buttons.is-info >.button.is-active,
.input-group.is-info >.button.is-active {
  border-color: #00b4cc;
  background-color: #00b4cc;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-info:focus,
.buttons.is-info >.button:focus,
.input-group.is-info >.button:focus {
  box-shadow: 0 0 0 3px rgba(0,212,240,0.25);
}
.button.is-info[disabled],
.buttons.is-info >.button[disabled],
.input-group.is-info >.button[disabled] {
  border-color: #00d4f0;
  background-color: #00d4f0;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-success,
.buttons.is-success >.button,
.input-group.is-success >.button {
  border-color: #18d88b;
  background-color: #18d88b;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-success.is-inverse,
.buttons.is-success >.button.is-inverse,
.input-group.is-success >.button.is-inverse,
.buttons.is-success.is-inverse >.button {
  background-color: transparent;
  color: #18d88b;
  fill: #18d88b;
  stroke-width: 0;
}
.button.is-success:hover,
.buttons.is-success >.button:hover,
.input-group.is-success >.button:hover,
.button.is-success:active,
.buttons.is-success >.button:active,
.input-group.is-success >.button:active,
.button.is-success.is-active,
.buttons.is-success >.button.is-active,
.input-group.is-success >.button.is-active {
  border-color: #14b876;
  background-color: #14b876;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-success:focus,
.buttons.is-success >.button:focus,
.input-group.is-success >.button:focus {
  box-shadow: 0 0 0 3px rgba(24,216,139,0.25);
}
.button.is-success[disabled],
.buttons.is-success >.button[disabled],
.input-group.is-success >.button[disabled] {
  border-color: #18d88b;
  background-color: #18d88b;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-warning,
.buttons.is-warning >.button,
.input-group.is-warning >.button {
  border-color: #ffa557;
  background-color: #ffa557;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-warning.is-inverse,
.buttons.is-warning >.button.is-inverse,
.input-group.is-warning >.button.is-inverse,
.buttons.is-warning.is-inverse >.button {
  background-color: transparent;
  color: #ffa557;
  fill: #ffa557;
  stroke-width: 0;
}
.button.is-warning:hover,
.buttons.is-warning >.button:hover,
.input-group.is-warning >.button:hover,
.button.is-warning:active,
.buttons.is-warning >.button:active,
.input-group.is-warning >.button:active,
.button.is-warning.is-active,
.buttons.is-warning >.button.is-active,
.input-group.is-warning >.button.is-active {
  border-color: #ff8a24;
  background-color: #ff8a24;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-warning:focus,
.buttons.is-warning >.button:focus,
.input-group.is-warning >.button:focus {
  box-shadow: 0 0 0 3px rgba(255,165,87,0.25);
}
.button.is-warning[disabled],
.buttons.is-warning >.button[disabled],
.input-group.is-warning >.button[disabled] {
  border-color: #ffa557;
  background-color: #ffa557;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-danger,
.buttons.is-danger >.button,
.input-group.is-danger >.button {
  border-color: #ff3d3d;
  background-color: #ff3d3d;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-danger.is-inverse,
.buttons.is-danger >.button.is-inverse,
.input-group.is-danger >.button.is-inverse,
.buttons.is-danger.is-inverse >.button {
  background-color: transparent;
  color: #ff3d3d;
  fill: #ff3d3d;
  stroke-width: 0;
}
.button.is-danger:hover,
.buttons.is-danger >.button:hover,
.input-group.is-danger >.button:hover,
.button.is-danger:active,
.buttons.is-danger >.button:active,
.input-group.is-danger >.button:active,
.button.is-danger.is-active,
.buttons.is-danger >.button.is-active,
.input-group.is-danger >.button.is-active {
  border-color: #ff0e0e;
  background-color: #ff0e0e;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-danger:focus,
.buttons.is-danger >.button:focus,
.input-group.is-danger >.button:focus {
  box-shadow: 0 0 0 3px rgba(255,61,61,0.25);
}
.button.is-danger[disabled],
.buttons.is-danger >.button[disabled],
.input-group.is-danger >.button[disabled] {
  border-color: #ff3d3d;
  background-color: #ff3d3d;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-black,
.buttons.is-black >.button,
.input-group.is-black >.button {
  border-color: #000;
  background-color: #000;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-black.is-inverse,
.buttons.is-black >.button.is-inverse,
.input-group.is-black >.button.is-inverse,
.buttons.is-black.is-inverse >.button {
  background-color: transparent;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-black:hover,
.buttons.is-black >.button:hover,
.input-group.is-black >.button:hover,
.button.is-black:active,
.buttons.is-black >.button:active,
.input-group.is-black >.button:active,
.button.is-black.is-active,
.buttons.is-black >.button.is-active,
.input-group.is-black >.button.is-active {
  border-color: #000;
  background-color: #000;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-black:focus,
.buttons.is-black >.button:focus,
.input-group.is-black >.button:focus {
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.button.is-black[disabled],
.buttons.is-black >.button[disabled],
.input-group.is-black >.button[disabled] {
  border-color: #000;
  background-color: #000;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-white,
.buttons.is-white >.button,
.input-group.is-white >.button {
  border-color: #fff;
  background-color: #fff;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-white.is-inverse,
.buttons.is-white >.button.is-inverse,
.input-group.is-white >.button.is-inverse,
.buttons.is-white.is-inverse >.button {
  background-color: transparent;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-white:hover,
.buttons.is-white >.button:hover,
.input-group.is-white >.button:hover,
.button.is-white:active,
.buttons.is-white >.button:active,
.input-group.is-white >.button:active,
.button.is-white.is-active,
.buttons.is-white >.button.is-active,
.input-group.is-white >.button.is-active {
  border-color: #d9d9d9;
  background-color: #d9d9d9;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-white:focus,
.buttons.is-white >.button:focus,
.input-group.is-white >.button:focus {
  box-shadow: 0 0 0 3px rgba(255,255,255,0.25);
}
.button.is-white[disabled],
.buttons.is-white >.button[disabled],
.input-group.is-white >.button[disabled] {
  border-color: #fff;
  background-color: #fff;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-dark,
.buttons.is-dark >.button,
.input-group.is-dark >.button {
  border-color: #323c47;
  background-color: #323c47;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-dark.is-inverse,
.buttons.is-dark >.button.is-inverse,
.input-group.is-dark >.button.is-inverse,
.buttons.is-dark.is-inverse >.button {
  background-color: transparent;
  color: #323c47;
  fill: #323c47;
  stroke-width: 0;
}
.button.is-dark:hover,
.buttons.is-dark >.button:hover,
.input-group.is-dark >.button:hover,
.button.is-dark:active,
.buttons.is-dark >.button:active,
.input-group.is-dark >.button:active,
.button.is-dark.is-active,
.buttons.is-dark >.button.is-active,
.input-group.is-dark >.button.is-active {
  border-color: #2a333c;
  background-color: #2a333c;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-dark:focus,
.buttons.is-dark >.button:focus,
.input-group.is-dark >.button:focus {
  box-shadow: 0 0 0 3px rgba(50,60,71,0.25);
}
.button.is-dark[disabled],
.buttons.is-dark >.button[disabled],
.input-group.is-dark >.button[disabled] {
  border-color: #323c47;
  background-color: #323c47;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.button.is-light,
.buttons.is-light >.button,
.input-group.is-light >.button {
  border-color: #f5f5f5;
  background-color: #f5f5f5;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-light.is-inverse,
.buttons.is-light >.button.is-inverse,
.input-group.is-light >.button.is-inverse,
.buttons.is-light.is-inverse >.button {
  background-color: transparent;
  color: #f5f5f5;
  fill: #f5f5f5;
  stroke-width: 0;
}
.button.is-light:hover,
.buttons.is-light >.button:hover,
.input-group.is-light >.button:hover,
.button.is-light:active,
.buttons.is-light >.button:active,
.input-group.is-light >.button:active,
.button.is-light.is-active,
.buttons.is-light >.button.is-active,
.input-group.is-light >.button.is-active {
  border-color: #d0d0d0;
  background-color: #d0d0d0;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-light:focus,
.buttons.is-light >.button:focus,
.input-group.is-light >.button:focus {
  box-shadow: 0 0 0 3px rgba(245,245,245,0.25);
}
.button.is-light[disabled],
.buttons.is-light >.button[disabled],
.input-group.is-light >.button[disabled] {
  border-color: #f5f5f5;
  background-color: #f5f5f5;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button .icon:first-child:not(:last-child) {
  margin-right: 0.25em;
}
.button .icon:last-child:not(:first-child) {
  margin-left: 0.25em;
}
.button .icon:only-child {
  margin: 0 -0.25em;
}
.button .label {
  margin: -0.5em 0;
}
.button.is-block,
.buttons.is-block >.button,
.input-group.is-block >.button {
  width: 100%;
}
.button.is-rounded,
.buttons.is-rounded >.button,
.input-group.is-rounded >.button {
  border-width: 1px;
  border-radius: 10em;
}
.button.is-clean {
  margin: 0;
  border: 0;
  background-color: transparent;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.button.is-link {
  padding-top: 0.3em;
  padding-bottom: 0.3em;
  padding-left: 0;
  padding-right: 0.7em;
  border: 0;
  background-color: transparent;
  color: #0072ff;
  fill: #0072ff;
  stroke-width: 0;
}
.button.is-link:after {
  position: absolute;
  display: block;
  content: '';
  width: 100%;
  height: 0.15em;
  background-color: #0072ff;
  bottom: 0;
  left: 0;
  right: 0;
}
.button.is-link:hover,
.button.is-link:active,
.button.is-link.is-active {
  color: #eb008b;
}
.button.is-link:hover:after,
.button.is-link:active:after,
.button.is-link.is-active:after {
  background-color: #eb008b;
  height: 0.25em;
}
.button:hover {
  text-decoration: none;
}
.button.is-disabled,
.button[disabled],
.buttons.is-disabled >.button,
.buttons[disabled] >.button,
.input-group.is-disabled >.button {
  opacity: 0.8;
  cursor: not-allowed;
}
.buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 10px;
}
.buttons >.label {
  z-index: 2;
  margin: 0 -18.5px;
}
.buttons >.button {
  margin-bottom: 0;
}
.buttons >.button:not(:first-child):not(:last-child) {
  border-radius: 0;
}
.buttons >.button:first-child {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.buttons >.button:last-child {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}
.buttons.is-inverse .button:not(:first-child):not(:last-child) {
  border-left-width: 0;
}
.buttons.is-inverse .button:last-child {
  border-left-width: 0;
}
.label {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  margin: 0 2px;
  margin-bottom: 10px;
  padding: 0.5em;
  min-width: 37px;
  border-radius: 4px;
  color: #000;
  vertical-align: top;
  font-weight: 200;
  line-height: 1;
  background-color: #c1c1c1;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label img {
  margin: -0.75em;
  height: 2.5em;
  vertical-align: top;
}
.label .icon {
  height: 1em;
  width: 1em;
}
.label .icon:first-child:not(:last-child),
.label img:first-child:not(:last-child) {
  margin-right: 0.25em;
}
.label .icon:last-child:not(:first-child),
.label img:last-child:not(:first-child) {
  margin-left: 0.25em;
}
.label.is-primary {
  background-color: #0072ff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label.is-secondary {
  background-color: #c7c7c7;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.label.is-info {
  background-color: #00d4f0;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label.is-success {
  background-color: #18d88b;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label.is-warning {
  background-color: #ffa557;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label.is-danger {
  background-color: #ff3d3d;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label.is-black {
  background-color: #000;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label.is-white {
  background-color: #fff;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.label.is-dark {
  background-color: #323c47;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.label.is-light {
  background-color: #f5f5f5;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.label.is-rounded {
  border-radius: 10em;
}
.label.is-block {
  display: flex;
}
.label.is-float {
  position: absolute;
  top: 0;
  margin: 0;
  margin-top: -1em;
  right: 0;
  margin-right: -1em;
}
.input {
  margin-bottom: 10px;
  padding: 0.5em 0.75em;
  width: 100%;
  outline: none;
  border-width: 1px;
  border-style: solid;
  border-radius: 4px;
  -webkit-appearance: none;
  -moz-appearance: none;
  border-color: #c1c1c1;
}
.input:focus {
  border-color: #0061d9;
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.input.is-primary,
.input-group.is-primary >.input {
  border-color: #0072ff;
}
.input.is-primary:focus,
.input-group.is-primary >.input:focus {
  border-color: #0061d9;
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.input.is-secondary,
.input-group.is-secondary >.input {
  border-color: #c7c7c7;
}
.input.is-secondary:focus,
.input-group.is-secondary >.input:focus {
  border-color: #a9a9a9;
  box-shadow: 0 0 0 3px rgba(199,199,199,0.25);
}
.input.is-info,
.input-group.is-info >.input {
  border-color: #00d4f0;
}
.input.is-info:focus,
.input-group.is-info >.input:focus {
  border-color: #00b4cc;
  box-shadow: 0 0 0 3px rgba(0,212,240,0.25);
}
.input.is-success,
.input-group.is-success >.input {
  border-color: #18d88b;
}
.input.is-success:focus,
.input-group.is-success >.input:focus {
  border-color: #14b876;
  box-shadow: 0 0 0 3px rgba(24,216,139,0.25);
}
.input.is-warning,
.input-group.is-warning >.input {
  border-color: #ffa557;
}
.input.is-warning:focus,
.input-group.is-warning >.input:focus {
  border-color: #ff8a24;
  box-shadow: 0 0 0 3px rgba(255,165,87,0.25);
}
.input.is-danger,
.input-group.is-danger >.input {
  border-color: #ff3d3d;
}
.input.is-danger:focus,
.input-group.is-danger >.input:focus {
  border-color: #ff0e0e;
  box-shadow: 0 0 0 3px rgba(255,61,61,0.25);
}
.input.is-black,
.input-group.is-black >.input {
  border-color: #000;
}
.input.is-black:focus,
.input-group.is-black >.input:focus {
  border-color: #000;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.input.is-white,
.input-group.is-white >.input {
  border-color: #fff;
}
.input.is-white:focus,
.input-group.is-white >.input:focus {
  border-color: #d9d9d9;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.25);
}
.input.is-dark,
.input-group.is-dark >.input {
  border-color: #323c47;
}
.input.is-dark:focus,
.input-group.is-dark >.input:focus {
  border-color: #2a333c;
  box-shadow: 0 0 0 3px rgba(50,60,71,0.25);
}
.input.is-light,
.input-group.is-light >.input {
  border-color: #f5f5f5;
}
.input.is-light:focus,
.input-group.is-light >.input:focus {
  border-color: #d0d0d0;
  box-shadow: 0 0 0 3px rgba(245,245,245,0.25);
}
.input.is-block,
.input-group.is-block >.input {
  width: 100%;
}
.input.is-rounded,
.input-group.is-rounded >.input {
  border-radius: 10em;
}
.input:disabled,
.input.is-disabled,
.input-group.is-disabled >.input {
  cursor: not-allowed;
  background: #c1c1c1;
}
.input.is-disabled,
.input-group.is-disabled >.input {
  pointer-events: none;
}
.input-tag {
  display: inline-flex;
  padding: 0.5em 0.75em;
  border-width: 1px;
  border-style: solid;
  border-radius: 4px;
  vertical-align: top;
  text-align: center;
  border-color: #c1c1c1;
  background-color: #c1c1c1;
  color: #323c47;
  fill: #323c47;
  stroke-width: 0;
}
.input-tag .icon:first-child:not(:last-child) {
  margin-right: 0.25em;
}
.input-tag .icon:last-child:not(:first-child) {
  margin-left: 0.25em;
}
.input-tag .icon:only-child {
  margin: 0 -0.25em;
}
.input-tag.is-primary,
.input-group.is-primary >.input-tag {
  border-color: #0072ff;
  background-color: #0072ff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-secondary,
.input-group.is-secondary >.input-tag {
  border-color: #c7c7c7;
  background-color: #c7c7c7;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-info,
.input-group.is-info >.input-tag {
  border-color: #00d4f0;
  background-color: #00d4f0;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-success,
.input-group.is-success >.input-tag {
  border-color: #18d88b;
  background-color: #18d88b;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-warning,
.input-group.is-warning >.input-tag {
  border-color: #ffa557;
  background-color: #ffa557;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-danger,
.input-group.is-danger >.input-tag {
  border-color: #ff3d3d;
  background-color: #ff3d3d;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-black,
.input-group.is-black >.input-tag {
  border-color: #000;
  background-color: #000;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-white,
.input-group.is-white >.input-tag {
  border-color: #fff;
  background-color: #fff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-dark,
.input-group.is-dark >.input-tag {
  border-color: #323c47;
  background-color: #323c47;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-light,
.input-group.is-light >.input-tag {
  border-color: #f5f5f5;
  background-color: #f5f5f5;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.input-tag.is-rounded,
.input-group.is-rounded >.input-tag {
  border-radius: 10em;
}
.input-tag.is-inverse {
  background-color: transparent;
}
.input-tag.is-clean {
  position: relative;
  background-color: #fff;
  fill: #c1c1c1;
  stroke-width: 0;
  border-right: 0;
  margin-right: -2px;
}
.input-tag.is-disabled,
.input-group.is-disabled >.input-tag {
  opacity: 0.9;
  cursor: not-allowed;
}
.input-group {
  display: flex;
  margin-bottom: 10px;
}
.input-group >*:not(.inputGroup-label) {
  margin-bottom: 0;
}
.input-group-label {
  flex: 1;
  margin-bottom: 0.5em;
  margin-right: 10px;
  white-space: nowrap;
}
.input-group.has-label {
  flex-wrap: wrap;
}
.input-group.has-labelInline {
  align-items: center;
}
.input-group.has-itemAfter .button {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}
.input-group.has-itemAfter .input {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right: 0;
}
.input-group.has-itemBefore .input-tag {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.input-group.has-itemBefore .input {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  border-left: 0;
}
.file {
  margin-bottom: 10px;
  padding: 0.5em 0.75em;
  width: 100%;
  border: 2px dashed #0072ff;
  border-radius: 4px;
  font-size: 16px;
  -webkit-appearance: none;
  -moz-appearance: none;
}
.checkbox,
.radio {
  margin: 10px 0;
  display: flex;
  align-items: center;
  cursor: pointer;
}
.checkbox-label,
.radio-label {
  vertical-align: middle;
}
.checkbox-input,
.radio-input {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  padding: 0;
  width: 1.3em;
  height: 1.3em;
  border: 1px solid #c1c1c1;
  border-radius: 4px;
  cursor: pointer;
  margin-right: 0.4em;
  outline: none;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}
.checkbox-input:focus,
.radio-input:focus {
  border-color: #0072ff;
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.checkbox-input:checked,
.radio-input:checked {
  background-color: #f5f5f5;
}
.checkbox-input:checked:after,
.radio-input:checked:after {
  opacity: 1;
}
.checkbox-input:after,
.radio-input:after {
  display: block;
  opacity: 0;
  width: 0.2em;
  height: 0.5em;
  border: solid #0072ff;
  border-width: 0 0.13em 0.13em 0;
  content: '';
  transform: translate3d(0, -0.1em, 0) rotate(45deg);
}
.checkbox.is-disabled .checkbox-input,
.radio.is-disabled .radio-input,
.checkbox[disabled] .checkbox-input,
.radio[disabled] .radio-input {
  opacity: 0.6;
  cursor: not-allowed;
  pointer-events: none;
}
.checkbox.is-inline,
.radio.is-inline {
  display: inline-flex;
  margin-right: 0.8em;
}
.checkbox.is-disabled,
.radio.is-disabled,
.checkbox[disabled],
.radio[disabled] {
  pointer-events: none;
  cursor: not-allowed;
}
.icon {
  display: inline;
  vertical-align: middle;
  line-height: inherit;
  font-size: 1em;
  width: 1em;
  height: 1em;
}
.icon.is-primary {
  fill: #0072ff;
  stroke-width: 0;
}
.icon.is-secondary {
  fill: #c7c7c7;
  stroke-width: 0;
}
.icon.is-info {
  fill: #00d4f0;
  stroke-width: 0;
}
.icon.is-success {
  fill: #18d88b;
  stroke-width: 0;
}
.icon.is-warning {
  fill: #ffa557;
  stroke-width: 0;
}
.icon.is-danger {
  fill: #ff3d3d;
  stroke-width: 0;
}
.icon.is-black {
  fill: #000;
  stroke-width: 0;
}
.icon.is-white {
  fill: #fff;
  stroke-width: 0;
}
.icon.is-dark {
  fill: #323c47;
  stroke-width: 0;
}
.icon.is-light {
  fill: #f5f5f5;
  stroke-width: 0;
}
.icon.is-tiny {
  width: calc( 0.253378378378378vw + 8.554054054054054px );
}
@media screen and (max-width: 767px) {
  .icon.is-tiny {
    width: 10.5px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-tiny {
    width: 12px;
  }
}
.icon.is-tiny {
  height: calc( 0.253378378378378vw + 8.554054054054054px );
}
@media screen and (max-width: 767px) {
  .icon.is-tiny {
    height: 10.5px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-tiny {
    height: 12px;
  }
}
.icon.is-small {
  width: calc( 0.295608108108108vw + 9.97972972972973px );
}
@media screen and (max-width: 767px) {
  .icon.is-small {
    width: 12.25px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-small {
    width: 14px;
  }
}
.icon.is-small {
  height: calc( 0.295608108108108vw + 9.97972972972973px );
}
@media screen and (max-width: 767px) {
  .icon.is-small {
    height: 12.25px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-small {
    height: 14px;
  }
}
.icon.is-normal {
  width: calc( 0.337837837837838vw + 11.405405405405405px );
}
@media screen and (max-width: 767px) {
  .icon.is-normal {
    width: 14px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-normal {
    width: 16px;
  }
}
.icon.is-normal {
  height: calc( 0.337837837837838vw + 11.405405405405405px );
}
@media screen and (max-width: 767px) {
  .icon.is-normal {
    height: 14px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-normal {
    height: 16px;
  }
}
.icon.is-large {
  width: calc( 0.422297297297297vw + 14.256756756756756px );
}
@media screen and (max-width: 767px) {
  .icon.is-large {
    width: 17.5px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-large {
    width: 20px;
  }
}
.icon.is-large {
  height: calc( 0.422297297297297vw + 14.256756756756756px );
}
@media screen and (max-width: 767px) {
  .icon.is-large {
    height: 17.5px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-large {
    height: 20px;
  }
}
.icon.is-massive {
  width: calc( 0.506756756756757vw + 17.10810810810811px );
}
@media screen and (max-width: 767px) {
  .icon.is-massive {
    width: 21px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-massive {
    width: 24px;
  }
}
.icon.is-massive {
  height: calc( 0.506756756756757vw + 17.10810810810811px );
}
@media screen and (max-width: 767px) {
  .icon.is-massive {
    height: 21px;
  }
}
@media screen and (min-width: 1360px) {
  .icon.is-massive {
    height: 24px;
  }
}
.radio-input {
  border-radius: 10em;
}
.radio-input:after {
  width: 70%;
  height: 70%;
  border: none;
  border-radius: 10em;
  background: #0072ff;
  transform: none;
}
.switcher {
  display: inline-flex;
  margin: 5px;
  vertical-align: middle;
}
.switcher-input {
  display: none;
}
.switcher-input:checked + .switcher-body {
  background-color: #0072ff;
  padding-left: 0.5em;
  padding-right: 1.3em;
}
.switcher-input:checked + .switcher-body .switcher-handle {
  left: calc(100% - 1.3em);
}
.switcher-input:checked + .switcher-body .switcher-true {
  max-width: 40em;
  opacity: 1;
}
.switcher-input:checked + .switcher-body .switcher-false {
  max-width: 0em;
  opacity: 0;
}
.switcher-input[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}
.switcher-input[disabled] + .switcher-body {
  opacity: 0.6;
  cursor: not-allowed;
}
.switcher-body {
  position: relative;
  display: inline-flex;
  padding: 0;
  padding-left: 1.3em;
  padding-right: 0.5em;
  min-width: 2.6em;
  height: 1.3em;
  background-color: #000;
  cursor: pointer;
  transition: 0.3s;
  justify-content: center;
  align-items: center;
  color: #fff;
  user-select: none;
}
.switcher-body p {
  font-size: 0.8em;
}
.switcher-true {
  max-width: 0em;
  opacity: 0;
}
.switcher-false {
  max-width: 40em;
  opacity: 1;
}
.switcher-handle {
  position: absolute;
  left: 0;
  margin: 0.25em;
  top: 0;
  display: block;
  width: 0.8em;
  height: 0.8em;
  background-color: #fff;
  content: '';
  transition: 0.3s;
}
.switcher-handle.is-dragging {
  transition: 0;
}
.switcher.is-rounded .switcher-handle,
.switcher.is-rounded .switcher-body {
  border-radius: 100em;
}
.switcher.is-disabled,
.switcher[disabled] {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.6;
}
.switcher.is-disabled .switcher-input,
.switcher[disabled] .switcher-input {
  cursor: not-allowed;
}
.table {
  overflow: hidden;
  width: 100%;
  border: 1px solid #000;
  border-spacing: 0;
  border-collapse: separate;
  border-radius: 4px;
  color: #000;
  text-align: left;
}
.table:not(:last-child) {
  margin-bottom: 10px;
}
.table th:not(:last-child),
.table td:not(:last-child) {
  border-right: 1px solid #000;
}
@media screen and (max-width: 767px) {
  .table th:not(:last-child),
  .table td:not(:last-child) {
    border-right: 0;
  }
}
@media screen and (max-width: 767px) {
  .table th,
  .table td {
    display: block;
    width: 100%;
  }
}
.table thead {
  background-color: #fff;
}
.table thead th {
  border-bottom: 1px solid #000;
  padding: 1em 0.5em;
  font-weight: bold;
}
@media screen and (max-width: 767px) {
  .table thead th {
    border-bottom: 0;
  }
}
.table tfoot {
  background-color: #fff;
}
.table tfoot th {
  border-top: 1px solid #000;
  padding: 0.5em;
}
@media screen and (max-width: 767px) {
  .table tr {
    display: block;
    border-top: 1px solid #000;
  }
}
.table td {
  padding: 0.5em;
  border-top: 1px solid #000;
  background-color: #fff;
}
@media screen and (max-width: 767px) {
  .table td {
    border: 0;
  }
}
.table-wrapper {
  position: relative;
  display: table;
  overflow-x: auto;
  margin: 10px auto;
  padding: 0.5em;
  border: 1px solid #fff;
  border-radius: 4px;
  background-color: #fff;
  width: 100%;
}
.table-sort {
  float: right;
  padding: 0;
  outline: 0;
  background: none;
  border: none;
}
.table-sort.is-active {
  fill: #0072ff;
  stroke: #0072ff;
}
.table-sort.is-desc {
  transform: scaleY(-1);
}
.table.is-striped tr:nth-child(2n) td {
  background-color: $alight;
}
.table.is-relaxed {
  border: 0;
}
.table.is-relaxed th,
.table.is-relaxed td {
  border-right: 0;
}
.table.is-center {
  text-align: center;
}
.table.is-top tbody {
  vertical-align: top;
}
.table.is-bottom tbody {
  vertical-align: bottom;
}
.table.is-middle tbody {
  vertical-align: middle;
}
.table.is-small td {
  padding: 0.25em 0.5em;
}
.table.is-large td {
  padding: 1em 0.5em;
}
.textarea {
  display: block;
  margin-bottom: 10px;
  padding: 0.5em;
  min-width: 100%;
  max-width: 100%;
  outline: none;
  border-width: 1px;
  border-style: solid;
  border-radius: 4px;
  text-align: left;
  line-height: 1.2;
  border-color: #c1c1c1;
}
.textarea:focus {
  border-color: #0061d9;
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.textarea.is-primary {
  border-color: #0072ff;
}
.textarea.is-primary:focus {
  border-color: #0061d9;
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.textarea.is-secondary {
  border-color: #c7c7c7;
}
.textarea.is-secondary:focus {
  border-color: #a9a9a9;
  box-shadow: 0 0 0 3px rgba(199,199,199,0.25);
}
.textarea.is-info {
  border-color: #00d4f0;
}
.textarea.is-info:focus {
  border-color: #00b4cc;
  box-shadow: 0 0 0 3px rgba(0,212,240,0.25);
}
.textarea.is-success {
  border-color: #18d88b;
}
.textarea.is-success:focus {
  border-color: #14b876;
  box-shadow: 0 0 0 3px rgba(24,216,139,0.25);
}
.textarea.is-warning {
  border-color: #ffa557;
}
.textarea.is-warning:focus {
  border-color: #ff8a24;
  box-shadow: 0 0 0 3px rgba(255,165,87,0.25);
}
.textarea.is-danger {
  border-color: #ff3d3d;
}
.textarea.is-danger:focus {
  border-color: #ff0e0e;
  box-shadow: 0 0 0 3px rgba(255,61,61,0.25);
}
.textarea.is-black {
  border-color: #000;
}
.textarea.is-black:focus {
  border-color: #000;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.textarea.is-white {
  border-color: #fff;
}
.textarea.is-white:focus {
  border-color: #d9d9d9;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.25);
}
.textarea.is-dark {
  border-color: #323c47;
}
.textarea.is-dark:focus {
  border-color: #2a333c;
  box-shadow: 0 0 0 3px rgba(50,60,71,0.25);
}
.textarea.is-light {
  border-color: #f5f5f5;
}
.textarea.is-light:focus {
  border-color: #d0d0d0;
  box-shadow: 0 0 0 3px rgba(245,245,245,0.25);
}
.textarea:disabled,
.textarea.is-disabled {
  cursor: not-allowed;
  background: #c1c1c1;
  color: #fff;
  pointer-events: none;
}
[tooltip] {
  position: relative;
}
[tooltip]:focus {
  outline: none;
}
[tooltip]:hover:before,
[tooltip]:hover:after {
  visibility: visible;
  opacity: 1;
}
[tooltip]:before {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 99999;
  display: block;
  visibility: hidden;
  width: 0;
  height: 0;
  border-width: 7px 7px 0 7px;
  border-style: solid;
  border-color: #000 transparent transparent transparent;
  content: '';
  opacity: 0;
  transition: 0.4s;
  transform: translateX(-50%) translateY(-100%);
  user-select: none;
}
[tooltip]:after {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 99999;
  display: block;
  visibility: hidden;
  padding: 0.5em;
  border-radius: 4px;
  background-color: #000;
  color: #fff;
  content: attr(tooltip);
  white-space: nowrap;
  opacity: 0;
  transition: 0.4s;
  transform: translateX(-50%) translateY(-100%) translateY(-7px);
  user-select: none;
}
[tooltip-position='bottom']:before {
  top: auto;
  top: initial;
  bottom: 0;
  border-width: 0 7px 7px 7px;
  border-color: transparent transparent #000 transparent;
  transform: translateX(-50%) translateY(100%);
}
[tooltip-position='bottom']:after {
  top: auto;
  top: initial;
  bottom: 0;
  transform: translateX(-50%) translateY(100%) translateY(7px);
}
[tooltip-position='left']:before {
  top: 50%;
  left: 0;
  border-width: 7px 0 7px 7px;
  border-color: transparent transparent transparent #000;
  transform: translateX(-100%) translateY(-50%);
}
[tooltip-position='left']:after {
  top: 50%;
  left: 0;
  transform: translateX(-100%) translateX(-7px) translateY(-50%);
}
[tooltip-position='right']:before {
  top: 50%;
  right: 0;
  left: auto;
  left: initial;
  border-width: 7px 7px 7px 0;
  border-color: transparent #000 transparent transparent;
  transform: translateX(100%) translateY(-50%);
}
[tooltip-position='right']:after {
  top: 50%;
  right: 0;
  left: auto;
  left: initial;
  transform: translateX(100%) translateX(7px) translateY(-50%);
}
[tooltip-rounded]:after {
  border-radius: 10em;
}
.select {
  position: relative;
  margin-bottom: 10px;
  margin-bottom: 0;
  padding: 0.5em 0.75em;
  max-width: 100%;
  width: 100%;
  outline: none;
  border-width: 1px;
  border-style: solid;
  border-radius: 4px;
  background-color: #fff;
  background-image: linear-gradient(45deg, transparent 50%, #000 50%), linear-gradient(135deg, #000 50%, transparent 50%);
  background-position: calc(100% - 0.8em) calc(50% + 0.1em), calc(100% - 0.4em) calc(50% + 0.1em);
  background-size: 0.4em 0.4em, 0.4em 0.4em;
  background-repeat: no-repeat;
  text-align: left;
  -webkit-appearance: none;
  -moz-appearance: none;
  border-color: #c1c1c1;
  background-image: linear-gradient(45deg, transparent 50%, #c1c1c1 50%), linear-gradient(135deg, #c1c1c1 50%, transparent 50%);
  color: #0072ff;
/*
   * select elments
   */
}
.select .select-label,
.select .select-item.is-selected,
.select .select-childItem.is-selected {
  background-color: #0072ff;
  color: #fff;
}
.select .select-item:not(.is-group):hover,
.select .select-childItem:hover {
  background-color: #0061d9;
  color: #fff;
}
.select:focus {
  border-color: #a4a4a4;
  box-shadow: 0 0 0 3px rgba(193,193,193,0.25);
}
.select-input {
  display: flex;
  padding: 0;
  border: 0;
  outline: none;
  background-color: transparent;
  color: inherit;
  text-align: left;
  font-size: inherit;
  -webkit-appearance: textfield;
  -moz-appearance: none;
}
.select select {
  display: none;
}
.select-labels {
  position: absolute;
  top: 0;
  left: 0;
  display: inline-flex;
  flex-wrap: wrap;
  margin-right: 2em;
  padding: 0;
}
.select-label {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  margin: 0.2em;
  padding: 0.4em;
  border-radius: 4px;
  background-color: #000;
  color: #fff;
  font-size: 1em;
  line-height: 1;
  fill: currentColor;
  stroke-width: 0;
}
.select-labelDismiss {
  width: 1em;
  height: 1em;
  color: currentColor;
}
.select-labelDismiss:hover {
  fill: #c1c1c1;
}
.select-menu {
  position: absolute;
  top: 100%;
  right: 0;
  left: 0;
  z-index: 999;
  margin: 0 -1px;
  border-width: 0 1px 1px 1px;
  border-style: solid;
  border-color: inherit;
  border-radius: 0 0 4px 4px;
  background: #fff;
  font-size: inherit;
}
.select-list {
  overflow: auto;
  margin: 0;
  padding: 0;
  max-height: 40vh;
  list-style: none;
}
.select-item {
  padding: 0;
  width: 100%;
}
.select-item:not(.is-group) {
  padding: 0.5em;
  cursor: pointer;
}
.select-childMenu {
  margin: 0;
  padding: 0;
  list-style: none;
}
.select-childTitle {
  display: block;
  padding: 0.5em;
  color: #c1c1c1;
}
.select-childItem {
  padding: 0.5em 0.5em 0.5em 1em;
  cursor: pointer;
}
.select.is-primary {
  border-color: #0072ff;
  background-image: linear-gradient(45deg, transparent 50%, #0072ff 50%), linear-gradient(135deg, #0072ff 50%, transparent 50%);
  color: #0072ff;
}
.select.is-primary .select-label,
.select.is-primary .select-item.is-selected,
.select.is-primary .select-childItem.is-selected {
  background-color: #0072ff;
  color: #fff;
}
.select.is-primary .select-item:not(.is-group):hover,
.select.is-primary .select-childItem:hover {
  background-color: #0061d9;
  color: #fff;
}
.select.is-primary:focus {
  border-color: #0061d9;
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.select.is-secondary {
  border-color: #000;
  background-image: linear-gradient(45deg, transparent 50%, #000 50%), linear-gradient(135deg, #000 50%, transparent 50%);
  color: #000;
}
.select.is-secondary .select-label,
.select.is-secondary .select-item.is-selected,
.select.is-secondary .select-childItem.is-selected {
  background-color: #000;
  color: #fff;
}
.select.is-secondary .select-item:not(.is-group):hover,
.select.is-secondary .select-childItem:hover {
  background-color: #000;
  color: #fff;
}
.select.is-secondary:focus {
  border-color: #000;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.select.is-info {
  border-color: #00d4f0;
  background-image: linear-gradient(45deg, transparent 50%, #00d4f0 50%), linear-gradient(135deg, #00d4f0 50%, transparent 50%);
  color: #00d4f0;
}
.select.is-info .select-label,
.select.is-info .select-item.is-selected,
.select.is-info .select-childItem.is-selected {
  background-color: #00d4f0;
  color: #fff;
}
.select.is-info .select-item:not(.is-group):hover,
.select.is-info .select-childItem:hover {
  background-color: #00b4cc;
  color: #fff;
}
.select.is-info:focus {
  border-color: #00b4cc;
  box-shadow: 0 0 0 3px rgba(0,212,240,0.25);
}
.select.is-success {
  border-color: #18d88b;
  background-image: linear-gradient(45deg, transparent 50%, #18d88b 50%), linear-gradient(135deg, #18d88b 50%, transparent 50%);
  color: #18d88b;
}
.select.is-success .select-label,
.select.is-success .select-item.is-selected,
.select.is-success .select-childItem.is-selected {
  background-color: #18d88b;
  color: #fff;
}
.select.is-success .select-item:not(.is-group):hover,
.select.is-success .select-childItem:hover {
  background-color: #14b876;
  color: #fff;
}
.select.is-success:focus {
  border-color: #14b876;
  box-shadow: 0 0 0 3px rgba(24,216,139,0.25);
}
.select.is-warning {
  border-color: #ffa557;
  background-image: linear-gradient(45deg, transparent 50%, #ffa557 50%), linear-gradient(135deg, #ffa557 50%, transparent 50%);
  color: #ffa557;
}
.select.is-warning .select-label,
.select.is-warning .select-item.is-selected,
.select.is-warning .select-childItem.is-selected {
  background-color: #ffa557;
  color: #fff;
}
.select.is-warning .select-item:not(.is-group):hover,
.select.is-warning .select-childItem:hover {
  background-color: #ff8a24;
  color: #fff;
}
.select.is-warning:focus {
  border-color: #ff8a24;
  box-shadow: 0 0 0 3px rgba(255,165,87,0.25);
}
.select.is-danger {
  border-color: #ff3d3d;
  background-image: linear-gradient(45deg, transparent 50%, #ff3d3d 50%), linear-gradient(135deg, #ff3d3d 50%, transparent 50%);
  color: #ff3d3d;
}
.select.is-danger .select-label,
.select.is-danger .select-item.is-selected,
.select.is-danger .select-childItem.is-selected {
  background-color: #ff3d3d;
  color: #fff;
}
.select.is-danger .select-item:not(.is-group):hover,
.select.is-danger .select-childItem:hover {
  background-color: #ff0e0e;
  color: #fff;
}
.select.is-danger:focus {
  border-color: #ff0e0e;
  box-shadow: 0 0 0 3px rgba(255,61,61,0.25);
}
.select.is-black {
  border-color: #000;
  background-image: linear-gradient(45deg, transparent 50%, #000 50%), linear-gradient(135deg, #000 50%, transparent 50%);
  color: #000;
}
.select.is-black .select-label,
.select.is-black .select-item.is-selected,
.select.is-black .select-childItem.is-selected {
  background-color: #000;
  color: #fff;
}
.select.is-black .select-item:not(.is-group):hover,
.select.is-black .select-childItem:hover {
  background-color: #000;
  color: #fff;
}
.select.is-black:focus {
  border-color: #000;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.select.is-white {
  border-color: #000;
  background-image: linear-gradient(45deg, transparent 50%, #000 50%), linear-gradient(135deg, #000 50%, transparent 50%);
  color: #000;
}
.select.is-white .select-label,
.select.is-white .select-item.is-selected,
.select.is-white .select-childItem.is-selected {
  background-color: #000;
  color: #fff;
}
.select.is-white .select-item:not(.is-group):hover,
.select.is-white .select-childItem:hover {
  background-color: #000;
  color: #fff;
}
.select.is-white:focus {
  border-color: #000;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.select.is-dark {
  border-color: #323c47;
  background-image: linear-gradient(45deg, transparent 50%, #323c47 50%), linear-gradient(135deg, #323c47 50%, transparent 50%);
  color: #323c47;
}
.select.is-dark .select-label,
.select.is-dark .select-item.is-selected,
.select.is-dark .select-childItem.is-selected {
  background-color: #323c47;
  color: #fff;
}
.select.is-dark .select-item:not(.is-group):hover,
.select.is-dark .select-childItem:hover {
  background-color: #2a333c;
  color: #fff;
}
.select.is-dark:focus {
  border-color: #2a333c;
  box-shadow: 0 0 0 3px rgba(50,60,71,0.25);
}
.select.is-light {
  border-color: #000;
  background-image: linear-gradient(45deg, transparent 50%, #000 50%), linear-gradient(135deg, #000 50%, transparent 50%);
  color: #000;
}
.select.is-light .select-label,
.select.is-light .select-item.is-selected,
.select.is-light .select-childItem.is-selected {
  background-color: #000;
  color: #fff;
}
.select.is-light .select-item:not(.is-group):hover,
.select.is-light .select-childItem:hover {
  background-color: #000;
  color: #fff;
}
.select.is-light:focus {
  border-color: #000;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.select .is-visible {
  display: block;
}
.select .is-hidden {
  display: none;
}
.select.is-rounded {
  border-radius: 10em;
}
.select:disabled,
.select.is-disabled {
  opacity: 0.7;
  cursor: not-allowed;
}
.select.is-active {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.select.is-disabled {
  opacity: 0.7;
  pointer-events: none;
}
.dropdown {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
}
.dropdown.is-right {
  justify-content: flex-end;
}
.dropdown.is-center {
  justify-content: center;
}
.dropdown-menu {
  position: absolute;
  top: 70px;
  left: 0;
  padding: 0.5em;
  width: 300px;
  border: 1px solid #000;
  border-radius: 4px;
  background-color: #fff;
  color: #000;
  list-style: none;
  transform-origin: top left;
  user-select: none;
}
.dropdown-menu li {
  padding: 0;
  font-size: 16px;
}
.dropdown-menu .dropdown-menu {
  position: relative;
  top: 0;
}
.dropdown-menu:empty {
  display: none;
}
.dropdown-menu.is-hidden {
  margin: 0;
  padding: 0;
  height: 0;
  transform: scale(0);
}
.dropdown-menu.is-visible {
  transform: scale(1);
}
.dropdown-menu:before {
  position: absolute;
  top: -0.5em;
  left: 0.5em;
  display: block;
  width: 0;
  height: 0;
  border-width: 0 0.5em 0.5em 0.5em;
  border-style: solid;
  border-color: transparent transparent #000 transparent;
  content: '';
}
.dropdown-menu:after {
  position: absolute;
  top: calc( 0.675675675675676vw + -11.18918918918919px );
  left: 0.5em;
  display: block;
  width: 0;
  height: 0;
  border-width: 0 0.5em 0.5em 0.5em;
  border-style: solid;
  border-color: transparent transparent #fff transparent;
  content: '';
}
.is-right .dropdown-menu {
  right: 0;
  left: auto;
  left: initial;
  transform-origin: top right;
}
.is-right .dropdown-menu:before,
.is-right .dropdown-menu:after {
  right: 0.5em;
  left: auto;
  left: initial;
}
.is-center .dropdown-menu {
  left: calc(50% - 150px);
  transform-origin: top center;
}
.is-center .dropdown-menu:before,
.is-center .dropdown-menu:after {
  left: calc(50% - 7px);
}
.modal {
  position: relative;
  z-index: 999;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: stretch;
  margin: 10px 8vw;
  padding: 2.5em;
  width: 100%;
  border: 0;
  border-radius: 4px;
  background-color: #fff;
  max-width: 800px;
  max-height: calc(100vh - 40px);
  box-shadow: 0 15px 20px -10px rgba(0,0,0,0.2);
}
.modal-header {
  position: relative;
  margin-bottom: 2.5em;
}
.modal-title {
  margin: 0;
}
.modal-body {
  position: relative;
  overflow: auto;
  padding: 0;
  max-height: 50vh;
}
.modal-icon {
  margin-right: 2.5em;
}
.modal-footer {
  margin-top: 2.5em;
}
.modal-footer .button {
  margin-right: 1.25em;
}
.modal-footer >* {
  margin-bottom: 0;
}
.modal-dismiss {
  position: absolute;
  top: 0;
  z-index: 9999;
  padding: 1.25em;
  border: 0;
  background-color: transparent;
  right: 0;
  cursor: pointer;
  fill: inherit;
  stroke-width: 0;
}
.modal-dismiss:hover {
  fill: #0072ff;
  stroke-width: 0;
}
.modal-container {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100vh;
  background-color: rgba(0,0,0,0.1);
  z-index: 999;
}
.modal-container.is-hidden {
  display: none;
}
.modal-container.is-visable {
  display: flex;
}
.modal.is-primary {
  background-color: #e5f1ff;
  color: #0072ff;
  fill: #0072ff;
  stroke-width: 0;
}
.modal.is-primary.is-outline {
  border-color: #0072ff;
  color: #0072ff;
  fill: #0072ff;
  stroke-width: 0;
}
.modal.is-primary:focus {
  border-color: #0061d9;
  box-shadow: 0 0 0 3px rgba(0,114,255,0.25);
}
.modal.is-secondary {
  background-color: #f9f9f9;
  color: #323c47;
  fill: #323c47;
  stroke-width: 0;
}
.modal.is-secondary.is-outline {
  border-color: #c7c7c7;
  color: #c7c7c7;
  fill: #c7c7c7;
  stroke-width: 0;
}
.modal.is-secondary:focus {
  border-color: #a9a9a9;
  box-shadow: 0 0 0 3px rgba(199,199,199,0.25);
}
.modal.is-info {
  background-color: #e4fcff;
  color: #00d4f0;
  fill: #00d4f0;
  stroke-width: 0;
}
.modal.is-info.is-outline {
  border-color: #00d4f0;
  color: #00d4f0;
  fill: #00d4f0;
  stroke-width: 0;
}
.modal.is-info:focus {
  border-color: #00b4cc;
  box-shadow: 0 0 0 3px rgba(0,212,240,0.25);
}
.modal.is-success {
  background-color: #e7fcf4;
  color: #18d88b;
  fill: #18d88b;
  stroke-width: 0;
}
.modal.is-success.is-outline {
  border-color: #18d88b;
  color: #18d88b;
  fill: #18d88b;
  stroke-width: 0;
}
.modal.is-success:focus {
  border-color: #14b876;
  box-shadow: 0 0 0 3px rgba(24,216,139,0.25);
}
.modal.is-warning {
  background-color: #fff6ee;
  color: #ffa557;
  fill: #ffa557;
  stroke-width: 0;
}
.modal.is-warning.is-outline {
  border-color: #ffa557;
  color: #ffa557;
  fill: #ffa557;
  stroke-width: 0;
}
.modal.is-warning:focus {
  border-color: #ff8a24;
  box-shadow: 0 0 0 3px rgba(255,165,87,0.25);
}
.modal.is-danger {
  background-color: #ffecec;
  color: #ff3d3d;
  fill: #ff3d3d;
  stroke-width: 0;
}
.modal.is-danger.is-outline {
  border-color: #ff3d3d;
  color: #ff3d3d;
  fill: #ff3d3d;
  stroke-width: 0;
}
.modal.is-danger:focus {
  border-color: #ff0e0e;
  box-shadow: 0 0 0 3px rgba(255,61,61,0.25);
}
.modal.is-black {
  background-color: #e6e6e6;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.modal.is-black.is-outline {
  border-color: #000;
  color: #000;
  fill: #000;
  stroke-width: 0;
}
.modal.is-black:focus {
  border-color: #000;
  box-shadow: 0 0 0 3px rgba(0,0,0,0.25);
}
.modal.is-white {
  background-color: #fff;
  color: #323c47;
  fill: #323c47;
  stroke-width: 0;
}
.modal.is-white.is-outline {
  border-color: #fff;
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.modal.is-white:focus {
  border-color: #d9d9d9;
  box-shadow: 0 0 0 3px rgba(255,255,255,0.25);
}
.modal.is-dark {
  background-color: #e8ebef;
  color: #323c47;
  fill: #323c47;
  stroke-width: 0;
}
.modal.is-dark.is-outline {
  border-color: #323c47;
  color: #323c47;
  fill: #323c47;
  stroke-width: 0;
}
.modal.is-dark:focus {
  border-color: #2a333c;
  box-shadow: 0 0 0 3px rgba(50,60,71,0.25);
}
.modal.is-light {
  background-color: #fefefe;
  color: #323c47;
  fill: #323c47;
  stroke-width: 0;
}
.modal.is-light.is-outline {
  border-color: #f5f5f5;
  color: #f5f5f5;
  fill: #f5f5f5;
  stroke-width: 0;
}
.modal.is-light:focus {
  border-color: #d0d0d0;
  box-shadow: 0 0 0 3px rgba(245,245,245,0.25);
}
.modal.is-outline {
  border-width: 1px;
  border-style: solid;
  background-color: transparent;
}
.navbar {
  display: flex;
  margin: 0;
  padding: 5px 10px;
  width: 100%;
  background-color: #fff;
}
.navbar.is-fixed {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  transition: 0.4s;
}
.navbar.is-inverse {
  background-color: #000;
}
.navbar.is-hidden {
  transform: translate3d(0, -100%, 0);
}
.navbar-brand,
.navbar-start,
.navbar-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}
.navbar-brand img {
  max-height: 100%;
}
.navbar-brand.is-white {
  filter: brightness(0) invert(1);
}
.navbar-start {
  flex: 1;
}
.navbar-item {
  display: block;
  padding: 0.5em 1em;
  color: #000;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  fill: #000;
  stroke-width: 0;
}
.navbar-item.dropdown {
  height: auto;
}
.navbar-item:hover,
.navbar-item:focus {
  color: #c7c7c7;
  fill: #c7c7c7;
  stroke-width: 0;
}
.navbar.is-inverse .navbar-item {
  color: #fff;
  fill: #fff;
  stroke-width: 0;
}
.navbar.is-inverse .navbar-item:hover,
.navbar.is-inverse .navbar-item:focus {
  color: #c7c7c7;
  fill: #c7c7c7;
  stroke-width: 0;
}
.navbar-item.is-active {
  border-bottom: 4px solid #c7c7c7;
  margin-bottom: -4px;
  color: #c7c7c7;
}
.pagination {
  display: flex;
  align-items: top;
  margin: 10px 0;
  flex-wrap: wrap;
}
.pagination-item,
.pagination-next,
.pagination-prev,
.pagination-first,
.pagination-last {
  position: relative;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  width: 2em;
  height: 2em;
  outline-width: 0;
  outline-offset: 0;
  border: none;
  text-decoration: none;
  cursor: pointer;
  background: #fff;
  font-size: inherit;
  fill: #000;
  stroke-width: 0;
}
.pagination-item.is-active,
.pagination-next.is-active,
.pagination-prev.is-active,
.pagination-first.is-active,
.pagination-last.is-active,
.pagination-item:active,
.pagination-next:active,
.pagination-prev:active,
.pagination-first:active,
.pagination-last:active,
.pagination-item:hover:not(.is-disabled),
.pagination-next:hover:not(.is-disabled),
.pagination-prev:hover:not(.is-disabled),
.pagination-first:hover:not(.is-disabled),
.pagination-last:hover:not(.is-disabled) {
  color: #0072ff;
  fill: #0072ff;
  stroke-width: 0;
}
.pagination-item.is-disabled,
.pagination-next.is-disabled,
.pagination-prev.is-disabled,
.pagination-first.is-disabled,
.pagination-last.is-disabled {
  border-color: #c1c1c1;
  color: #c1c1c1;
  fill: #c1c1c1;
  stroke-width: 0;
}
.pagination-item:focus,
.pagination-next:focus,
.pagination-prev:focus,
.pagination-first:focus,
.pagination-last:focus {
  outline-color: 0;
}
.pagination-item .icon,
.pagination-next .icon,
.pagination-prev .icon,
.pagination-first .icon,
.pagination-last .icon {
  width: 1.4em;
  height: 1.4em;
}
.content li + li {
  margin-top: 0.25em;
}
.content p:not(:last-child),
.content dl:not(:last-child),
.content ol:not(:last-child),
.content ul:not(:last-child),
.content blockquote:not(:last-child),
.content pre:not(:last-child),
.content table:not(:last-child) {
  margin-bottom: 1em;
  font-size: 1em;
}
.content h1 {
  font-size: 2.4em;
  margin-bottom: 0.5em;
}
.content h1:not(:first-child) {
  margin-top: 1em;
}
.content h2 {
  font-size: 2.2em;
  margin-bottom: 0.5714em;
}
.content h2:not(:first-child) {
  margin-top: 1.1428em;
}
.content h3 {
  font-size: 2em;
  margin-bottom: 0.6666em;
}
.content h3:not(:first-child) {
  margin-top: 1.8em;
}
.content h4 {
  font-size: 1.6em;
  margin-bottom: 0.8em;
}
.content h5 {
  font-size: 1.4em;
  margin-bottom: 0.8888em;
}
.content h6 {
  font-size: 1.2em;
  margin-bottom: 1em;
}
.content blockquote {
  border-left: 0.5em solid #0072ff;
  padding: 0.5em;
  margin: 0;
}
.content ol {
  list-style: decimal outside;
  margin-left: 1em;
  margin-top: 1em;
  padding: 0;
}
.content ul {
  list-style: disc outside;
  margin-left: 1em;
  margin-top: 1em;
  padding: 0;
}
.content ul ul {
  list-style-type: circle;
  margin-top: 0.5em;
}
.content ul ul ul {
  list-style-type: square;
}
.content dd {
  margin-left: 2em;
}
.content figure {
  margin-left: 2em;
  margin-right: 2em;
  text-align: center;
}
.content figure:not(:first-child) {
  margin-top: 2em;
}
.content figure:not(:last-child) {
  margin-bottom: 2em;
}
.content figure img {
  display: inline-block;
}
.content figure figcaption {
  font-style: italic;
}
.content pre {
  overflow-x: auto;
  padding: 0.5em;
  white-space: pre;
  word-wrap: normal;
}
.content sup,
.content sub {
  font-size: 75%;
}
.add-sticky {
  position: sticky;
  top: 10px;
}
.add-floatRight {
  float: right;
}
.add-floatLeft {
  float: left;
}
.add-flex {
  display: flex;
}
.add-justifyCenter {
  justify-content: center;
}
.add-justifyEnd {
  justify-content: flex-end;
}
.add-justifyStart {
  justify-content: flex-start;
}
.add-justifyAround {
  justify-content: space-around;
}
.add-justifyBetween {
  justify-content: space-between;
}
.add-alignCenter {
  align-items: center;
}
.add-alignEnd {
  align-items: flex-end;
}
.add-alignStart {
  align-items: flex-start;
}
.add-alignBaseline {
  align-items: baseline;
}
.add-alignStretch {
  align-items: stretch;
}
.add-padding {
  padding: 0.5em !important;
}
.add-paddingTop {
  padding-top: 0.5em !important;
}
.add-paddingBottom {
  padding-bottom: 0.5em !important;
}
.add-paddingRight {
  padding-right: 0.5em !important;
}
.add-paddingLeft {
  padding-left: 0.5em !important;
}
.add-margin {
  margin: 10px !important;
}
.add-marginTop {
  margin-top: 10px !important;
}
.add-marginBottom {
  margin-bottom: 10px !important;
}
.add-marginRight {
  margin-right: 10px !important;
}
.add-marginLeft {
  margin-left: 10px !important;
}
.no-padding {
  padding: 0 !important;
}
.no-paddingTop {
  padding-top: 0 !important;
}
.no-paddingBottom {
  padding-bottom: 0 !important;
}
.no-paddingRight {
  padding-right: 0 !important;
}
.no-paddingLeft {
  padding-left: 0 !important;
}
.no-margin {
  margin: 0 !important;
}
.no-marginTop {
  margin-top: 0 !important;
}
.no-marginBottom {
  margin-bottom: 0 !important;
}
.no-marginRight {
  margin-right: 0 !important;
}
.no-marginLeft {
  margin-left: 0 !important;
}
::selection {
  color: inherit;
}
.button {
  white-space: nowrap;
}
.header {
  width: 100%;
  padding: 50px;
  color: #fff;
}
.header-title {
  font-size: 50px;
  line-height: 1em;
  margin: 20px 0;
  font-weight: lighter;
}
.header-content {
  font-size: 16px;
  margin-bottom: 50px;
  font-weight: lighter;
}
.header-image >img {
  width: 100%;
}
.header,
.header.is-red {
  background-image: linear-gradient(30deg, #ff3d3d, #ffdd57);
}
.header.is-black {
  background-image: linear-gradient(30deg, #000, #4d4d4d);
}
.header.is-green {
  background-image: linear-gradient(30deg, #18d88b, #ffdd57);
}
.header.is-blue {
  background-image: linear-gradient(30deg, #0072ff, #4d9cff);
}
.header.is-white {
  background-image: linear-gradient(45deg, #e6e6e6, #fff);
}
.section {
  padding: 20px 30px;
}
.section-title {
  font-size: 30px;
  color: #323c47;
}
.section-paragraph {
  font-size: 16px;
  color: #526375;
}
.section.is-red {
  background: #ff3d3d;
}
.section.is-black {
  background: #000;
}
.section.is-green {
  background: #18d88b;
}
.section.is-blue {
  background: #0072ff;
}
.section.is-white {
  background: #fff;
}
.social {
  padding: 100px 0;
}
.social-number {
  font-size: 50px;
  margin: 20px 0 50px;
}
.social-item {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.social-title {
  font-size: 30px;
  margin: 30px 0;
  text-align: center;
}
.social-content {
  font-size: 20px;
  margin: 0 0 40px;
  text-align: center;
}
.social-logo {
  width: 100%;
  margin: 20px 0;
}
.social-quote {
  font-size: 30px;
  color: #000;
  quotes: "\201C" "\201D" "\2018" "\2019";
}
.social-quote:before {
  content: open-quote;
  margin-right: 20px;
  font-size: 40px;
}
.social-quote:after {
  content: close-quote;
  margin-left: 20px;
  font-size: 40px;
}
.social.is-red {
  background: #ff3d3d;
}
.social.is-black {
  background: #000;
}
.social.is-green {
  background: #18d88b;
}
.social.is-blue {
  background: #0072ff;
}
.user {
  display: flex;
  align-items: center;
  margin: 10px 0;
}
.user.is-alt {
  justify-content: center;
  flex-direction: column;
}
.user-avatar {
  border-radius: 50%;
  width: 60px;
  height: 60px;
  margin-right: 20px;
  flex-shrink: 0;
  overflow: hidden;
}
.is-alt .user-avatar {
  margin: 0 0 20px;
}
.user-data {
  text-align: left;
  white-space: nowrap;
}
.is-alt .user-data {
  text-align: center;
}
.user-name {
  font-size: 16px;
  color: #000;
  margin: 5px 0;
}
.user-caption {
  font-size: 16px;
  color: #c1c1c1;
  margin: 0 0 5px;
}
.add-center-horizontal {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
.add-center-vertical {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
}
.add-padding {
  padding: 20px;
}
.add-text-center {
  text-align: center;
}
.add-full-width {
  width: 100%;
}
.is-active img {
  opacity: 1;
  transition: 0.4s;
}
.is-active p,
.is-active h1,
.is-active h2,
.is-active h3,
.is-active h6,
.is-active b {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: 0.4s;
}
.is-inactive img {
  opacity: 0;
  transition: 0.4s;
}
.is-inactive p,
.is-inactive h1,
.is-inactive h2,
.is-inactive h3,
.is-inactive h6,
.is-inactive b {
  opacity: 0;
  transform: translate3d(0, -200px, 0);
  transition: 0.4s;
}
.column {
  transition: 0.2s;
}


.vuse-icon {
  display: block;
  width: 20px;
  height: 20px;
}
.uploader {
  position: relative;
  cursor: pointer;
  outline: none;
}
.uploader-input {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  opacity: 0;
  z-index: 100;
  cursor: pointer;
}
.uploader >img {
  width: 100%;
  display: block;
}
.uploader:hover {
  box-shadow: 0 0 0 2px #c1c1c1;
}


/*# sourceMappingURL=style.css.map*/

================================================
FILE: docs/API.md
================================================
# API

Your section components will have some properties injected to help you customize their behavior in building phase and production/render phase.

## $section

An instance of the [section class](https://github.com/baianat/vuse/blob/master/src/js/section.js) that represents this component.

## $builder

An instance of the singleton [builder class](https://github.com/baianat/vuse/blob/master/src/js/builder.js)

## $sectionData

Is a computed property that mirrors `$section.data` which contains the current values (text, images, etc...) for the section.


================================================
FILE: docs/README.md
================================================
---
home: true
actionText: Getting Started →
actionLink: ./getting-started
heroImage: /img/logo.png
---


================================================
FILE: docs/example.md
================================================
---
navbar: true
sidebar: false
editLink: false
pageClass: example
---

<vuse-builder @saved="onSave"></vuse-builder>

<script>
export default {
  methods: {
    onSave (vuse) {
      vuse.export('preview');
    }
  }
}
</script>

<style>
.example .content {
  padding: 0 !important;
  margin: 0 !important;
  max-width: 100% !important;
}
.example .page {
  padding: 0 !important;
}
.example .page-edit {
 display: none !important;
}
.example .menu {
  margin: 0;
}
</style>


================================================
FILE: docs/exporting.md
================================================
# Exporting

There are three ways to export the built page: preview, pwa or json. When clicking the save button the `b-builder` component emits a saved event with the builder instance as its payload, which exposes an `export` method.

```html
<div id="app">
  <b-builder @saved="onSave"></b-builder>
</div>

<script>
  new Vue({
  el: '#app',
  methods: {
    onSave (builder) {
      // you can use 'preview', 'pwa' or 'json' strings
      // 'json' is the default exporting mode
      builder.export('preview');
    }
  }
});
</script>
```

================================================
FILE: docs/getting-started.md
================================================
# getting-started

## What is this

This builder (sections builder) reuses your Vue components as **editable sections** to produce an interactive page builder to the end user, you can use it as a prototyping tool as well as it is sort-of a block builder.

The user/developer can then export the builder for usability in multiple formats, the following are the officially supported ones:

- `json` A json object which can be later used to re-render a page, particularly useful if you plan to have dynamic pages or want to store them in a Database.
- `preview` opens a new page without the editable logic in new tab to see the end result.
- `pwa` produces a zip file which contains all the page files and images neatly packed, this is probably the format you will use for page/prototype landing page builder, The project is augmented by default with service workers to support offline viewing.

The builder is just a Vue plugin, so you can integrate this into your own projects without needing to create separate bundles for it.

## Installation

### Package managers

First step is to install it using `yarn` or `npm`:

```bash
npm install vuse

# or use yarn
yarn add vuse
```

### CDNs

Or add it as a script tag in your projects.

- [unpkg](https://unpkg.com/vuse)

```html
<script src="https://unpkg.com/vue@2.4.2"></script>
<script src="https://unpkg.com/vuse"></script>
```

### Usage

::: tip
  If you added it using a script tag, you can skip this section. as it will be auto-installed for you
:::

```js
import Builder from 'vuse';

Vue.use(Builder);
```

You can start using the `b-builder` component to build things now.

This package does not include any sections. The builder is just a system of helpers for managing customizable sections, seeding fake data, exporting views and re-rendering them. The logic for your components/sections is written by you eventually. **we will be adding a huge number of sections soon to be used with this one**. You can use the included examples after reading the API to build your own for now.

================================================
FILE: docs/section.md
================================================
# Section

A section is the building block of the page, below is an example of a header section.
::: tip
  Examples use [pug](https://pugjs.org) template language to make it easier to work with templates.
:::

```pug
<template lang="pug">
  section.header(
    v-styler="$sectionData.classes"
    :class="[{'is-editable': $builder.isEditing}, $sectionData.classes]"
  )
    .container
      .grid
        .column.is-desktop-6.add-center-vertical
          h3.header-title(
            :class="{'is-editable': $builder.isEditing}"
            v-html="$sectionData.title"
            v-styler="$sectionData.title"
          )
          p.header-content(
            :class="{'is-editable': $builder.isEditing}"
            v-html="$sectionData.content"
            v-styler="$sectionData.content"
          )
          a.button(
            :class="[{'is-editable': $builder.isEditing}, $sectionData.button.classes]"
            :href="$sectionData.button.href"
            v-html="$sectionData.button.text"
            v-styler="$sectionData.button"
          )
        .column.is-desktop-6
          uploader(
            class="header-image"
            path="$sectionData.images[0]"
          )
</template>

<script>
  import { types } from 'vuse';

  export default {
    name: 'hero1',
    cover: '../covers/hero1.png',
    $schema: {
      title: types.Title,
      content: types.Text,
      images: [types.Image],
      button: types.Button,
      classes: types.ClassList
    },
    props: {
      id: {
        type: Number,
        required: true
      }
    }
  };
</script>
```

Each section has several elements that can be edited. Section data are stored in `$sectionData` object which is reactive.

## Adding the ability to edit elements in a section

1. Add `is-editable` class to it. Since editable state can be toggled off/on, it's always good to bind `is-editable` class to change when editing mode changes. e.g. `:class="{'is-editable': $builder.isEditing}"`
1. Add [`v-styler`](https://github.com/baianat/builder#v-styler) directive to the element
1. Bind the element’s innerHTML with its equivalent data e.g. `v-html="$sectionData.button.text"`
1. If you have any other data that `v-styler` changes, you have to bind it too. e.g. `:href="$sectionData.button.href"`

Putting it all together

```html
  <a
    :class="[{'button', 'is-editable': $builder.isEditing}, $sectionData.button.classes]"
    :href="$sectionData.button.href"
    v-html="$sectionData.button.text"
    v-styler="$sectionData.button"
  ></a>
```

After creating the HTML structure, you should configure the section schema to use the built-in seeder to provide you with initial/fake values when the component is instantiated in build/edit mode. Or you can set the initial values yourself instead of seeding them.

```html
<script>
  import { types } from 'vuse';

  export default {
    // section name
    name: 'hero1',
    // section cover image
    cover: '../cover-hero1.png',
    // group multiple sections
    group: 'heros',
    // section data schema
    $schema: {
      // main title
      title: types.Text,
      // main content
      content: types.Text,
      // section classes
      classes: types.ClassList,
      // array of section's images
      images: [
        types.Image,
        types.Image
      ],
      // object holds button data, href etc..
      button: types.Button,
      // if section has many columns you can use
      // a columns array to separate each column's data
      columns: [
      {
        title: types.Title,
        content: types.Text,
        group: types.group
      },
      {
        title: types.Title,
        group: types.group
      }
    ]
    },
    props: {
         id: {       type: Number,       required: true     } // it is required to have an id prop.
    }
  };
</script>
```

## Using the section

Until now, we have only been creating our section component, we now need to introduce it to our builder so it can use it:

```js
import Builder from 'vuse';
import section from './components/sections/section';

// Builder has Vue-like API when registering components.
Builder.component(section);
Vue.use(Builder);

new Vue({
  el: '#app'
});
```

```html
<div id="app">
  <b-builder></b-builder>
</div>
```

You only have to register the component on the Builder plugin, which has a Vue-like API. This ensures your Vue global scope isn't polluted by the builder and keeps everything contained within the `b-builder` component.

================================================
FILE: docs/styler.md
================================================
# Styler

This directive is automatically injected in your section components, and can be used to facilitate editing elements greatly, since it has support for multiple element types like `div`, `a`, `button` and `p` tags as well.

To tell styler which variable to update, you pass it as directive expression e.g. `v-styler="$sectionData.button"`

The styler directive has four types `text`, `button`, `section` or `grid`. By default, the directive can know the type implicitly, from the element tag or from the provided schema. 

If you want to explicitly specify the type, you can pass it as a directive modifier e.g. `v-styler.button="$sectionData.button"`.

## How to use

coming soon...


================================================
FILE: package.json
================================================
{
  "name": "vuse",
  "version": "0.1.1",
  "description": "Vue.js Page Builder",
  "author": "Abdelrahman Ismail <abdelrahman3d@gmail.com>",
  "module": "dist/vuse.esm.js",
  "unpkg": "dist/vuse.min.js",
  "main": "dist/vuse.js",
  "scripts": {
    "dev": "webpack-dev-server --hot --inline --config ./demo/webpack.config.js",
    "build": "cross-env NODE_ENV=production node scripts/build.js",
    "build:demo": "cross-env NODE_ENV=production webpack --config ./demo/webpack.config.js",
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs",
    "docs:deploy": "scripts/deploy.sh",
    "lint": "eslint ./src --fix"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-rc.1",
    "@babel/plugin-proposal-class-properties": "^7.0.0-rc.1",
    "@babel/plugin-proposal-object-rest-spread": "^7.0.0-rc.1",
    "@babel/preset-env": "^7.0.0-rc.1",
    "babel-loader": "^8.0.0-beta",
    "chalk": "^2.4.1",
    "clean-webpack-plugin": "^0.1.19",
    "copy-webpack-plugin": "^4.5.1",
    "cross-env": "^5.0.5",
    "css-loader": "^1.0.0",
    "eslint": "^5.3.0",
    "eslint-config-standard": "^11.0.0",
    "eslint-loader": "^2.1.0",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-node": "^7.0.1",
    "eslint-plugin-promise": "^3.5.0",
    "eslint-plugin-standard": "^3.0.1",
    "eslint-plugin-vue": "^4.7.1",
    "file-loader": "^1.1.11",
    "filesize": "^3.6.1",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "gzip-size": "^5.0.0",
    "html-webpack-plugin": "^4.0.0-alpha",
    "mini-css-extract-plugin": "^0.4.4",
    "mkdirp": "^0.5.1",
    "progress-bar-webpack-plugin": "^1.10.0",
    "pug": "^2.0.0-rc.3",
    "pug-plain-loader": "^1.0.0",
    "rollup": "^0.64.1",
    "rollup-plugin-buble": "^0.19.2",
    "rollup-plugin-commonjs": "^9.1.5",
    "rollup-plugin-css-only": "^0.4.0",
    "rollup-plugin-node-resolve": "^3.0.0",
    "rollup-plugin-replace": "^2.0.0",
    "rollup-plugin-uglify": "^4.0.0",
    "rollup-plugin-vue": "^4.3.2",
    "style-loader": "^0.22.1",
    "stylus": "^0.54.5",
    "stylus-loader": "^3.0.1",
    "stylus-relative-loader": "^3.4.0",
    "util": "^0.11.0",
    "vue": "^2.5.17",
    "vue-loader": "^15.3.0",
    "vue-template-compiler": "^2.5.17",
    "vuepress": "^0.14.8",
    "webpack": "^4.16.5",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.5"
  },
  "dependencies": {
    "@baianat/base.framework": "^2.0.0-beta.0",
    "intersection-observer": "^0.5.0",
    "jszip": "^3.1.4",
    "lodash-es": "^4.17.4",
    "popper.js": "^1.14.4",
    "save-as": "^0.1.8",
    "sortablejs": "^1.6.1",
    "vue-server-renderer": "2.5.17"
  },
  "license": "MIT",
  "files": [
    "dist/*.js",
    "dist/*.css"
  ],
  "keywords": [
    "page-builder",
    "vuejs",
    "ES6"
  ],
  "maintainers": [
    {
      "name": "Abdelrahman Awad",
      "email": "logaretm1@gmail.com"
    },
    {
      "name": "Abdelrahman Ismail",
      "email": "abdelrahman3d@gmail.com"
    }
  ]
}


================================================
FILE: scripts/build.js
================================================
const chalk = require('chalk');
const mkdirpNode = require('mkdirp');
const { promisify } = require('util');
const { rollup } = require('rollup');
const { paths, configs, utils } = require('./config');
const mkdirp = promisify(mkdirpNode);

async function buildConfig (build) {
  await mkdirp(paths.dist);
  const bundleName = build.output.file.replace(paths.dist, '');
  console.log(chalk.cyan(`📦  Generating ${bundleName}...`));

  const bundle = await rollup(build.input);
  await bundle.write(build.output);

  console.log(chalk.green(`👍  ${bundleName} ${utils.stats({ path: build.output.file })}`));
}

async function build () {
  await Promise.all(Object.keys(configs).map(key => {
    return buildConfig(configs[key]).catch(err => {
      console.log(err);
    });
  }));
  process.exit(0);
}

build();


================================================
FILE: scripts/config.js
================================================
const path = require('path');
const fs = require('fs');
const replace = require('rollup-plugin-replace');
const vue = require('rollup-plugin-vue').default;
const resolve = require('rollup-plugin-node-resolve');
const css = require('rollup-plugin-css-only');
const buble = require('rollup-plugin-buble');
const commonjs = require('rollup-plugin-commonjs');
const filesize = require('filesize');
const gzipSize = require('gzip-size');
const { uglify } = require('rollup-plugin-uglify');

const version = process.env.VERSION || require('../package.json').version;

const common = {
  banner:
    `/**
    * Vuse v${version}
    * (c) ${new Date().getFullYear()} Baianat
    * @license MIT
    */`,
  paths: {
    input: path.join(__dirname, '../src/index.js'),
    src: path.join(__dirname, '../src/'),
    dist: path.join(__dirname, '../dist/')
  },
  builds: {
    umd: {
      file: 'vuse.js',
      format: 'umd',
      name: 'vuse',
      env: 'development'
    },
    umdMin: {
      file: 'vuse.min.js',
      format: 'umd',
      name: 'vuse',
      env: 'production'
    },
    esm: {
      input: path.join(__dirname, '../src/index.esm.js'),
      file: 'vuse.esm.js',
      format: 'es'
    }
  }
};

function genConfig (options) {
  const config = {
    description: '',
    input: {
      input: options.input || common.paths.input,
      plugins: [
        commonjs(),
        replace({ __VERSION__: version }),
        css(),
        vue({ css: false }),
        resolve(),
        buble()
      ]
    },
    output: {
      banner: common.banner,
      name: options.name,
      format: options.format,
      file: path.join(common.paths.dist, options.file)
    }
  };

  if (options.env) {
    config.input.plugins.unshift(replace({
      'process.env.NODE_ENV': JSON.stringify(options.env)
    }));
  }

  if (options.env === 'production') {
    config.input.plugins.push(uglify());
  }

  return config;
};

const configs = Object.keys(common.builds).reduce((prev, key) => {
  prev[key] = genConfig(common.builds[key]);

  return prev;
}, {});

module.exports = {
  configs,
  uglifyOptions: common.uglifyOptions,
  paths: common.paths,
  utils: {
    stats ({ path }) {
      const code = fs.readFileSync(path);
      const { size } = fs.statSync(path);
      const gzipped = gzipSize.sync(code);

      return `| Size: ${filesize(size)} | Gzip: ${filesize(gzipped)}`;
    }
  }
};


================================================
FILE: scripts/deploy.sh
================================================
#!/usr/bin/env sh

set -e

npm run docs:build

cd docs/.vuepress/dist

git init
git add -A
git commit -m 'deploy'

git push -f git@github.com:baianat/vuse.git master:gh-pages

cd -

================================================
FILE: src/components/VuseBuilder.vue
================================================
<template lang="pug">
  div
    div#artboard.artboard(
      ref="artboard"
      :class="{ 'is-sorting': $builder.isSorting, 'is-editable': $builder.isEditing }"
    )
      component(v-for='section in $builder.sections'
        :is='section.name'
        :key='section.id'
        :id='section.id'
      )

    .controller
      .controller-intro(v-if="showIntro && !this.$builder.sections.length")
        label(for="projectName") Hello, start your project
        input.controller-input(
          id="projectName"
          placeholder="project name"
          v-model="title"
        )
        template(v-if="themes")
          .controller-themes
            button.controller-theme(
              v-for="theme in themes"
              @click="addTheme(theme)"
            )
              | {{ theme.name }}

      .controller-panel
        button.controller-button.is-green(
          tooltip-position="top"
          tooltip="export"
          @click="submit"
        )
          VuseIcon(name='download')
        button.controller-button.is-red(
          v-if="!tempSections"
          tooltip-position="top"
          tooltip="clear sections"
          @click="clearSections"
        )
          VuseIcon(name='trash')
        button.controller-button.is-gray(
          v-if="tempSections"
          tooltip-position="top"
          tooltip="undo"
          @click="undo"
        )
          VuseIcon(name='undo')
        button.controller-button.is-blue(
          tooltip-position="top"
          tooltip="sorting"
          :class="{ 'is-red': $builder.isSorting }"
          @click="toggleSort"
        )
          VuseIcon(name='sort')
        button.controller-button.is-blue(
          tooltip-position="top"
          tooltip="add section"
          :class="{ 'is-red': listShown, 'is-rotated': listShown }"
          :disabled="!$builder.isEditing"
          @click="newSection"
        )
          VuseIcon(name='plus')

    ul.menu(:class="{ 'is-visiable': listShown }" ref="menu")
      li.menu-group(v-for="(group, name) in groups"  v-if="group.length")
        .menu-header(@click="toggleGroupVisibility")
          span.menu-title {{ name }}
          span.menu-icon
            VuseIcon(name='arrowDown')
        .menu-body
          template(v-for="section in group")
            a.menu-element(
              @click="addSection(section)"
              @drag="currentSection = section"
            )
              img.menu-elementImage(v-if="section.cover" :src="section.cover")
              span.menu-elementTitle {{ section.name }}

</template>

<script>
import Sortable from 'sortablejs';
import VuseIcon from './VuseIcon';

export default {
  name: 'VuseBuilder',
  components: {
    VuseIcon
  },
  props: {
    showIntro: {
      type: Boolean,
      default: true
    },
    data: {
      type: Object,
      default: () => ({
        title: '',
        sections: []
      })
    }
  },
  data () {
    return {
      title: null,
      listShown: false,
      tempSections: null,
      sections: this.getSections(),
      currentSection: '',
      groups: {}
    }
  },

  watch: {
    title (value) {
      this.$builder.title = value;
      document.title = value;
    }
  },
  created () {
    // sets the initial data.
    this.$builder.set(this.data);
    this.title = this.$builder.title;
    this.themes = this.$builder.themes;
    this.generateGroups();
  },
  mounted () {
    this.$builder.rootEl = this.$refs.artboard;
    const groups = this.$refs.menu.querySelectorAll('.menu-body');
    const _self = this;
    groups.forEach((group) => {
      Sortable.create(group, {
        group: {
          name: 'sections-group',
          put: false,
          pull: 'clone'
        },
        sort: false
      });
    });
    this.sortable = Sortable.create(this.$refs.artboard, {
      group: {
        name: 'artboard',
        put: 'sections-group'
      },
      animation: 150,
      scroll: true,
      scrollSpeed: 10,
      sort: false,
      disabled: true,
      preventOnFilter: false,
      onAdd (evt) {
        _self.addSection(_self.currentSection, evt.newIndex);
        evt.item.remove();
      },
      onUpdate (evt) {
        _self.$builder.sort(evt.oldIndex, evt.newIndex);
      }
    });
  },

  updated () {
    if (this.$builder.scrolling) {
      this.$builder.scrolling(this.$refs.artboard);
    }
  },

  beforeDestroy () {
    this.$builder.clear();
  },
  methods: {
    newSection () {
      // add the section immediatly if none are present.
      if (this.sections.length === 1) {
        this.addSection(this.sections[0]);
        return;
      }
      this.toggleListVisibility();
    },
    addSection (section, position) {
      this.$builder.add(section, position);
    },
    clearSections () {
      this.tempSections = this.$builder.clear();
      setTimeout(() => {
        this.tempSections = null;
      }, 5000);
    },
    undo () {
      this.$builder.sections = this.tempSections;
      this.tempSections = null;
    },
    addTheme (theme) {
      this.$builder.set(theme);
    },
    toggleSort () {
      this.$builder.isSorting = !this.$builder.isSorting;
      this.$builder.isEditing = !this.$builder.isSorting;
      if (!this.$builder.isSorting && this.sortable) {
        this.sortable.option('sort', false);
        this.sortable.option('disabled', true);
        return;
      }
      this.sortable.option('disabled', false);
      this.sortable.option('sort', true);
    },
    toggleListVisibility () {
      this.listShown = !this.listShown;
      this.sortable.option('disabled', !this.listShown);
    },
    showList () {
      this.listShown = true;
      this.sortable.option('disabled', false);
    },
    hideList () {
      this.listShown = false;
      this.sortable.option('disabled', true);
    },
    toggleGroupVisibility (e) {
      const element = e.target;
      const group = element.closest('.menu-group');
      group.classList.toggle('is-visiable');
    },
    submit () {
      this.$emit('saved', this.$builder);
    },
    generateGroups () {
      let groups = { random: [] };

      // group sections together
      this.sections.forEach((section) => {
        let sectionGroup = section.group;
        if (!sectionGroup) {
          groups.random.push(section);
          return;
        }
        if (!groups[sectionGroup]) {
          groups[sectionGroup] = [section];
          return;
        }
        groups[sectionGroup].push(section);
      })
      this.groups = groups;
    },
    getSections () {
      let sections = [];

      // get sections data
      sections = Object.keys(this.$builder.components).map((sec) => {
        return {
          name: sec,
          group: this.$builder.components[sec].options.group,
          cover: this.$builder.components[sec].options.cover,
          schema: this.$builder.components[sec].options.$schema
        }
      });
      return sections;
    }
  }
};
</script>

<style lang="stylus">
@import '../stylus/_app.styl'

.artboard
  transform-origin: top center
  &.is-editable .is-editable
    outline: none
    &:hover
      box-shadow: inset 0 0 0 2px $gray
.controller
  box-sizing: border-box
  &-panel
    position: fixed
    z-index: 200
    bottom: 30px
    right: 40px
  &-input
    outline: none
    border: 1px solid $gray
    padding: 0.5em 1em
    margin: 20px 0
    border-radius: 40px
    width: 100%
    font-size: 16px
    &:focus
      border-color: $blue
      box-shadow: 0 0 0 2px alpha($blue, 50%)
  &-button
    transition: 0.2s
    border: none
    outline: none
    border-radius: 20px
    padding: 5px
    color: $white
    fill: $white
    font-size: 16px
    svg
      transition: 0.2s
    &:not(:last-child)
      margin-right: 20px
    &.is-rotated >svg
      transform: rotate(45deg)
    &:hover
      @extends $floatHover
    &.is-blue
      background-color: $blue
      &:hover
        background-color: darken($blue, 20%)
    &.is-red
      background-color: $red
      &:hover
        background-color: darken($red, 20%)
    &.is-green
      background-color: $green
      &:hover
        background-color: darken($green, 20%)
    &.is-dark
      background-color: $dark
      &:hover
        background-color: darken($dark, 20%)
    &.is-gray
      background-color: $gary
      &:hover
        background-color: darken($gray, 20%)
  &-intro
    width: 100%
    max-width: 500px
    margin: auto
    display: flex
    justify-content: center
    align-items: center
    flex-direction: column
    padding: 70px 50px
    text-align: center
    font-size: 30px
    color: $dark

  &-themes
    display: flex
    flex-direction: column
    width: 100%

  &-theme
    background-color: $white
    color: $dark
    border: 1px solid $gray
    margin: 5px
    padding: 20px
    border-radius: 4px
    width: 100%
    cursor: pointer
    font-size: 16px
    &:hover
      border-color: $blue
.menu
  user-select: none
  -moz-user-select: none
  position: fixed
  z-index 300
  top: 0
  left: 0
  bottom: 0
  margin: 0
  width: 250px
  background: $white
  padding: 20px 10px
  display: flex
  flex-direction: column
  overflow-y: auto
  list-style: none
  transition: 0.4s
  box-shadow: 1px 0 10px alpha($dark, 20%)
  transform: translate3d(-100%, 0, 0)
  &.is-visiable
    transform: translate3d(0, 0, 0)
  &-body
    display: none
    padding: 0
    margin: 0
    list-style: none
    ~/-group &
      width: 90%
      margin: 10px auto
    ~/-group.is-visiable &
      display: block
  &-icon
    width: 24px
    height: 24px
    fill: $gray
    transition: 0.2s
    ~/-group.is-visiable &
      transform: rotate(180deg)

  &-element
    position: relative
    display: flex
    justify-content: center
    align-items: center
    width: 100%
    min-height: 50px
    border-radius: 5px
    background: darken($gray, 10%)
    transition: 0.3s
    cursor: pointer
    color: $white
    overflow: hidden
    user-select: none
    -moz-user-select: none
    &:not(:last-child)
      margin-bottom: 10px
    &:hover
      @extends $floatHover

  &-elementImage
    max-width: 100%
    pointer-events: none
    +
      ~/-elementTitle
        position: absolute
        right: 0
        bottom: 0
        left: 0
        text-shadow: 1px 1px 2px alpha($black, 80%)
        text-align: center
        padding: 5px

  &-header
    display: flex
    justify-content: space-between
    align-items: center
    padding: 10px 5px
    border-bottom: 1px solid alpha($black, 5%)

.sortable-ghost
  opacity: 0.3
  box-shadow: 0 0 2px 1px $blue

.is-editable
  &:hover
    box-shadow: inset 0 0 0 2px $gray
</style>


================================================
FILE: src/components/VuseIcon.js
================================================
const icons = {
  plus: 'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z',
  tic: 'M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z',
  sort: 'M14 5h8v2h-8zm0 5.5h8v2h-8zm0 5.5h8v2h-8zM2 11.5C2 15.08 4.92 18 8.5 18H9v2l3-3-3-3v2h-.5C6.02 16 4 13.98 4 11.5S6.02 7 8.5 7H12V5H8.5C4.92 5 2 7.92 2 11.5z',
  link: 'M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z',
  palettes: 'M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z',
  close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
  bold: 'M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z',
  italic: 'M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z',
  underline: 'M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z',
  center: 'M7 15v2h10v-2H7zm-4 6h18v-2H3v2zm0-8h18v-2H3v2zm4-6v2h10V7H7zM3 3v2h18V3H3z',
  left: 'M15 15H3v2h12v-2zm0-8H3v2h12V7zM3 13h18v-2H3v2zm0 8h18v-2H3v2zM3 3v2h18V3H3z',
  right: 'M3 21h18v-2H3v2zm6-4h12v-2H9v2zm-6-4h18v-2H3v2zm6-4h12V7H9v2zM3 3v2h18V3H3z',
  trash: 'M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.13-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z',
  align: 'M3 21h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18v-2H3v2zm0-4h18V7H3v2zm0-6v2h18V3H3z',
  textStyle: 'M23 7V1h-6v2H7V1H1v6h2v10H1v6h6v-2h10v2h6v-6h-2V7h2zM3 3h2v2H3V3zm2 18H3v-2h2v2zm12-2H7v-2H5V7h2V5h10v2h2v10h-2v2zm4 2h-2v-2h2v2zM19 5V3h2v2h-2zm-5.27 9h-3.49l-.73 2H7.89l3.4-9h1.4l3.41 9h-1.63l-.74-2zm-3.04-1.26h2.61L12 8.91l-1.31 3.83z',
  section: 'M10 18h5v-6h-5v6zm-6 0h5V5H4v13zm12 0h5v-6h-5v6zM10 5v6h11V5H10z',
  arrowDown: 'M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z',
  arrowRight: 'M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z',
  arrowLeft: 'M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z',
  mobile: 'M15.5 1h-8C6.12 1 5 2.12 5 3.5v17C5 21.88 6.12 23 7.5 23h8c1.38 0 2.5-1.12 2.5-2.5v-17C18 2.12 16.88 1 15.5 1zm-4 21c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm4.5-4H7V4h9v14z',
  tablet: 'M21 4H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h18c1.1 0 1.99-.9 1.99-2L23 6c0-1.1-.9-2-2-2zm-2 14H5V6h14v12z',
  laptop: 'M20 18c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z',
  monitor: 'M21 2H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h7v2H8v2h8v-2h-2v-2h7c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H3V4h18v12z',
  download: 'M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z',
  eye: 'M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z',
  undo: 'M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z'
};

export default {
  functional: true,
  props: {
    name: {
      type: String,
      required: true,
      validator: (val) => {
        if (!(val in icons) && process.env.NODE_ENV !== 'production') {
          console.warn(`Invalid icon name "${val}"`);
          return false;
        }

        return true;
      }
    }
  },
  render (h, { props }) {
    const path = h('path', {
      attrs: {
        d: icons[props.name]
      }
    });

    return h(
      'svg',
      {
        attrs: {
          version: '1.1',
          xmlns: 'http://www.w3.org/2000/svg',
          class: 'vuse-icon',
          viewBox: '0 0 24 24'
        }
      },
      [path]
    );
  }
};


================================================
FILE: src/components/VuseRenderer.vue
================================================
<template lang="pug">
  #artboard.artboard
    component(v-for='section in $builder.sections'
      :is='section.name'
      :key='section.id'
      :id='section.id'
    )
</template>

<script>
export default {
  name: 'VuseRenderer',
  props: {
    data: {
      type: Object,
      default: () => ({
        title: '',
        sections: []
      })
    }
  },
  created () {
    this.$builder.set(this.data);
    this.$builder.isEditing = false;
    this.$builder.isRendered = true;
  }
};
</script>


================================================
FILE: src/components/VuseStyler.vue
================================================
<template lang="pug">
  .styler(
    ref="styler"
    id="styler"
    v-if="$builder.isEditing"
    :class="{ 'is-visible': isVisible }"
    @click.stop=""
  )
    ul.styler-list
      li(v-if="type === 'button' || type === 'section'")
        button.styler-button(@click="updateOption('colorer')")
          VuseIcon(name='palettes')
      li(v-if="type === 'button'")
        button.styler-button(@click="updateOption('link')")
          VuseIcon(name='link')
      li(v-if="type === 'header' || type === 'section'")
        button.styler-button(@click="removeSection")
          VuseIcon(name='trash')
      template(v-if="type === 'text'")
        li: button.styler-button(@click="updateOption('textColor')")
            VuseIcon(name='palettes')
        li: button.styler-button(@click="updateOption('align')")
            VuseIcon(name='align')
        li: button.styler-button(@click="updateOption('textStyle')")
            VuseIcon(name='textStyle')
      template(v-if="type === 'grid'")
        li: button.styler-button(@click="selectDevice('mobile')")
            VuseIcon(name='mobile')
        //- li: button.styler-button(@click="selectDevice('tablet')")
        //-     VuseIcon(name='tablet')
        li: button.styler-button(@click="selectDevice('desktop')")
            VuseIcon(name='laptop')
        //- li: button.styler-button(@click="selectDevice('widescreen')")
        //-     VuseIcon(name='monitor')

    ul.styler-list
      li(v-if="currentOption === 'colorer'")
        ul.colorer
          li(v-for="color in colors")
            input(
              type="radio"
              :id="`color${color.charAt(0).toUpperCase() + color.slice(1)}`"
              name="colorer"
              :value="color"
              v-model="colorerColor"
            )
      li(v-if="currentOption === 'textColor'")
          ul.colorer
            li(v-for="(color, index) in colors")
              input(
                type="radio"
                :id="`color${color.charAt(0).toUpperCase() + color.slice(1)}`"
                name="colorer"
                :value="textColors[index]"
                v-model="textColor"
                )
      li(v-if="currentOption === 'link'")
        .input-group.is-rounded.has-itemAfter.is-primary
          input.input(type="text" placeholder="type your link" v-model="url")
          button.button(@click="addLink")
            VuseIcon(name='link')

      li(v-if="currentOption === 'align'")
        ul.align
          li: button.styler-button(@click="execute('justifyleft')")
            VuseIcon(name='left')
          li: button.styler-button(@click="execute('justifycenter')")
            VuseIcon(name='center')
          li: button.styler-button(@click="execute('justifyright')")
            VuseIcon(name='right')

      li(v-if="currentOption === 'textStyle'")
        ul.align
          li: button.styler-button(@click="execute('bold')")
            VuseIcon(name='bold')
          li: button.styler-button(@click="execute('italic')")
            VuseIcon(name='italic')
          li: button.styler-button(@click="execute('underline')")
            VuseIcon(name='underline')

      li(v-if="currentOption === 'columnWidth'")
        ul.align
          li: button.styler-button(@click="gridValue--")
            VuseIcon(name='arrowLeft')
          li: input(type="number" min="0" max="12" v-model="gridValue").styler-input
          li: button.styler-button(@click="gridValue++")
            VuseIcon(name='arrowRight')

</template>

<script>
import Popper from 'popper.js';
import VuseIcon from './VuseIcon';
import { isParentTo } from './../util';

export default {
  name: 'Styler',
  components: {
    VuseIcon
  },
  props: {
    el: {
      type: Object,
      required: true
    },
    type: {
      type: String,
      required: true
    },
    name: {
      type: String,
      required: true
    },
    section: {
      type: Object,
      required: true
    }
  },
  data: () => ({
    colors: ['blue', 'green', 'red', 'black', 'white'],
    textColors: ['#4da1ff', '#38E4B7', '#EA4F52', '#000000', '#FFFFFF'],
    textColor: '',
    oldColorerColor: '',
    colorerColor: '',
    mouseTarget: '',
    currentOption: '',
    url: '',
    gridValue: 0,
    isVisible: false
  }),
  watch: {
    colorerColor: function () {
      this.changeColor();
    },
    textColor: function () {
      this.execute('forecolor', this.textColor)
    },
    gridValue: function () {
      this.gridValue = Math.min(Math.max(this.gridValue, 0), 12);
      this.section.set(this.name, (grid) => {
        grid[this.device] = this.gridValue;
      });
    }
  },
  created () {
    if (this.type === 'button') {
      this.url = this.section.get(`${this.name}.href`);
      this.el.contentEditable = 'true';
    }
    if (this.type === 'text') {
      this.el.contentEditable = 'true';
    }
  },
  mounted () {
    if (!this.$builder.isEditing) return;

    // add listeners to show/hide styler
    this.el.addEventListener('click', this.showStyler);
  },
  beforeDestroy () {
    this.hideStyler();
    this.$refs.styler.remove();
    this.el.classList.remove('is-editable');
    this.el.removeEventListener('click', this.showStyler);
    document.removeEventListener('click', this.hideStyler, true);
  },
  methods: {
    updateOption (option) {
      this.currentOption = option;
      this.$nextTick(() => {
        this.popper.update();
      })
    },
    addLink () {
      this.section.set(`${this.name}.href`, this.url);
    },
    changeColor () {
      this.removeClass(`is-${this.oldColorerColor}`);
      this.oldColorerColor = this.colorerColor;
      this.addClass(`is-${this.colorerColor}`);
    },
    addClass (className) {
      this.section.set(this.name, (value) => {
        if (value && value.classes && Array.isArray(value.classes)) {
          value = value.classes;
        }
        value.push(className);
      });
    },
    selectDevice (device) {
      const gridValue = this.section.get(this.name)[device];
      this.updateOption('columnWidth');
      this.device = device;
      this.gridValue = gridValue;
    },
    removeClass (className) {
      if (Array.isArray(className)) {
        return className.forEach(c => {
          this.removeClass(c);
        });
      }
      this.section.set(this.name, value => {
        if (value && value.classes && Array.isArray(value.classes)) {
          value = value.classes;
        }
        const idx = value.indexOf(className);
        value.splice(idx, 1);
      });
    },
    removeSection () {
      this.$builder.remove(this.section);
    },
    execute (command, value = null) {
      this.el.focus();
      document.execCommand(command, false, value);
    },
    showStyler (event) {
      event.stopPropagation();
      if (this.isVisible) return;
      this.isVisible = true;

      // exute popper element
      if (!this.popper) {
        const position = this.$props.type === 'section' ? 'left-start' : 'top';
        this.popper = new Popper(this.el, this.$refs.styler, {
          placement: position
        });
      }
      document.addEventListener('click', this.hideStyler, true);
      this.currentOption = '';
    },
    hideStyler (event) {
      if (
        (event && isParentTo(event.target, this.$el)) ||
        (event && isParentTo(event.target, this.el))
      ) {
        return
      }
      this.isVisible = false;
      if (this.popper) {
        this.popper.destroy();
        this.popper = null;
      }
      document.removeEventListener('click', this.hideStyler, true);

      if (this.type === 'section' || this.type === 'grid') {
        return;
      }
      if (this.type === 'button') {
        this.section.set(`${this.name}.text`, this.el.innerHTML);
        return;
      }

      this.section.set(this.name, this.el.innerHTML);
    }
  }
};
</script>

<style lang="stylus">
@import '~@baianat/base.framework/src/stylus/util/colors'

.styler
  position: absolute
  top: 0
  z-index: 200
  visibility: hidden
  opacity: 0
  margin: 10px 0
  padding: 5px
  background: $dark
  border-radius: 26px
  display: flex
  flex-direction: column
  justify-content: center
  align-items: center
  &-list
    display: flex
    justify-content: center
    align-items: center
    list-style: none
    margin: 0
    padding: 0
  &-input
    background: $white
    color: $dark
    border: 0
    outline: 0
    width: 40px
    height: 40px
    border-radius: 42px
    margin: 0 5px 0 0
    text-align: center
    -webkit-appearance: none
    -moz-appearance: textfield
    appearance: none
  &-button
    display: flex
    justify-content: center
    align-items: center
    outline: 0
    background: $dark
    border: 0
    fill: $white
    color: $white
    width: 42px
    height: 42px
    border-radius: 42px
    margin: 0 5px 0 0
    &:hover
      background: darken($dark, 20%)
    &:first-child
      margin-left: 5px
  &-selector
    margin: 0 5px
  &.is-visible
    visibility: visible
    opacity: 1
  .input-group
    margin: 5px

.align
  @extend .styler-list
  height: 42px

.colorer
  @extend .styler-list
  height: 42px
  li >input
    -webkit-appearance: none
    -moz-appearance: textfield
    appearance: none
    width: 30px
    height: 30px
    border-radius: 40px
    border: 4px solid darken($dark, 20%)
    margin: 0 5px
    outline: none
    &:checked
      border-color: lighten($dark, 20%)
    &:hover
      border-color: lighten($dark, 20%)
    &#colorRed
      background $red
    &#colorBlue
      background $blue
    &#colorGreen
      background $green
    &#colorBlack
      background $black
    &#colorWhite
      background $white

.is-hidden
  display: none

input[type=number]::-webkit-inner-spin-button
input[type=number]::-webkit-outer-spin-button
  -webkit-appearance: none
  margin: 0
</style>


================================================
FILE: src/index.esm.js
================================================
import Vuse from './vuse';
import * as types from './types';

const version = '__VERSION__';

// Auto install if Vue is defined globally.
if (typeof Vue !== 'undefined') {
  // eslint-disable-next-line
  Vue.use(Builder);
}

export {
  Vuse,
  types,
  version
};

export default Vuse;


================================================
FILE: src/index.js
================================================
import Vuse from './vuse';
import * as types from './types';

// Auto install if Vue is defined globally.
if (typeof Vue !== 'undefined') {
  // eslint-disable-next-line
  Vue.use(Builder);
}

Vuse.version = '__VERSION__';
Vuse.types = types;

export default Vuse;


================================================
FILE: src/mixin.js
================================================
function installMixin ({ builder }) {
  builder.mixin = {
    provide: function providesBuilder () {
      const provides = {};
      if (this.$builder) {
        provides.$builder = this.$builder;
      }

      if (this.$section) {
        provides.$section = this.$section;
      }

      return provides;
    },
    beforeCreate () {
      this.$builder = builder;
      if (!this.$options.propsData || this.$options.propsData.id === undefined) {
        return;
      }
      this.$section = this.$builder.find(this.$options.propsData.id);
      this.$options.computed = {
        $sectionData: function getSectionData () {
          return this.$section.data;
        },
        gridClasses: function getGridClasses () {
          return this.$sectionData.columns.map(column => {
            return Object.keys(column.grid).map(device => {
              if (!column.grid[device]) {
                return '';
              }
              const prefix = this.$builder.columnsPrefix[device]
              return `${prefix}${column.grid[device]}`;
            });
          })
        }
      }
    },
    updated () {
      Array.from(this.$el.querySelectorAll('[contentEditable]')).forEach((el) => {
        el.contentEditable = this.$builder.isEditing;
      });
    }
  };
};

export default installMixin;


================================================
FILE: src/plugins/pwa.js
================================================
import JSZip from 'jszip';
import saveAs from 'save-as';
import { getImageBlob, cleanDOM } from '../../src/util';

/**
 * Adds a service worker that caches the static assets.
 */
function createSW (output, { images = [] } = {}) {
  output.file('sw.js', `
    const staticCacheName = 'bbuilder-static-v1';

    self.addEventListener('install', function(event) {
      event.waitUntil(
        caches.open(staticCacheName).then(function(cache) {
          return cache.addAll([
            '/',
            '/assets/js/main.js',
            ${images.map(i => "'/assets/img/" + i.name + "'").join(',').trim(',')}
          ]);
        })
      );
    });

    function serveAsset(request) {
      return caches.open(staticCacheName).then(function(cache) {
        return cache.match(request).then(function(response) {
          if (response) return response;

          return fetch(request).then(function(networkResponse) {
            cache.put(request, networkResponse.clone());
            return networkResponse;
          });
        });
      });
    }

    self.addEventListener('fetch', function(event) {
      const requestUrl = new URL(event.request.url);

      if (requestUrl.origin === location.origin) {
        if (requestUrl.pathname === '/') {
          event.respondWith(caches.match('/'));
          return;
        }
        if (requestUrl.pathname.startsWith('/assets/')) {
          event.respondWith(serveAsset(event.request));
          return;
        }
      }

      event.respondWith(
        caches.match(event.request).then(function(response) {
          return response || fetch(event.request);
        })
      );
    });
  `);

  const scripts = output.folder('assets/js');
  scripts.file('main.js', `
    function registerSW () {
      if (!navigator.serviceWorker) return;
      navigator.serviceWorker.register('/sw.js').then(function (reg) {
        console.log('SW registered!');
      });
    }

    registerSW();
  `);
}

/**
 * Adds some PWA features.
 */
function createPWA (output, payload) {
  createSW(output, payload);
}

function download (assets) {
  const frag = this.outputFragment();
  const images = Array.from(frag.querySelectorAll('img'));
  const artboard = frag.querySelector('#artboard');
  const title = document.title;
  const zip = new JSZip();
  const output = zip.folder('project');
  const imgFolder = output.folder('assets/img');
  const cssFolder = output.folder('assets/css');

  Promise.all(images.map((image) => {
    const imageLoader = getImageBlob(image.src);
    return imageLoader.then((img) => {
      imgFolder.file(img.name, img.blob, { base64: true });
      image.setAttribute('src', `assets/img/${img.name}`);

      return img;
    });
  })).then(images => {
    createPWA(output, { images });
  }).then(() => {
    return new Promise((resolve, reject) => {
      const assetsClient = new XMLHttpRequest();
      assetsClient.open('GET', assets.css);
      assetsClient.onload = function () {
        resolve(this.response);
      }
      assetsClient.send(null);
    }).then((content) => {
      cssFolder.file('app.css', content);
      return content;
    });
  }).then(() => {
    cleanDOM(frag);
    output.file('index.html',
      `<html>
          <head>
            <title>${title}</title>
            <link href="assets/css/app.css" rel="stylesheet">
          </head>
          <body>
            ${artboard.innerHTML}
          <script src="/assets/js/main.js"></script>
          </body>
        </html>`);

    zip.generateAsync({ type: 'blob' }).then((blob) => {
      saveAs(blob, 'project.zip');
    });
  });
}

export default function install ({ builder }) {
  builder.download = download;
};


================================================
FILE: src/plugins/scrolling.js
================================================
import 'intersection-observer';

const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.intersectionRatio > 0.5) {
      entry.target.classList.add('is-active');
      entry.target.classList.remove('is-inactive');
      return;
    }
    entry.target.classList.add('is-inactive');
    entry.target.classList.remove('is-active');
  });
}

const observer = new IntersectionObserver(callback, {
  root: null,
  rootMargin: '0px',
  threshold: [0.1, 0.5, 0.9, 1]
});

const scrolling = (rootEl) => {
  if (!rootEl) return;
  let sections = Array.from(rootEl.querySelectorAll('section'));
  sections.forEach(section => {
    section.classList.add('is-inactive');
    observer.observe(section);
  });
}

export default function install ({ builder }) {
  builder.scrolling = scrolling;
};


================================================
FILE: src/section.js
================================================
import getPath from 'lodash-es/get';
import toPath from 'lodash-es/toPath';
import Seeder from './seeder';

const SECTION_OPTIONS = {
  name: null,
  schema: {}
};

let counter = 0;

export default class Section {
  constructor (options) {
    this.id = counter++;
    options = Object.assign({}, SECTION_OPTIONS, options);
    this.name = options.name;
    this.schema = options.schema;
    this.data = options.data || Seeder.seed(options.schema);
    this.stylers = [];
  }

  set (name, value) {
    const path = toPath(name);
    const prop = path.pop();

    path.shift();
    const obj = path.length === 0 ? this.data : getPath(this.data, path);
    if (typeof value === 'function') {
      value(obj[prop]);
      return;
    }

    obj[prop] = value;
  }

  get (name) {
    const path = toPath(name);
    const prop = path.pop();
    path.shift();
    const obj = path.length === 0 ? this.data : getPath(this.data, path);

    return obj[prop];
  }

  destroy () {
    this.stylers.forEach(styler => styler.$destroy())
  }
};


================================================
FILE: src/seeder.js
================================================
import * as types from './types';
import { isObject } from './util';

const ASSETS_DIR = '.';
const data = new Map([
  [types.Title, 'Awesome title'],
  [types.Text, 'We\'re creating the best place to go when starting a new business or company.With Baianat you can instantly search domain names, social media handles, and see your logo in beautiful logotypes.'],
  [types.Avatar, `${ASSETS_DIR}/img/avatar.png`],
  [types.Logo, `${ASSETS_DIR}/img/google.svg`],
  [types.Link, 'http://example.com'],
  [types.Image, `${ASSETS_DIR}/img/baianat.png`],
  [types.ClassList, () => []],
  [types.Button, () => ({ text: 'Click Me!', classes: [], href: 'http://example.com' })],
  [types.Quote, 'When you were made a leader, you weren\'t given a crown; you were given the responsibility to bring out the best in others.'],
  [types.Grid, () => ({mobile: '', tablet: '', desktop: '', widescreen: ''})],
  [Number, 100],
  [String, 'This is pretty neat']
]);

export default class Seeder {
  // Seeds values using a schema.
  static seed (schema) {
    if (isObject(schema)) {
      return Object.keys(schema).reduce((values, key) => {
        values[key] = Seeder.seed(schema[key]);
        return values;
      }, {});
    } else if (Array.isArray(schema)) {
      return schema.map(s => {
        return Seeder.seed(s)
      });
    }

    let value = data.get(schema);
    if (value === undefined) {
      value = schema;
    }
    return typeof value === 'function' ? value() : value;
  }
};


================================================
FILE: src/styler.js
================================================
import Styler from './components/VuseStyler.vue';
import { getTypeFromTagName, getTypeFromSchema } from './util';

function installStyler ({ builder, Vue }) {
  const StylerInstance = Vue.extend(Styler).extend({
    beforeCreate () {
      this.$builder = builder;
    }
  });

  builder.styler = {
    inserted (el, binding, vnode) {
      const newNode = document.createElement('div');
      const section = vnode.context.$section;
      const rootApp = vnode.context.$root.$el;
      rootApp.appendChild(newNode);
      el.classList.add('is-editable');
      section.stylers.push(new StylerInstance({
        propsData: {
          el,
          section: section,
          type: binding.arg || getTypeFromSchema(binding.expression, section.schema) || getTypeFromTagName(el.tagName),
          name: binding.expression
        }
      }).$mount(newNode));
    }
  };
};

export default installStyler;


================================================
FILE: src/stylus/_app.styl
================================================
@import variables
@import colors

.vuse-icon
  display: block
  width: 20px
  height: 20px
$floatHover
  cursor: pointer
  box-shadow: 0 14px 28px alpha($black, 0.125), 0 10px 10px alpha($black, 0.1)

================================================
FILE: src/stylus/colors.styl
================================================
/*
 * Color theme
 */
$magenta ?= #eb008b
$blue ?= #0072FF
$cyan ?= #00d4f0
$green ?= #18d88b
$yellow ?= #ffdd57
$orange ?= #ffa557
$red ?= #ff3d3d
$purple ?= #a324ea

/*
 * Graysacle
 */
$black ?= #000
$dark ?= #323c47
$gray ?= #c1c1c1
$gray-dark ?= darken($gray, 10%)
$gray-light ?= lighten($gray, 10%)
$light ?= #f5f5f5
$white ?= #fff


================================================
FILE: src/stylus/variables.styl
================================================

$flexCenter
  display: flex
  justify-content: center
  align-items: center

================================================
FILE: src/types.js
================================================
export class Avatar {};

export class Title {};

export class Text {};

export class Logo {};

export class Image {};

export class Quote {};

export class Link {};

export class ClassList {};

export class Button {};

export class Grid { };


================================================
FILE: src/util.js
================================================
import getPath from 'lodash/get';
import * as types from './types';

export function isObject (obj) {
  return obj && typeof obj === 'object' && obj !== null && !Array.isArray(obj);
};

export function isParentTo (target, parent) {
  let currentNode = target;
  while (currentNode !== null) {
    if (currentNode === parent) return true;
    currentNode = currentNode.parentNode;
  }
  return false;
}

/**
 *
 * @param {String} target
 * @param {Object} schema
 */
export function getTypeFromSchema (target, schema) {
  const tempTarget = target.split('.');
  tempTarget.shift();
  const value = getPath(schema, tempTarget.join('.'));
  if (value === types.Grid) return 'grid';
  if (value === types.Text) return 'text';
  if (value === types.Title) return 'text';
  if (value === types.Button) return 'button';
  if (value === types.ClassList) return 'section';
  if (value === String) return 'text';
  if (value === Number) return 'text';

  return null;
}

export function getImageBlob (URL) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', URL);
    xhr.responseType = 'blob';

    xhr.onload = function () {
      const imageBlob = this.response;
      const fileType = this.response.type.split('/')[1].split('+')[0];
      const randomNumber = new Date().getUTCMilliseconds();
      const filename = `image-${randomNumber}.${fileType}`;
      resolve({ blob: imageBlob, name: filename });
    }
    xhr.send(null);
  });
}

export function getTypeFromTagName (tagName) {
  tagName = tagName.toUpperCase();
  switch (tagName) {
    case 'H1':
      return 'text';
    case 'H2':
      return 'text';
    case 'H3':
      return 'text';
    case 'H4':
      return 'text';
    case 'H5':
      return 'text';
    case 'H6':
      return 'text';
    case 'P':
      return 'text';
    case 'B':
      return 'text';
    case 'SPAN':
      return 'text';
    case 'BUTTON':
      return 'button';
    case 'A':
      return 'button';
    case 'SECTION':
      return 'section';
    case 'HEADER':
      return 'section';
    default:
      break;
  }
}

export function cleanDOM (artboard) {
  const editables = Array.from(artboard.querySelectorAll('.is-editable'));
  const uploaders = Array.from(artboard.querySelectorAll('.uploader'));
  const stylers = Array.from(artboard.querySelectorAll('.styler'));

  editables.forEach((el) => {
    el.contentEditable = 'inherit';
    el.classList.remove('is-editable');
  });
  uploaders.forEach((el) => {
    const input = el.querySelector(':scope > input');
    const image = el.querySelector(':scope > img');

    image.classList.add('add-full-width');
    el.classList.remove('uploader');
    input.remove();
  });
  stylers.forEach((styler) => {
    styler.remove();
  });
}


================================================
FILE: src/vuse.js
================================================
import merge from 'lodash-es/merge';
import Section from './section';
import VuseBuilder from './components/VuseBuilder.vue';
import VuseRenderer from './components/VuseRenderer.vue';
import styler from './styler';
import mixin from './mixin';
import { cleanDOM } from './util';

let PLUGINS = [];
let mixier = {};
const BUILDER_OPTIONS = {
  title: '',
  intro: true,
  sections: [],
  plugins: [],
  themes: [],
  columnsPrefix: {
    mobile: 'is-mobile-',
    tablet: 'is-tablet-',
    desktop: 'is-desktop-',
    widescreen: 'is-widescreen-',
    ultrawide: 'is-ultrawide-'
  }
};

// To tell if it is installed or not
let _Vue = null;

class Vuse {
  constructor (options) {
    this.isEditing = true;
    this.isSorting = false;
    this.isRendered = false;
    this.title = options.title;
    this.intro = options.intro;
    this.sections = options.sections;
    this.columnsPrefix = options.columnsPrefix;
    this.themes = options.themes;
    this.components = {};
    this.assets = {
      css: options.assets.css || 'dist/css/app.css'
    }
    this.installPlugins();
  }

  /**
   * Creates and adds a new section to the list of sections.
   * @param {*} options
   */
  add (options, position) {
    if (position !== undefined) {
      this.sections.splice(position, 0, new Section(options));
      return;
    }
    this.sections.push(new Section(options));
  }

  /**
   * Finds a section with the specified id.
   *
   * @param {String|Number} id
   */
  find (id) {
    return this.sections.find(s => s.id === id);
  }

  /**
   * Removes a section with the specified id.
   * @param {String|Number} id
   */
  remove (section) {
    const id = this.sections.findIndex(s => s.id === section.id);
    this.sections.splice(id, 1);
    section.destroy();
  }

  /**
   * Removes a section with the specified id.
   * @param {String|Number} oldIndex
   * @param {String|Number} newIndex
   */
  sort (oldIndex, newIndex) {
    const section = this.sections[oldIndex];
    this.sections.splice(oldIndex, 1);
    this.sections.splice(newIndex, 0, section);
  }

  /**
  * Constructs a document fragment.
  */
  outputFragment () {
    const frag = document.createDocumentFragment();
    frag.appendChild(document.head.cloneNode(true));
    frag.appendChild(this.rootEl.cloneNode(true));

    return frag;
  }

  /**
  * clears the builder sections.
  */
  clear () {
    const tempSections = this.sections;
    this.sections.forEach(section => section.destroy());
    this.sections = [];
    return tempSections;
  }

  /**
   * Static helper for components registration pre-installation.
   *
   * @param {String} name
   * @param {Object} definition
   */
  static component (name, definition) {
    // Just make a plugin that installs a component.
    Vuse.use((ctx) => {
      ctx.builder.component(name, definition);
    });
  }

  /**
   * Acts as a mixin for subcomponents.
   * @param {Object} mixinObj
   */
  static mix (mixinObj) {
    mixier = merge(mixier, mixinObj);
  }

  /**
   * Adds a component section to the builder and augments it with the styler.
   * @param {*} name
   * @param {*} definition
   */
  component (name, definition) {
    // reoslve the component name automatically.
    if (typeof name === 'object') {
      definition = name;
      name = definition.name;
    }

    // if passed a plain object
    if (!definition.extend) {
      definition = _Vue.extend(definition);
    }

    this.components[name] = definition.extend({
      directives: { styler: this.styler },
      mixins: [this.mixin],
      components: mixier.components
    });
  }

  /**
   * Installs added plugins.
   */
  installPlugins () {
    PLUGINS.forEach((ctx) => {
      ctx.plugin({ builder: this, Vue: _Vue }, ctx.options);
    });
    // reset to prevent duplications.
    PLUGINS = [];
  }

  static install (Vue, options = {}) {
    // already installed
    if (_Vue) return;

    _Vue = Vue;
    const builder = new Vuse(Object.assign({}, BUILDER_OPTIONS, options));
    // configer assets output location
    Vue.util.defineReactive(builder, 'sections', builder.sections);
    Vue.util.defineReactive(builder, 'isEditing', builder.isEditing);
    Vue.util.defineReactive(builder, 'isSorting', builder.isSorting);
    const extension = {
      components: builder.components,
      beforeCreate () {
        this.$builder = builder;
      }
    };

    // register the main components.
    Vue.component('VuseBuilder', Vue.extend(VuseBuilder).extend(extension));
    Vue.component('VuseRenderer', Vue.extend(VuseRenderer).extend(extension));
  }

  /**
   * The plugin to be installed with the builder. The function receives the installation context which
   * contains the builder instance and the Vue prototype.
   *
   * @param {Function} plugin
   * @param {Object} options
   */
  static use (plugin, options = {}) {
    if (typeof plugin !== 'function') {
      return console.warn('Plugins must be a function');
    }

    // append to the list of to-be installed plugins.
    PLUGINS.push({ plugin, options });
  }

  set (data) {
    this.title = data.title !== undefined ? data.title : this.title;
    if (data.sections && Array.isArray(data.sections)) {
      this.sections = data.sections.map(section => {
        const sectionData = {
          name: section.name,
          schema: section.schema,
          data: section.data
        };
        if (!sectionData.schema) {
          sectionData.schema = this.components[sectionData.name].options.$schema
        }

        return new Section(sectionData);
      });
    }
  }

  /**
   * Outputs a JSON representation of the builder that can be used for rendering with the renderer component.
   */
  toJSON () {
    return {
      title: this.title,
      sections: this.sections.map(s => ({
        name: s.name,
        data: s.data
      }))
    };
  }

  /**
   * Previews the created page in a seperate tap/window.
   */
  preview () {
    const frag = this.outputFragment();
    const artboard = frag.querySelector('#artboard');
    const printPreview = window.open('about:blank', 'print_preview');
    const printDocument = printPreview.document;
    cleanDOM(frag);
    printDocument.open();
    printDocument.write(
      `<!DOCTYPE html>
        <html>
          <head>
            <title>${this.title}</title>
            <link href="${this.assets.css}" rel="stylesheet">
          </head>
          <body>
            ${artboard.innerHTML}
          <body>
        </html>`
    );
  }

  /**
   * Exports the builder instance to a specified output. default is json.
   *
   * @param {String} method
   */
  export (method = 'json') {
    if (method === 'pwa' || method === 'zip') {
      if (typeof this.download === 'function') {
        return this.download(this.assets);
      }

      return console.warn('You do not have the zip plugin installed.');
    }

    if (method === 'preview') {
      return this.preview();
    }

    return this.toJSON();
  }
};

// use the plugin API to add the styler and mixin functionalities.
Vuse.use(styler);
Vuse.use(mixin);

export default Vuse;
Download .txt
gitextract_7xlm9eti/

├── .babelrc
├── .eslintrc.json
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── demo/
│   ├── App.vue
│   ├── Uploader.vue
│   ├── app.js
│   ├── index.html
│   ├── render.html
│   ├── sections/
│   │   ├── forms/
│   │   │   └── newsletter.vue
│   │   ├── hero/
│   │   │   ├── hero1.vue
│   │   │   └── hero2.vue
│   │   ├── section/
│   │   │   ├── section1.vue
│   │   │   └── section2.vue
│   │   └── social/
│   │       ├── social1.vue
│   │       ├── social2.vue
│   │       ├── social3.vue
│   │       └── social4.vue
│   ├── style/
│   │   ├── _demo.styl
│   │   ├── colors.styl
│   │   ├── header.styl
│   │   ├── helper.styl
│   │   ├── main.styl
│   │   ├── scrolling.styl
│   │   ├── section.styl
│   │   ├── social.styl
│   │   ├── transition.styl
│   │   ├── user.styl
│   │   └── variables.styl
│   └── webpack.config.js
├── docs/
│   ├── .vuepress/
│   │   ├── config.js
│   │   ├── enhanceApp.js
│   │   └── public/
│   │       └── style.css
│   ├── API.md
│   ├── README.md
│   ├── example.md
│   ├── exporting.md
│   ├── getting-started.md
│   ├── section.md
│   └── styler.md
├── package.json
├── scripts/
│   ├── build.js
│   ├── config.js
│   └── deploy.sh
└── src/
    ├── components/
    │   ├── VuseBuilder.vue
    │   ├── VuseIcon.js
    │   ├── VuseRenderer.vue
    │   └── VuseStyler.vue
    ├── index.esm.js
    ├── index.js
    ├── mixin.js
    ├── plugins/
    │   ├── pwa.js
    │   └── scrolling.js
    ├── section.js
    ├── seeder.js
    ├── styler.js
    ├── stylus/
    │   ├── _app.styl
    │   ├── colors.styl
    │   └── variables.styl
    ├── types.js
    ├── util.js
    └── vuse.js
Download .txt
SYMBOL INDEX (58 symbols across 13 files)

FILE: docs/.vuepress/enhanceApp.js
  function normalize (line 54) | function normalize (component) {

FILE: scripts/build.js
  function buildConfig (line 8) | async function buildConfig (build) {
  function build (line 19) | async function build () {

FILE: scripts/config.js
  function genConfig (line 48) | function genConfig (options) {
  method stats (line 94) | stats ({ path }) {

FILE: src/components/VuseIcon.js
  method render (line 46) | render (h, { props }) {

FILE: src/mixin.js
  function installMixin (line 1) | function installMixin ({ builder }) {

FILE: src/plugins/pwa.js
  function createSW (line 8) | function createSW (output, { images = [] } = {}) {
  function createPWA (line 75) | function createPWA (output, payload) {
  function download (line 79) | function download (assets) {
  function install (line 131) | function install ({ builder }) {

FILE: src/plugins/scrolling.js
  function install (line 30) | function install ({ builder }) {

FILE: src/section.js
  constant SECTION_OPTIONS (line 5) | const SECTION_OPTIONS = {
  class Section (line 12) | class Section {
    method constructor (line 13) | constructor (options) {
    method set (line 22) | set (name, value) {
    method get (line 36) | get (name) {
    method destroy (line 45) | destroy () {

FILE: src/seeder.js
  constant ASSETS_DIR (line 4) | const ASSETS_DIR = '.';
  class Seeder (line 20) | class Seeder {
    method seed (line 22) | static seed (schema) {

FILE: src/styler.js
  function installStyler (line 4) | function installStyler ({ builder, Vue }) {

FILE: src/types.js
  class Avatar (line 1) | class Avatar {}
  class Title (line 3) | class Title {}
  class Text (line 5) | class Text {}
  class Logo (line 7) | class Logo {}
  class Image (line 9) | class Image {}
  class Quote (line 11) | class Quote {}
  class Link (line 13) | class Link {}
  class ClassList (line 15) | class ClassList {}
  class Button (line 17) | class Button {}
  class Grid (line 19) | class Grid { }

FILE: src/util.js
  function isObject (line 4) | function isObject (obj) {
  function isParentTo (line 8) | function isParentTo (target, parent) {
  function getTypeFromSchema (line 22) | function getTypeFromSchema (target, schema) {
  function getImageBlob (line 37) | function getImageBlob (URL) {
  function getTypeFromTagName (line 54) | function getTypeFromTagName (tagName) {
  function cleanDOM (line 88) | function cleanDOM (artboard) {

FILE: src/vuse.js
  constant PLUGINS (line 9) | let PLUGINS = [];
  constant BUILDER_OPTIONS (line 11) | const BUILDER_OPTIONS = {
  class Vuse (line 29) | class Vuse {
    method constructor (line 30) | constructor (options) {
    method add (line 50) | add (options, position) {
    method find (line 63) | find (id) {
    method remove (line 71) | remove (section) {
    method sort (line 82) | sort (oldIndex, newIndex) {
    method outputFragment (line 91) | outputFragment () {
    method clear (line 102) | clear () {
    method component (line 115) | static component (name, definition) {
    method mix (line 126) | static mix (mixinObj) {
    method component (line 135) | component (name, definition) {
    method installPlugins (line 157) | installPlugins () {
    method install (line 165) | static install (Vue, options = {}) {
    method use (line 194) | static use (plugin, options = {}) {
    method set (line 203) | set (data) {
    method toJSON (line 224) | toJSON () {
    method preview (line 237) | preview () {
    method export (line 263) | export (method = 'json') {
Condensed preview — 64 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (204K chars).
[
  {
    "path": ".babelrc",
    "chars": 211,
    "preview": "{\r\n  \"presets\": [\r\n    [\"@babel/preset-env\", { \"modules\": false }]\r\n  ],\r\n  \"env\": {\r\n    \"test\": {\r\n      \"presets\": [\r"
  },
  {
    "path": ".eslintrc.json",
    "chars": 191,
    "preview": "{\n    \"extends\": [\n        \"standard\",\n        \"plugin:vue/recommended\"\n    ],\n\n    \"rules\": {\n        \"semi\": \"off\",\n  "
  },
  {
    "path": ".gitignore",
    "chars": 425,
    "preview": "# Logs\r\nlogs\r\n*.log\r\nnpm-debug.log*\r\nyarn-debug.log*\r\nyarn-error.log*\r\n\r\n# Dependency directories\r\nnode_modules/\r\njspm_p"
  },
  {
    "path": ".npmignore",
    "chars": 51,
    "preview": "/docs\r\n/dev\r\n/src\r\n/static\r\n/scripts\r\n.*\r\nyarn.lock"
  },
  {
    "path": "LICENSE",
    "chars": 1064,
    "preview": "MIT License\n\nCopyright (c) 2017 Baianat\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "README.md",
    "chars": 518,
    "preview": "# Vuse\n\n<p align=\"center\">\n  <a href=\"https://github.com/baianat/vuse\" target=\"_blank\">\n    <img width=\"450\" src=\"https:"
  },
  {
    "path": "demo/App.vue",
    "chars": 210,
    "preview": "<template>\n  <VuseBuilder @saved=\"onSave\" />\n</template>\n\n<script>\nexport default {\n  name: 'App',\n  methods: {\n    onSa"
  },
  {
    "path": "demo/Uploader.vue",
    "chars": 1161,
    "preview": "<template lang=\"pug\">\n  div.uploader\n    img(:src=\"src\")\n    input.uploader-input(\n      type=\"file\"\n      ref=\"uploader"
  },
  {
    "path": "demo/app.js",
    "chars": 1478,
    "preview": "// Vuse scripts\r\nimport Vue from 'vue';\r\nimport pwa from '../src/plugins/pwa';\r\nimport Vuse from '../src';\r\n\r\n// demo sc"
  },
  {
    "path": "demo/index.html",
    "chars": 280,
    "preview": "<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-sca"
  },
  {
    "path": "demo/render.html",
    "chars": 622,
    "preview": "<html lang=\"en\">\r\n  <head>\r\n    <meta charset=\"UTF-8\" />\r\n    <meta name=\"viewport\" content=\"width=device-width, initial"
  },
  {
    "path": "demo/sections/forms/newsletter.vue",
    "chars": 1344,
    "preview": "<template lang=\"pug\">\n  section.header(\n    v-styler:section=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n  "
  },
  {
    "path": "demo/sections/hero/hero1.vue",
    "chars": 1176,
    "preview": "<template lang=\"pug\">\n  section.header(\n    v-styler=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n    )\n    "
  },
  {
    "path": "demo/sections/hero/hero2.vue",
    "chars": 1250,
    "preview": "<template lang=\"pug\">\n  section.header(\n    v-styler=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n    )\n    "
  },
  {
    "path": "demo/sections/section/section1.vue",
    "chars": 1585,
    "preview": "<template lang=\"pug\">\n  section.section(\n    v-styler=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n  )\n    ."
  },
  {
    "path": "demo/sections/section/section2.vue",
    "chars": 1971,
    "preview": "<template lang=\"pug\">\n  section.section(\n    v-styler:section=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n "
  },
  {
    "path": "demo/sections/social/social1.vue",
    "chars": 1658,
    "preview": "<template lang=\"pug\">\n  section.social(\n    v-styler:section=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n  "
  },
  {
    "path": "demo/sections/social/social2.vue",
    "chars": 989,
    "preview": "<template lang=\"pug\">\n  section.social(\n    v-styler:section=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n  "
  },
  {
    "path": "demo/sections/social/social3.vue",
    "chars": 1140,
    "preview": "<template lang=\"pug\">\n  section.social(\n    v-styler:section=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n  "
  },
  {
    "path": "demo/sections/social/social4.vue",
    "chars": 2169,
    "preview": "<template lang=\"pug\">\n  section.social(\n    v-styler:section=\"$sectionData.classes\"\n    :class=\"$sectionData.classes\"\n  "
  },
  {
    "path": "demo/style/_demo.styl",
    "chars": 192,
    "preview": "@import variables\n@import '~@baianat/base.framework/base'\n\n@import main\n@import header\n@import section\n@import social\n@i"
  },
  {
    "path": "demo/style/colors.styl",
    "chars": 338,
    "preview": "/*\n * Color theme\n */\n$magenta ?= #eb008b\n$blue ?= #0072FF\n$cyan ?= #00d4f0\n$green ?= #18d88b\n$yellow ?= #ffdd57\n$orange"
  },
  {
    "path": "demo/style/header.styl",
    "chars": 676,
    "preview": ".header\n  width: 100%\n  padding: 50px\n  color: $white\n  &-title\n    font-size: 50px\n    line-height: 1em\n    margin: 20p"
  },
  {
    "path": "demo/style/helper.styl",
    "chars": 362,
    "preview": "+prefix-classes('add-')\n  .center-horizontal\n    display: flex\n    flex-direction: column    \n    justify-content: cente"
  },
  {
    "path": "demo/style/main.styl",
    "chars": 60,
    "preview": "::selection\n  color: inherit\n\n\n.button\n  white-space: nowrap"
  },
  {
    "path": "demo/style/scrolling.styl",
    "chars": 313,
    "preview": ".is-active\n  img\n    opacity: 1\n    transition: 0.4s\n  p\n  h1\n  h2\n  h3\n  h6\n  b\n    opacity: 1\n    transform: translate"
  },
  {
    "path": "demo/style/section.styl",
    "chars": 317,
    "preview": ".section\n  padding: 20px 30px\n  &-title\n    font-size: 30px\n    color: $dark\n\n  &-paragraph\n    font-size: 16px\n    colo"
  },
  {
    "path": "demo/style/social.styl",
    "chars": 792,
    "preview": ".social\n  padding: 100px 0\n  &-number\n    font-size: 50px\n    margin: 20px 0 50px\n  &-item\n    display: flex\n    flex-di"
  },
  {
    "path": "demo/style/transition.styl",
    "chars": 138,
    "preview": ".fade-enter-active\n.fade-leave-active\n  transition: all .3s ease\n  transform: scaleX(1)\n\n.fade-enter\n.fade-leave-to\n  tr"
  },
  {
    "path": "demo/style/user.styl",
    "chars": 521,
    "preview": ".user\n  display: flex\n  align-items: center\n  margin: 10px 0\n  &.is-alt\n    justify-content: center\n    flex-direction: "
  },
  {
    "path": "demo/style/variables.styl",
    "chars": 76,
    "preview": "\n$flexCenter\n  display: flex\n  justify-content: center\n  align-items: center"
  },
  {
    "path": "demo/webpack.config.js",
    "chars": 2827,
    "preview": "const path = require('path');\nconst webpack = require('webpack');\nconst VueLoaderPlugin = require('vue-loader/lib/plugin"
  },
  {
    "path": "docs/.vuepress/config.js",
    "chars": 540,
    "preview": "module.exports = {\r\n  title: 'Vuse',\r\n  description: 'Advanced page builder based on Vue.js',\r\n  base: '/vuse/',\r\n  them"
  },
  {
    "path": "docs/.vuepress/enhanceApp.js",
    "chars": 1553,
    "preview": "// Vuse scripts\r\nimport Vuse from '../../src';\r\n\r\n// demo scripts\r\nimport '../../demo/style/_demo.styl';\r\nimport Uploade"
  },
  {
    "path": "docs/.vuepress/public/style.css",
    "chars": 99510,
    "preview": "\n.vuse-icon {\n  display: block;\n  width: 20px;\n  height: 20px;\n}\n.controller-button:hover,\n.menu-element:hover {\n  curso"
  },
  {
    "path": "docs/API.md",
    "chars": 575,
    "preview": "# API\r\n\r\nYour section components will have some properties injected to help you customize their behavior in building pha"
  },
  {
    "path": "docs/README.md",
    "chars": 110,
    "preview": "---\r\nhome: true\r\nactionText: Getting Started →\r\nactionLink: ./getting-started\r\nheroImage: /img/logo.png\r\n---\r\n"
  },
  {
    "path": "docs/example.md",
    "chars": 511,
    "preview": "---\r\nnavbar: true\r\nsidebar: false\r\neditLink: false\r\npageClass: example\r\n---\r\n\r\n<vuse-builder @saved=\"onSave\"></vuse-buil"
  },
  {
    "path": "docs/exporting.md",
    "chars": 562,
    "preview": "# Exporting\r\n\r\nThere are three ways to export the built page: preview, pwa or json. When clicking the save button the `b"
  },
  {
    "path": "docs/getting-started.md",
    "chars": 2092,
    "preview": "# getting-started\r\n\r\n## What is this\r\n\r\nThis builder (sections builder) reuses your Vue components as **editable section"
  },
  {
    "path": "docs/section.md",
    "chars": 4640,
    "preview": "# Section\r\n\r\nA section is the building block of the page, below is an example of a header section.\r\n::: tip\r\n  Examples "
  },
  {
    "path": "docs/styler.md",
    "chars": 705,
    "preview": "# Styler\r\n\r\nThis directive is automatically injected in your section components, and can be used to facilitate editing e"
  },
  {
    "path": "package.json",
    "chars": 2962,
    "preview": "{\n  \"name\": \"vuse\",\n  \"version\": \"0.1.1\",\n  \"description\": \"Vue.js Page Builder\",\n  \"author\": \"Abdelrahman Ismail <abdel"
  },
  {
    "path": "scripts/build.js",
    "chars": 810,
    "preview": "const chalk = require('chalk');\nconst mkdirpNode = require('mkdirp');\nconst { promisify } = require('util');\nconst { rol"
  },
  {
    "path": "scripts/config.js",
    "chars": 2399,
    "preview": "const path = require('path');\nconst fs = require('fs');\nconst replace = require('rollup-plugin-replace');\nconst vue = re"
  },
  {
    "path": "scripts/deploy.sh",
    "chars": 180,
    "preview": "#!/usr/bin/env sh\n\nset -e\n\nnpm run docs:build\n\ncd docs/.vuepress/dist\n\ngit init\ngit add -A\ngit commit -m 'deploy'\n\ngit p"
  },
  {
    "path": "src/components/VuseBuilder.vue",
    "chars": 11069,
    "preview": "<template lang=\"pug\">\r\n  div\r\n    div#artboard.artboard(\r\n      ref=\"artboard\"\r\n      :class=\"{ 'is-sorting': $builder.i"
  },
  {
    "path": "src/components/VuseIcon.js",
    "chars": 4317,
    "preview": "const icons = {\n  plus: 'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z',\n  tic: 'M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2"
  },
  {
    "path": "src/components/VuseRenderer.vue",
    "chars": 530,
    "preview": "<template lang=\"pug\">\r\n  #artboard.artboard\r\n    component(v-for='section in $builder.sections'\r\n      :is='section.name"
  },
  {
    "path": "src/components/VuseStyler.vue",
    "chars": 10176,
    "preview": "<template lang=\"pug\">\r\n  .styler(\r\n    ref=\"styler\"\r\n    id=\"styler\"\r\n    v-if=\"$builder.isEditing\"\r\n    :class=\"{ 'is-v"
  },
  {
    "path": "src/index.esm.js",
    "chars": 286,
    "preview": "import Vuse from './vuse';\nimport * as types from './types';\n\nconst version = '__VERSION__';\n\n// Auto install if Vue is "
  },
  {
    "path": "src/index.js",
    "chars": 278,
    "preview": "import Vuse from './vuse';\r\nimport * as types from './types';\r\n\r\n// Auto install if Vue is defined globally.\r\nif (typeof"
  },
  {
    "path": "src/mixin.js",
    "chars": 1360,
    "preview": "function installMixin ({ builder }) {\r\n  builder.mixin = {\r\n    provide: function providesBuilder () {\r\n      const prov"
  },
  {
    "path": "src/plugins/pwa.js",
    "chars": 3689,
    "preview": "import JSZip from 'jszip';\nimport saveAs from 'save-as';\nimport { getImageBlob, cleanDOM } from '../../src/util';\n\n/**\n "
  },
  {
    "path": "src/plugins/scrolling.js",
    "chars": 812,
    "preview": "import 'intersection-observer';\n\nconst callback = (entries, observer) => {\n  entries.forEach(entry => {\n    if (entry.in"
  },
  {
    "path": "src/section.js",
    "chars": 1083,
    "preview": "import getPath from 'lodash-es/get';\r\nimport toPath from 'lodash-es/toPath';\r\nimport Seeder from './seeder';\r\n\r\nconst SE"
  },
  {
    "path": "src/seeder.js",
    "chars": 1526,
    "preview": "import * as types from './types';\r\nimport { isObject } from './util';\r\n\r\nconst ASSETS_DIR = '.';\r\nconst data = new Map(["
  },
  {
    "path": "src/styler.js",
    "chars": 934,
    "preview": "import Styler from './components/VuseStyler.vue';\r\nimport { getTypeFromTagName, getTypeFromSchema } from './util';\r\n\r\nfu"
  },
  {
    "path": "src/stylus/_app.styl",
    "chars": 199,
    "preview": "@import variables\n@import colors\n\n.vuse-icon\n  display: block\n  width: 20px\n  height: 20px\n$floatHover\n  cursor: pointer"
  },
  {
    "path": "src/stylus/colors.styl",
    "chars": 338,
    "preview": "/*\n * Color theme\n */\n$magenta ?= #eb008b\n$blue ?= #0072FF\n$cyan ?= #00d4f0\n$green ?= #18d88b\n$yellow ?= #ffdd57\n$orange"
  },
  {
    "path": "src/stylus/variables.styl",
    "chars": 76,
    "preview": "\n$flexCenter\n  display: flex\n  justify-content: center\n  align-items: center"
  },
  {
    "path": "src/types.js",
    "chars": 261,
    "preview": "export class Avatar {};\r\n\r\nexport class Title {};\r\n\r\nexport class Text {};\r\n\r\nexport class Logo {};\r\n\r\nexport class Imag"
  },
  {
    "path": "src/util.js",
    "chars": 2782,
    "preview": "import getPath from 'lodash/get';\nimport * as types from './types';\n\nexport function isObject (obj) {\n  return obj && ty"
  },
  {
    "path": "src/vuse.js",
    "chars": 7096,
    "preview": "import merge from 'lodash-es/merge';\nimport Section from './section';\nimport VuseBuilder from './components/VuseBuilder."
  }
]

About this extraction

This page contains the full source code of the baianat/vuse GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 64 files (185.6 KB), approximately 60.1k tokens, and a symbol index with 58 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!