markdown 有用的shopify资源

shopify resources
# Shopify usefull resources

## Liquid

1. Main Docs
    [Перейти](https://shopify.github.io/liquid/)

2. Github Wiki
    [Перейти](https://github.com/Shopify/liquid/wiki)

3. Shopify Cheat Sheet
    [Перейти](https://www.shopify.com/partners/shopify-cheat-sheet)

markdown Elasticbeanstalkで轨道c

rails_c_on_elasticbeanstalk
```
sudo su - root
cd /var/app/current/
bundle exec rails c production
```

markdown Gitlab

gitlab
# configure ports and url
external_url 'http://gitmydomain.com'
nginx['listen_port'] = 9080

markdown LinuxOS

linux系统一线

pip
# install pip
pip install pip2pi

# pip repo
dir2pi .

# add pip repo info to ~/.pip/pip.conf
[global]
index-url = {{ PIP_LOCATION }}

# to download packages
pip install --download . package
repos
# create yum repo
yum install -y -q yum-utils

# update yum cache
yum clean all

# add repo metadata to /etc/yum.repos.d/localrepo.repo
[localrepo]
name=Hotscan Repository
baseurl=ftp://{{ LOCALREPO_FTP_URL }}/pub
gpgcheck=0
enabled=1

# yum proxy /etc/yum.conf
proxy=http://<Proxy-Server-IP-Address>:<Proxy_Port>
proxy_username=<Proxy-User-Name>
proxy_password=<Proxy-Password> 

# install ftp server
yum install -y -q vsftpd

# start ftp server
systemctl start vsftpd
sysremctl enabled vsftpd

# cp all rpm files to /var/ftp/pub
createrepo /var/ftp/pub

# open port 21 on firewall
firewall-cmd --permanent --port 21/tcp

# to download necessary rpm
yum install --downloadonly --downloaddir=. package
yum reinstall --downloadonly --downloaddir=. package
linux
# install yum-config-manager
yum install -y -q yum-utils

# create user and group
useradd <user> -g <group> 
passwd <passwd>
groupadd <group>
gpasswd <passwd>
userdel
usermod
groupdel
groupmod

# stop firewall
systemctl stop firewalld

# configure firewall
firewall-cmd --get-active-zones
firewall-cmd --zone=public --add-port=3127/tcp --permanent
firewall-cmd --reload

# nohup 
nohup command &>/dev/null &

# kill ports
yum install psmisc
fuser 80/tcp

# add service to boot
chkconfig <service> on
ssh
# generate keygen
keygen -r rsa -b 4096

# start ssh-agent
eval $(ssh-agent)

# add private key to ssh
ssh-add ~/.ssh/user_rsa

# copy ssh key to server
ssh-copy-id -i file user@host

# host checking turn off
~/.ssh/config
Host *
    StrictHostKeyChecking nosudo
chmod 400 ~/.ssh/config
proxy
# install htpasswd
yum install -y -q httpd-tools

# install squid proxy
yum install -y -q squid
htpasswd -c /etc/squid/passwd hotscan

# configuration of squid proxy
vi /etc/squid/squid.conf

## allowed network
acl localnet src 192.168.163.0/24

## access port
http_port 3127

## authentication 
auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic realm proxy
acl authenticated proxy_auth REQUIRED
http_access allow authenticated

markdown 基础64空白图像

whatever.md
data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==

markdown 从主机操作系统访问Virtualbox Guest

从主机操作系统访问Virtualbox Guest

accessing-virtualbox.md
# Accessing your Virtualbox Guest from your Host OS

As a developer you want to ping and access the webserver on your virtual machine.
This is a very simple solution to enable the bridge to the guest VM.

## Requirements

* VirtualBox (latest version)
* A guest operation system (e.g. Ubuntu)

## Setup

* Shut down all running VM's
* Right click on the VM > Change... > Network
* Open Tab: **Adapter 1**
* Enable the Adapter and select "NAT"

The next step is importand to make it work:

* Open Tab: **Adapter 2**
* Enable the adapter and select: "Host-only Adapter"
* Select Name: "VirtualBox Host-only Ethernet Adapter"
* Click at "Extended"
* Select the adapter: "Intel PRO/1000 MT Desktop..."
* Select the modus: "Allow all and host"
* Click on "Ok" to save all settings.

Yes, you have to enable two adapters at the same time to make it work. Realy.
You need a "NAT" and a "Host-only Adapter".

* Start the VM
* Open the terminal (with Ctrl+Alt+T)
* Enter: `ifconfig`
* Now you should see a local IP addresse like: `192.168.56.104`
* The IP address is dynamic an can be different on your VM

## Test

* Go back into your host machine
* Open the command line: `cmd`
* Ping the guest VM with the command: `ping 192.168.56.104`
* You should see the ping response
* If you have a webserver installed on the guest VM then open `http://192.168.56.104` in your browser to the hosted website.


markdown ERwNeb

ERwNeb

style.scss
/*Colors*/

/*Fonts*/
$mainFont: "Poppins", sans-serif;
$primFont: "Nunito", sans-serif;

body {
  background: linear-gradient(90deg, #b784ed, #7925ed);
  display: flex;
  justify-content: center;
}

*,
*::before,
*::after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
}
/*Reset Heading*/
h2,
h3,
p {
  margin: 0;
  padding: 0;
}

/* Start Style*/

.wrapper {
  //background:linear-gradient(200deg, #1e5fb3, #abbad7);
  width: 800px;
  height: 600px;
  margin: 10px auto;
  display: flex;
  justify-content: space-around;
  align-items: center;
  .upload-border,
  .files-border {
    width: 325px;
    height: 425px;
    background: linear-gradient(to left, #acb1d9, #c4d3f0);
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 15px;
    overflow: hidden;
    .upload {
      width: 300px;
      height: 400px;
      background: #fff;
      border-radius: 8px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      &:hover {
        .plus {
          transform:translate(0%, -4%);
          box-shadow:0 0 5px 0 #7d8ace;
        }
      }
      h3 {
        margin-bottom: 30px;
        color: #616161;
        font: 100 22px $mainFont;
      }
      .plus {
        font-size: 40px;
        padding: 45px;
        border: 8px dashed #7d8ace;
        border-radius: 50%;
        margin-bottom: 30px;
        color: #7d8ace;
        cursor: pointer;
        transition:all .5s ease;
      }
      span {
        color: #757575;
        font: 100 14px $mainFont;
      }
    }
  }
  .files {
    width: 300px;
    height: 400px;
    background: #fff;
    border-radius: 8px;
    padding: 25px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    &__row {
      margin-bottom: 30px;
      transition: all 0.5s ease;
      .content {
        display: flex;
        width: 260px;
        justify-content: space-between;
        margin-bottom: 15px;
        .pic-text {
          display: flex;
          justify-content: space-around;
          align-items: center;
          .image {
            color: #7d8ace;
            margin-right: 10px;
          }
          p {
            color: #717171;
            font: 100 14px $mainFont;
          }
        }
        .check,
        .false,
        .false1 {
          padding: 8px;
          border: 2px solid #ddd;
          border-radius: 50%;
          position: relative;
        }
        .check {
          color: #bdf351;
          border-color: #bdf351;
        }
        .false,
        .false1 {
          color: #615e65;
          padding: 8px 9px;
          cursor: pointer;
          &:after {
            content: "";
            position: absolute;
            top: 50%;
            left: 50%;
            border: 2px solid #f1d75c;
            border-radius: 50%;
            transform: translate(-50%, -50%) rotate(-48deg);
            padding: 16px;
            border-top-color: transparent;
          }
        }
        .false1 {
          &:after {
            border-color: transparent #f1d75c transparent transparent;
          }
        }
      }
      .bar {
        width: 100%;
        height: 1px;
        background: #ddd;
      }
    }
    &__footer {
      width: 260px;
      height: 100px;
      display: flex;
      justify-content: center;
      align-items: flex-end;
      p {
        color: #a0a0a0;
        font: 100 16px $mainFont;
      }
    }
  }
}
script.js
// #Day_09

// #File_Upload

// Live Preview - Full Page Here: https://codepen.io/Mohamed-Ayman/full/bKRGXm/


// Based On This : https://dribbble.com/shots/3751947-File-upload

// I Will add a pretty JavaScript code To Make IT More Attractive

// #Daily_Practise
index.html
<div class="wrapper">
  <div class="upload-border">
    <div class="upload">
      <h3>Drop your files here</h3>
      <i class="fa fa-plus plus" id="plus" aria-hidden="true"></i>
      <span>Or click on the area</span>
    </div>
  </div>

  <div class="files-border">
    <div class="files" id="files">
      <div class="files__row">
        <div class="content">
          <div class="pic-text">
            <i class="fa fa-file-image-o fa-2x image" aria-hidden="true"></i>
            <p>Vacation.dng</p>
          </div>
          <div class="pic">
            <i class="fa fa-check check" aria-hidden="true"></i>
          </div>
        </div>
        <div class="bar"></div>
      </div>

      <div class="files__row" id="remove">
        <div class="content">
          <div class="pic-text">
            <i class="fa fa-file-audio-o fa-2x image" aria-hidden="true"></i>
            <p>Vivaldi -- Spring.m4a</p>
          </div>
          <div class="pic">
            <i class="fa fa-times false" id="icon" aria-hidden="true"></i>
          </div>
        </div>
        <div class="bar"></div>
      </div>
      <div class="files__row" id="top">
        <div class="content">
          <div class="pic-text">
            <i class="fa fa-file-archive-o fa-2x image" aria-hidden="true"></i>
            <p>Monthly Report.tar.gz</p>
          </div>
          <div class="pic">
            <i class="fa fa-times false1" aria-hidden="true"></i>
          </div>
        </div>
        <div class="bar"></div>
      </div>
      <div class="files__footer">
        <p> <span id="number">71% </span> completed</p>
      </div>
    </div>
  </div>
</div>
erwneb.markdown
ERwNeb
------


A [Pen](https://codepen.io/harunpehlivan/pen/ERwNeb) by [HARUN PEHLİVAN](https://codepen.io/harunpehlivan) on [CodePen](https://codepen.io).

[License](https://codepen.io/harunpehlivan/pen/ERwNeb/license).

markdown 拖放文件上传

拖放文件上传

style.scss
/*Colors*/

/*Fonts*/
$mainFont: "Poppins", sans-serif;
$primFont: "Nunito", sans-serif;

body {
  background: linear-gradient(90deg, #b784ed, #7925ed);
  display: flex;
  justify-content: center;
}

*,
*::before,
*::after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
}
/*Reset Heading*/
h2,
h3,
p {
  margin: 0;
  padding: 0;
}

.hidden {
  display: none;
}

/* Start Style*/

.wrapper {
  //background:linear-gradient(200deg, #1e5fb3, #abbad7);
  width: 1000px;
  height: 600px;
  margin: 10px auto;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr 1fr;
  .items-border {
    width: 400px;
    height: 100px;
    background: linear-gradient(to left, #acb1d9, #c4d3f0);
    margin: auto;
    border-radius: 15px;
    display: flex;
    justify-content: center;
    align-items: center;
    .items-upload {
      width: 380px;
      height: 80px;
      border-radius: 15px;
      background: #fff;
      display: flex;
      justify-content: space-around;
      position: relative;
      .items {
        align-self: center;
        color: #7d8ace;
        cursor: pointer;
        width: 41px;
        height: 48px;
        position: relative;
      }
    }
  }
  .content {
    display: flex;
    justify-content: space-around;
  }
  .upload-border,
  .files-border {
    width: 390px;
    height: 425px;
    background: linear-gradient(to left, #acb1d9, #c4d3f0);
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 15px;
    overflow: hidden;
    .upload {
      width: 360px;
      height: 400px;
      background: #fff;
      border-radius: 8px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      h3 {
        margin-bottom: 30px;
        color: #616161;
        font: 100 22px $mainFont;
      }
      .plus {
        font-size: 40px;
        padding: 45px;
        border: 8px dashed #7d8ace;
        ///border-radius:50%;
        margin-bottom: 30px;
        color: #7d8ace;
        cursor: pointer;
        //background:#DDD;
        &.bg-gray {
          background: #ddd;
        }
      }
      span {
        color: #757575;
        font: 100 14px $mainFont;
      }
    }
  }
  .files {
    width: 360px;
    height: 400px;
    background: #fff;
    border-radius: 8px;
    padding: 25px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    &__row {
      margin-bottom: 30px;
      position: relative;
      transition: all 0.5s ease;
      &.hidden {
        display: none;
      }
      &.hold {
        border: none;
      }
      &.invisible {
        display: none;
      }
      .content {
        display: grid;
        grid-template-columns: repeat(9, 1fr);
        margin-bottom: 15px;
        grid-gap: 10px;
        .picture {
          grid-row: 1/3;
          .image {
            color: #7d8ace;
          }
        }
        .text {
          grid-column: 2 / -1;
          display: grid;
          grid-template-rows: repeat(2, 25px);
          grid-gap: 15px;
          .status {
            display: flex;
            justify-content: space-between;
            p {
              color: #717171;
              font: 100 14px $mainFont;
            }
            .check,
            .false {
              position: relative;
            }
            .check {
              color: #bdf351;
              border-color: #bdf351;
            }
            .false {
              color: #a0a09e;
              cursor: pointer;
            }
          }
          .progressbar {
            width: 95%;
            height: 5px;
            background: #ddd;
            border-radius: 15px;
            position: relative;
            .progressOrange,
            .progressGreen {
              position: absolute;
              top: 0;
              left: 0;
              height: 5px;
              border-radius: 15px;
              //animation: upwidth 3s linear;
            }
          }
          .progressGreen {
            background: #bdf351;
            width: 100%;
          }
          .progressOrange {
            background: #f18000;
            width: 5%;
          }
          .last-progress {
            background: #f18000;
            width: 1%;
          }
        }
      }
      .bar {
        width: 100%;
        height: 2px;
        background: #ddd;
        position: absolute;
        bottom: 15px;
      }
    }
    &__footer {
      width: 260px;
      height: 100px;
      display: flex;
      justify-content: center;
      align-items: flex-end;
      p {
        color: #a0a0a0;
        font: 100 14px $mainFont;
      }
    }
  }
}

@keyframes upwidth {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}
scripts
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
script.js
$(document).ready(function () {
    const dragIcon = document.getElementById('image');
    const dropIcon = document.querySelector(".plus");
    
   
    //First Icon
    dragIcon.addEventListener('dragstart', dragStart);
    dragIcon.addEventListener('dragend', dragEnd);
    dropIcon.addEventListener('dragover', dragOver);
    dropIcon.addEventListener('dragenter', dragEnter);
    dropIcon.addEventListener('dragleave', dragLeave);
    dropIcon.addEventListener('drop', dragDrop);

     
    // Icon One Function
    function dragStart() {
        this.className += " hold";
        setTimeout(() => this.className = ' invisible', 0);
    }
    function dragEnd() {
        this.className = 'fa fa-file-image-o fa-3x image';
    }
    function dragOver(e) {
        e.preventDefault();
    }
    function dragEnter() {
        this.className += " bg-gray";
    }
    function dragLeave() {
        this.classList.remove('bg-gray');
    }
    function dragDrop() {
        this.classList.remove('bg-gray');
        $('.first').removeClass('hidden');
        increaseNumber();
        upWidth();
    }
    function upWidth() {
        'use strice';
        $('.first-progress').animate({
            width: '100%'
        },15000, function() {
            change();
        })
    }
    function increaseNumber() {
        var newValue = parseInt($('#value').text());
        var x = 221;
        setInterval(increase, 150);
        function increase() {
            newValue = newValue % 360 +1;
            if (newValue >= x) {
                return ;
            }
            $('#value').text(newValue);
        }
    }
    function change() {
        if($('.two').hasClass('two')) {
            $('.two').addClass('hidden');
            $('.three').removeClass('hidden');
            $('.first-progress').css({background: '#bdf351'});
        }
    }
});
index.html
<div class="wrapper">

  <div class="items-border">
    <div class="items-upload">
      <div class="items">
        <i class="fa fa-file-image-o fa-3x image" id="image" draggable="true" aria-hidden="true"></i>
      </div>
      <div class="items">
        <i class="fa fa-file-sound-o fa-3x image" id="image1" draggable="true" aria-hidden="true"></i>
      </div>
      <div class="items">
        <i class="fa fa-file-archive-o fa-3x image" id="image" draggable="true" aria-hidden="true"></i>
      </div>
    </div>
  </div>

  <div class="content">
    <div class="upload-border">
      <div class="upload">
        <h3>Drop your files here</h3>
        <i class="fa fa-plus plus" id="plus" aria-hidden="true"></i>
        <span>Or click on the area</span>
      </div>
    </div>

    <div class="files-border">
      <div class="files" id="files">
        <div class="files__row">
          <div class="content">
            <div class="picture">
              <i class="fa fa-file-image-o fa-3x image" aria-hidden="true"></i>
            </div>
            <div class="text">
              <div class="status">
                <p>Vacation.dng</p>
                <p>Complete <i class="fa fa-check check" aria-hidden="true"></i></p>
              </div>
              <div class="progressbar">
                <div class="progressGreen"></div>
              </div>
            </div>
          </div>
          <div class="bar"></div>
        </div>

        <div class="files__row first hidden">
          <div class="content">
            <div class="picture">
              <i class="fa fa-file-audio-o fa-3x image" aria-hidden="true"></i>
            </div>
            <div class="text">
              <div class="status">
                <p>Vivaldi-Spring.m4a</p>
                <p class="two"><span id="value">125</span>/220 mb <i class="fa fa-times false" id="icon" aria-hidden="true"></i></p>
                <p class="three hidden">Complete <i class="fa fa-check check" aria-hidden="true"></i></p>
              </div>
              <div class="progressbar">
                <div class="progressOrange first-progress"></div>
              </div>
            </div>
          </div>
          <div class="bar"></div>
        </div>

        <div class="files__row second hidden">
          <div class="content">
            <div class="picture">
              <i class="fa fa-file-archive-o fa-3x image" aria-hidden="true"></i>
            </div>
            <div class="text">
              <div class="status">
                <p>Monthly Report.gz</p>
                <p><span>233</span>/325 mb <i class="fa fa-times false" id="icon" aria-hidden="true"></i></p>
              </div>
              <div class="progressbar">
                <div class="progressOrange last-progress"></div>
              </div>
            </div>
          </div>
          <div class="bar"></div>
        </div>

        <!--
                    <div class="files__footer">
                        <p> <span id="number">71% </span> completed</p>
                    </div>-->
      </div>
    </div>
  </div>
</div>
drag-and-drop-file-upload.markdown
Drag and Drop File Upload
-------------------------


A [Pen](https://codepen.io/harunpehlivan/pen/YvrpLJ) by [HARUN PEHLİVAN](https://codepen.io/harunpehlivan) on [CodePen](https://codepen.io).

[License](https://codepen.io/harunpehlivan/pen/YvrpLJ/license).

markdown Google服务

Google服务

style.scss
$mainFont: "Nunito", sans-serif;
body {
  background: #ffbba8;
  background: linear-gradient(141deg, #0fb8ad 0%, #1fc8db 51%, #2cb5e8 75%);
}
* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
}
*::before,
*::after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -o-box-sizing: border-box;
  box-sizing: border-box;
}
/*heading*/
h2,
h3,
h4,
h5 {
  margin: 0;
}
p {
  margin: 0;
  font: 100 14px $mainFont;
}

.leftside-blog,
.leftside-android,
.rightside-chrome,
.rightside-music,
.gmail-top,
.news-middel,
.earth-bottom,
.maps-top,
.search-middel,
.youtube-bottom {
  position: relative;
  height:200px;
  overflow: hidden;
  border-radius: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
}

/*Main Hover*/
.leftside-blog,
.leftside-android,
.rightside-chrome,
.rightside-music,
.gmail-top,
.news-middel,
.earth-bottom,
.maps-top,
.search-middel,
.youtube-bottom {
  &:hover {
    .blog-overlay,
    .android-overlay,
    .chrome-overlay,
    .music-overlay,
    .gmail-overlay,
    .news-overlay,
    .earth-overlay,
    .maps-overlay,
    .search-overlay,
    .youtube-overlay {
      bottom: 0;
      opacity: 1;
    }
    .picture {
      transform: translateY(-55%);
      img {
        width: 64px;
      }
    }
  }
  .picture {
    transition: all 0.5s ease-in-out;
    img {
      width: 80px;
      transition: all 0.5s ease-in-out;
    }
  }
}

/* Start Overlay */
.overlay {
  position: absolute;
  bottom: -50%;
  left: 0;
  opacity: 0;
  padding: 10px;
  color: #fff;
  transition: all 0.5s ease-in-out;
  h5 {
    font: 600 16px $mainFont;
  }
}

.wrapper {
  max-width: 545px;
  min-height: 840px;
  margin: auto;
  background: #eee;
  display: flex;
  box-shadow: 0 0 4px 4px rgba(238, 238, 238, .5);
  @media (min-width: 900px) {
    max-width: 1100px;
  }
  .sidebar {
    background: #fff;
    flex-basis: 8%;
    border: 1px solid #d2d2d2;
    .links {
      display: flex;
      flex-direction: column;
      .social {
        background: #fff;
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 13px;
        cursor: pointer;
        border-bottom: 1px solid #d2d2d2;
      }
    }
  }
  .content {
    //flex-direction: column;
    max-width: 1000px;
    padding: 20px;
    border-top: 1px solid #d2d2d2;
    
    @media (min-width: 900px) {
      display: flex;
      flex-basis: 92%;
      justify-content: space-between;
    }
    .column-one {
      display: flex;
      flex-direction: column;
      max-width: 970px;
      flex-basis: 48%;
      @media (max-width: 899px) {
        margin-bottom: 25px;
      }
      .content-top {
        background: #fff;
        display: flex;
        justify-content: space-between;
        border-radius:8px;
        padding: 20px;
        overflow: hidden;
        flex: 1;
        .top-text {
          display: flex;
          flex-direction: column;
          flex: 70%;
          max-width: 255px;
          z-index: 1;
          h2 {
            letter-spacing: 1px;
            color: #2b2b2b;
            line-height: 1;
            font: 100 25px $mainFont;
            margin-top: 30px;
          }
          p {
            color: #7d7d7d;
            line-height: 1.4;
            margin-bottom: 20px;
          }
          .bullets {
            display: flex;
            justify-content: flex-end;
            margin-right: 25px;
            span {
              height: 12px;
              width: 12px;
              background: #c7c7c7;
              border-radius: 50%;
              display: inline-block;
              margin-right: 5px;
              cursor: pointer;
              &.active {
                background: #fabf28;
              }
            }
          }
        }
        .top-button {
          position: relative;
          display: flex;
          flex: 30%;
          z-index: 0;
          @media (min-width: 900px) {
            justify-content: flex-end;
          }
          .btn {
            width: 150px;
            padding: 10px;
            background: rgba(76, 143, 255, 1);
            border: 0;
            outline: 0;
            color: #fff;
            flex: 1;
            align-self: flex-start;
          }
          .shapes {
            position: absolute;
            flex: 1;
            width: 170px;
            height: 180px;
            align-self: flex-end;
            z-index: -1;
            .red-circle {
              width: 135px;
              height: 135px;
              background: transparent;
              border: 23px solid #d94335;
              border-right-color: #241e1e;
              transform: rotate(-45deg);
              border-radius: 50%;
              position: absolute;
              bottom: -39px;
              right: 11px;
            }
            .blue-circle {
              width: 175px;
              height: 175px;
              background: transparent;
              border: 24px solid #2a70e8;
              border-left-color: #241e1e;
              transform: rotate(-45deg);
              border-radius: 50%;
              position: absolute;
              bottom: 8px;
              right: -74px;
            }
            .yellow-circle {
              width: 60px;
              height: 60px;
              background: transparent;
              border: 13px solid #ffc228;
              border-radius: 50%;
              position: absolute;
              top: 5px;
              left: -21px;
            }
          }
        }
      }
      .content-bottom {
        display: flex;
        justify-content: space-between;
        flex: 2;
        margin-top: 25px;
        .bottom-leftside {
          display: flex;
          flex-direction: column;
          flex-basis: 48%;
          .leftside-blog {
            background: #ce483d;
            margin-bottom: 15px;
            @media (min-width: 900px) {
              flex:1.4;
            }
            .blog-overlay {
              background-color: rgba(189, 64, 54, 0.8);
            }
          }
          .leftside-android {
            background: rgb(142, 176, 33);
            @media (min-width: 900px) {
              flex:1.8;
            }
            &:hover {
              .picture {
                img {
                  width: 80px;
                }
              }
            }
            .picture {
              img {
                width: 128px;
              }
            }
            .android-overlay {
              background-color: rgba(126, 157, 28, 0.8);
            }
          }
        }
        .bottom-rightside {
          display: flex;
          flex-direction: column;
          flex-basis: 48%;
          .rightside-chrome {
            background: #79302a;
            margin-bottom: 15px;
            @media (min-width: 900px) {
              flex:1.8;
            }
            &:hover {
              .picture {
                  transform: translateY(-79%);
              }
            }
            .chrome-overlay {
              background-color: rgba(102, 38, 33, 0.8);
            }
          }
          .rightside-music {
            background: #ffd006;
            @media (min-width: 900px) {
              flex:1.4;
            }
            .music-overlay {
              background-color: rgba(235, 192, 9, 0.9);
            }
          }
        }
      }
    }
    .column-two {
      @media (max-width: 899px) {
        margin-bottom: 25px;
      }
      @media (min-width: 900px) {
        flex-basis: 24%;
        display: flex;
        flex-direction: column;
      }
      .gmail-top {
        background: #abcbd6;
        flex: 1.5;
        margin-bottom: 15px;
        .gmail-overlay {
          background-color: rgba(140, 190, 207, 0.8);
        }
      }
      .news-middel {
        flex: 1.4;
        background: #7bc1a1;
        margin-bottom: 15px;
        .news-overlay {
          background-color: rgba(94, 185, 144, 0.8);
        }
      }
      .earth-bottom {
        flex: 1.8;
        background: #101e55;
        .earth-overlay {
          background-color: rgba(11, 22, 63, 0.8);
        }
      }
    }
    .column-three {
      @media (min-width: 900px) {
        flex-basis: 24%;
        display: flex;
        flex-direction: column;
      }
      .maps-top {
        flex: 2;
        background: #fabf28;
        margin-bottom: 15px;
        .maps-overlay {
          background-color: rgba(242, 181, 28, 0.8);
        }
      }
      .search-middel {
        flex: 1.8;
        background: #2a70e8;
        margin-bottom: 15px;
        .search-overlay {
          background-color: rgba(9, 87, 219, 0.8);
        }
      }
      .youtube-bottom {
        flex: 1.4;
        background: #2b2423;
        .youtube-overlay {
          background-color: rgba(21, 17, 17, 0.8);
        }
      }
    }
  }
}
script.js
// • based on this: https://dribbble.com/shots/896977-Google-Grid

// • June 9, 2018 
// • CSS Daily Practice
// • Day #6
// • Friends_Code_Challenge
index.html
<div class="wrapper">
  <div class="sidebar">
    <div class="links">
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566785/googleplus.png" alt="googleplus"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566694/search-side.png" alt="search"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566693/gmail-side.png" alt="gmail"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566704/youtube-side.png" alt="youtube"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566692/map-side.png" alt="maps"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566690/blogger-side.png" alt="blogger"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566690/google-earth-side.png" alt="google-earth"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566690/chromeside.png" alt="googlechrome"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566688/android-side.png" alt="android"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566693/music-player-side.png" alt="music"></div>
      <div class="social"><img src="https://res.cloudinary.com/elafreet/image/upload/v1528566693/news-side.png" alt="news"></div>
    </div>
  </div>
  <div class="content">
    <div class="column-one">
      <div class="content-top">
        <div class="top-text">
          <h2>Get more out of Google by using Google+</h2>
          <p>Whether you'r Using Gmail, Search, Youtube, Maps, or Blogger, Google+ gives you new ways to share the right things with the right people.</p>
          <div class="bullets">
            <span class="active"></span>
            <span></span>
            <span></span>
          </div>
        </div>
        <div class="top-button">
          <button class="btn">Upgrade To Google+</button>
          <div class="shapes">
            <div class="red-circle"></div>
            <div class="blue-circle"></div>
            <div class="yellow-circle"></div>
          </div>
        </div>
      </div>
      <div class="content-bottom">
        <div class="bottom-leftside">
          <div class="leftside-blog">
            <div class="picture">
              <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566689/blogger.png" alt="blogger">
            </div>
            <div class="blog-overlay overlay">
              <h5>Blogger >></h5>
              <p>Lorem ipsum dolor sit elit. Eos, voluptatum excepturi eveniet molestias tempore?</p>
            </div>
          </div>
          <div class="leftside-android">
            <div class="picture">
              <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566690/android.png" alt="android">
            </div>
            <div class="android-overlay overlay">
              <h5>Android >></h5>
              <p>Lorem ipsum dolor sit amet mollitia suscipit atque amet delectus officiis autem?</p>
            </div>
          </div>
        </div>
        <div class="bottom-rightside">
          <div class="rightside-chrome">
            <div class="picture">
              <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566690/chrome.png" alt="chrome">
            </div>
            <div class="chrome-overlay overlay">
              <h5>Chrome >></h5>
              <p>Lorem ipsum dolor sit amet consectetur amet delectus exercitationem natus officiis autem?</p>
            </div>
          </div>
          <div class="rightside-music">
            <div class="picture">
              <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566691/music-player.png" alt="music">
            </div>
            <div class="music-overlay overlay">
              <h5>Music >></h5>
              <p>Lorem ipsum dolor sit amet exercitationem natus officiis autem?</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="column-two">
      <div class="gmail-top">
        <div class="picture">
          <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566692/gmail.png" alt="gmail">
        </div>
        <div class="gmail-overlay overlay">
          <h5>Gmail >></h5>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. delectus exercitationem natus officiis autem?</p>
        </div>
      </div>
      <div class="news-middel">
        <div class="picture">
          <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566692/news.png" alt="news">
        </div>
        <div class="news-overlay overlay">
          <h5>News >></h5>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. exercitationem natus officiis autem?</p>
        </div>
      </div>
      <div class="earth-bottom">
        <div class="picture">
          <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566694/google-earth.png" alt="google-earth">
        </div>
        <div class="earth-overlay overlay">
          <h5>Earth >></h5>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. exercitationem natus officiis autem?</p>
        </div>
      </div>
    </div>
    <div class="column-three">
      <div class="maps-top">
        <div class="picture">
          <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566692/map.png" alt="map">
        </div>
        <div class="maps-overlay overlay">
          <h5>Maps >></h5>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut consequatur quibusdam mollitia suscipit atque amet delectus exercitationem natus officiis autem?</p>
        </div>
      </div>
      <div class="search-middel">
        <div class="picture">
          <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566694/search.png" alt="search">
        </div>
        <div class="search-overlay overlay">
          <h5>Search >></h5>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut consequatur quibusdam mollitia ?</p>
        </div>
      </div>
      <div class="youtube-bottom">
        <div class="picture">
          <img src="https://res.cloudinary.com/elafreet/image/upload/v1528566695/youtube1.png" alt="youtube">
        </div>
        <div class="youtube-overlay overlay">
          <h5>Youtube >></h5>
          <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut consequatur ?</p>
        </div>
      </div>
    </div>
  </div>
</div>
google-services.markdown
Google Services
---------------


A [Pen](https://codepen.io/harunpehlivan/pen/MXEbXJ) by [HARUN PEHLİVAN](https://codepen.io/harunpehlivan) on [CodePen](https://codepen.io).

[License](https://codepen.io/harunpehlivan/pen/MXEbXJ/license).

markdown 如何设置Ubuntu服务器(即DigitalOcean LAMP堆栈)Akeneo PIM服务器。

如何设置Ubuntu服务器(即DigitalOcean LAMP堆栈)Akeneo PIM服务器。

setup-ubuntu-akeneo-pim.md
# How to setup the Akeneo server

```sh
# date: january 2018
# author: Dick de Leeuw (dick@leeuw.studio, @leeuwd)
# prerequisites: LAMP droplet (>= 8GB RAM)
# environment: Ubuntu 16.04.3 LTS xenial, Apache/2.4.29 (Ubuntu), MySQL 5.7.21 & PHP 7.1

# create droplet

# login as root from local
ssh root@[IP]

# update
apt update
apt upgrade
apt dist-upgrade

# akeneo dependencies
apt install apt-transport-https
add-apt-repository ppa:ondrej/php
add-apt-repository ppa:ondrej/apache2
apt update
apt-get install upstart composer php7.1 php7.1-cli php7.1-common php7.1-json php7.1-opcache php7.1-mysql php7.1-mbstring php7.1-mcrypt php7.1-zip unzip php7.1-fpm php7.1-bcmath php7.1-curl php7.1-gd php7.1-intl php7.1-soap php7.1-xml php-xml php7.1-exif php7.1-imagick supervisor openjdk-8-jre-headless

# enable php 7.1
a2enmod proxy_fcgi setenvif
a2enconf php7.1-fpm
service apache2 restart

# elasticsearch (use v5, v6 won't work with akeneo!)
wget -O - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
echo "deb https://artifacts.elastic.co/packages/5.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-5.x.list
apt update
apt install elasticsearch
sudo systemctl enable elasticsearch

# elasticsearch config
nano /etc/elasticsearch/elasticsearch.yml
# uncomment and set: cluster.name: akeneo
# uncomment and set: node.name: node-1
# save and close
sudo systemctl start elasticsearch

# test elasticsearch (wait 1 min before running this, give it time to start)
curl -X GET 'http://localhost:9200'

# java heap count
sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | tee /etc/sysctl.d/elasticsearch.conf
systemctl restart elasticsearch

# prevent updates, those will break akeneo
apt-mark hold php7.1
apt-mark hold elasticsearch
apt-add-repository --remove ppa:ondrej/php
apt-add-repository --remove ppa:ondrej/apache2

# firewall
sudo ufw allow in "Apache Full"

# enable apache proxy modules
a2enmod rewrite proxy_fcgi

# apache config (add line)
nano /etc/apache2/apache2.conf
ServerName [HOSTNAME]

# apache php mod
nano /etc/apache2/mods-enabled/dir.conf
# move index.php to front of line
# so: DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm

# restart and check apache
systemctl restart apache2
systemctl status apache2

# set hostname
hostnamectl set-hostname '[HOSTNAME]'
# e.g. hostnamectl set-hostname 'akeneo.domain.com'

# set timezone
dpkg-reconfigure tzdata

# nodejs
curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
apt-get install -y nodejs
apt-get install -y build-essential

# yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
apt-get update && apt-get install yarn

# php cli config
nano /etc/php/7.1/cli/php.ini
date.timezone = [TIMEZONE]
# e.g. date.timezone = Europe/Amsterdam
# see http://php.net/manual/en/timezones.php

# php fpm config (modify lines)
nano /etc/php/7.1/fpm/php.ini
date.timezone = [TIMEZONE]
memory_limit = 1024M
post_max_size = 64M
upload_max_filesize = 64M

# swap file
sudo fallocate -l 1G /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# auto ban IPs that hack (http://denyhosts.sourceforge.net)
apt-get install denyhosts
# sudo nano /etc/denyhosts.conf for optional config

# fail2ban
sudo apt-get install fail2ban
nano /etc/fail2ban/jail.conf
# find [sshd] section
# add/set enabled  = true

# htop process viewer (http://hisham.hm/htop/)
apt-get install htop
# open/test with 'htop' command

# mysql root password
cat /root/.digitalocean_password
mysql_secure_installation
# paste password in
# run installation wizard

# mysql table and user
mysql -u root -p
CREATE DATABASE akeneo_production DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE USER 'pim_usr_prod'@'localhost' IDENTIFIED BY '[PASSWORD]';
GRANT ALL PRIVILEGES ON akeneo_production.* TO 'pim_usr_prod'@'localhost';
GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY '[ROOT_MYSQL_PASSWORD]';
FLUSH PRIVILEGES;
quit

# allow remote mysql access (comment lines)
# decide this for youself, it's a risk but eases sysops
nano /etc/mysql/mysql.conf.d/mysqld.cnf
#skip-external-locking
#bind-address=127.0.0.1
service mysql restart

# firewall whitelist mysql
sudo ufw allow 3306/tcp
sudo service ufw restart

# final upgrades & cleanup
sudo apt upgrade
rm -rf /etc/update-motd.d/99-one-click
rm -rf /root/.digitalocean_password
apt autoremove
apt autoclean

# non-root user
adduser [USERNAME]
usermod -aG sudo [USERNAME]
su - [USERNAME]
mkdir ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
ssh-keygen -t rsa -C "[EMAIL_ADDRESS]" -b 4096
cat ~/.ssh/id_rsa.pub
# save this public key somewhere, you can use it as deploy key in Github/Gitlab
exit

# now add public key auth: https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04#step-four-%E2%80%94-add-public-key-authentication-(recommended)
# e.g. from macOS: cat ~/.ssh/id_rsa.pub | ssh [USERNAME]@[IP] "cat >> ~/.ssh/authorized_keys"
# the latter only works when creating the droplet with ssh password access allowed (i.e. key not set when creating droplet)
# otherwise, on local, cat ~/.ssh/id_rsa.pub and copy key, paste into /home/[USERNAME]/.ssh/authorized_keys

# reboot (just to be sure all works fine)
reboot

# login as non-root
ssh [USERNAME]@[IP]

# filesystem
sudo mkdir -p /var/www/html/akeneo
sudo chown [USERNAME]:[USERNAME] /var/www/html/akeneo
chmod 775 /var/www/html/akeneo

# apache virtual host file
sudo rm -f /etc/apache2/sites-enabled/000-default.conf
sudo touch /etc/apache2/sites-available/akeneo_production.conf
sudo nano /etc/apache2/sites-available/akeneo_production.conf
# paste virtual host config in (see below), save and close
sudo a2enmod rewrite
sudo service apache2 restart
sudo apache2ctl configtest
sudo a2ensite akeneo_production
sudo systemctl reload apache2

# host file (add line)
sudo nano /etc/hosts
127.0.0.1 [HOSTNAME]

# akeneo source
cd /var/www/html/akeneo/web
wget https://download.akeneo.com/pim-community-standard-v2.1-latest.tar.gz
tar --strip-components=1 -zxvf pim-community-standard-v2.1-latest.tar.gz
rm -f pim-community-standard-v2.1-latest.tar.gz
mkdir -p /app/file_storage
mkdir -p /app/uploads
mkdir -p /var/media
chmod -R 777 ./app/file_storage/
chmod -R 777 ./app/uploads/
chmod -R 777 ./var/logs/
chmod -R 777 ./var/cache/
chmod -R 777 ./var/media/
composer install --optimize-autoloader --prefer-dist
yarn install

# set db credentials
sudo nano app/config/parameters.yml

# github token (https://github.com/settings/tokens)
composer config --global github-oauth.github.com "[GITHUB_TOKEN]"

# install
php bin/console cache:clear --no-warmup --env=prod
php bin/console pim:installer:assets --symlink --clean --env=prod
bin/console pim:install --force --symlink --clean --env=prod
yarn run webpack

# cron
*/15 * * * * php /var/www/html/akeneo/bin/console pim:completeness:calculate --env=prod > /var/www/html/akeneo/bin/console/var/logs/calculate_completeness.log 2>&1
*/15 * * * * php /var/www/html/akeneo/bin/console pim:versioning:refresh --env=prod > /var/www/html/akeneo/bin/console/var/logs/refresh_versioning.log 2>&1

# supervisor task runner
sudo touch /etc/supervisor/conf.d/akeneo_production.conf
sudo nano /etc/supervisor/conf.d/akeneo_production.conf
# paste supervisor config (see below) in it
supervisorctl reread
supervisorctl update
supervisorctl start akeneo_production

```

## Apache virtual host config

```xml
# apache virtual host config file
# /etc/apache2/sites-available/akeneo_production.conf
# after change, restart apache with 'systemctl restart apache2'

<VirtualHost *:80>
    ServerName [HOSTNAME]
    DocumentRoot /var/www/html/akeneo/web
    
    <Directory /var/www/html/akeneo/web>
        AllowOverride None
        Require all granted

        Options -MultiViews
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ app.php [QSA,L]
    </Directory>

    <Directory /var/www/html/akeneo>
        Options FollowSymlinks
    </Directory>

    <Directory /var/www/html/akeneo/web/bundles>
        RewriteEngine Off
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php7.1-fpm.sock|fcgi://localhost/"
    </FilesMatch>

    SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0
</VirtualHost>
```

## Supervisor config

```sh
[program:akeneo_production]
command=/usr/bin/php /var/www/html/akeneo/bin/console akeneo:batch:job-queue-consumer-daemon --env=prod
autostart=false
autorestart=true
stderr_logfile=/var/log/akeneo_daemon.err.log
stdout_logfile=/var/log/akeneo_daemon.out.log
user=[USERNAME]
```