Merge branch 'tailwind' into 'master'
feat: Move main router and menu into app to allow easier development See merge request mythic-insight/legendary!19
| 
						 | 
					@ -7,7 +7,6 @@ defmodule Admin.Router do
 | 
				
			||||||
    plug :fetch_flash
 | 
					    plug :fetch_flash
 | 
				
			||||||
    plug :protect_from_forgery
 | 
					    plug :protect_from_forgery
 | 
				
			||||||
    plug :put_secure_browser_headers
 | 
					    plug :put_secure_browser_headers
 | 
				
			||||||
    plug :put_layout, {CoreWeb.LayoutView, :app}
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :require_admin do
 | 
					  pipeline :require_admin do
 | 
				
			||||||
| 
						 | 
					@ -18,5 +17,5 @@ defmodule Admin.Router do
 | 
				
			||||||
    plug :accepts, ["json"]
 | 
					    plug :accepts, ["json"]
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  use Kaffy.Routes, scope: "/", pipe_through: [:require_admin]
 | 
					  use Admin.Routes
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								apps/admin/lib/admin/routes.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					defmodule Admin.Routes do
 | 
				
			||||||
 | 
					  defmacro __using__(_opts \\ []) do
 | 
				
			||||||
 | 
					    quote do
 | 
				
			||||||
 | 
					      use Kaffy.Routes, scope: "/admin", pipe_through: [:require_admin]
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,10 @@
 | 
				
			||||||
@import "blog";
 | 
					@import "blog";
 | 
				
			||||||
@import "code";
 | 
					@import "code";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					  outline: 1px pink solid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
input[type="checkbox"]::after {
 | 
					input[type="checkbox"]::after {
 | 
				
			||||||
  content: "";
 | 
					  content: "";
 | 
				
			||||||
  color: currentColor;
 | 
					  color: currentColor;
 | 
				
			||||||
| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
/* This file is for your main application css. */
 | 
					 | 
				
			||||||
@import "./phoenix.css";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Alerts and form errors */
 | 
					 | 
				
			||||||
.alert {
 | 
					 | 
				
			||||||
  padding: 15px;
 | 
					 | 
				
			||||||
  margin-bottom: 20px;
 | 
					 | 
				
			||||||
  border: 1px solid transparent;
 | 
					 | 
				
			||||||
  border-radius: 4px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.alert-info {
 | 
					 | 
				
			||||||
  color: #31708f;
 | 
					 | 
				
			||||||
  background-color: #d9edf7;
 | 
					 | 
				
			||||||
  border-color: #bce8f1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.alert-warning {
 | 
					 | 
				
			||||||
  color: #8a6d3b;
 | 
					 | 
				
			||||||
  background-color: #fcf8e3;
 | 
					 | 
				
			||||||
  border-color: #faebcc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.alert-danger {
 | 
					 | 
				
			||||||
  color: #a94442;
 | 
					 | 
				
			||||||
  background-color: #f2dede;
 | 
					 | 
				
			||||||
  border-color: #ebccd1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.alert p {
 | 
					 | 
				
			||||||
  margin-bottom: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.alert:empty {
 | 
					 | 
				
			||||||
  display: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -13,3 +13,45 @@ import "../css/app.css"
 | 
				
			||||||
//     import socket from "./socket"
 | 
					//     import socket from "./socket"
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
import "phoenix_html"
 | 
					import "phoenix_html"
 | 
				
			||||||
 | 
					import { ready } from "./utils"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function togglePasswordFieldVisibility()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  const passwordFields = document.querySelectorAll('[name="user[password]"]')
 | 
				
			||||||
 | 
					  passwordFields.forEach((el) => {
 | 
				
			||||||
 | 
					    if (el.type == 'password')
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      el.type = 'text'
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      el.type = 'password'
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const toggleSidebar = (event) => {
 | 
				
			||||||
 | 
					  document.querySelectorAll('.sidebar').forEach((el) => {
 | 
				
			||||||
 | 
					    el.classList.toggle('visible')
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ready(() => {
 | 
				
			||||||
 | 
					  document.getElementById('nav-toggle').onclick = function(){
 | 
				
			||||||
 | 
					    document.getElementById("nav-content").classList.toggle("hidden");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  document.querySelectorAll('.js-passwordRevealer').forEach((el) => {
 | 
				
			||||||
 | 
					    el.addEventListener('click', togglePasswordFieldVisibility)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  document.querySelectorAll('.js-SidebarOpener').forEach((el) => {
 | 
				
			||||||
 | 
					    el.addEventListener('click', toggleSidebar)
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  document.querySelectorAll('.js-flash-closer').forEach((el) => {
 | 
				
			||||||
 | 
					    el.addEventListener('click', () => {
 | 
				
			||||||
 | 
					      el.closest('.js-flash').remove()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5943
									
								
								apps/app/assets/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						| 
						 | 
					@ -4,11 +4,22 @@
 | 
				
			||||||
  "license": "MIT",
 | 
					  "license": "MIT",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "deploy": "webpack --mode production",
 | 
					    "deploy": "webpack --mode production",
 | 
				
			||||||
    "watch": "webpack --mode development --watch"
 | 
					    "watch": "webpack --mode development --watch",
 | 
				
			||||||
 | 
					    "preinstall": "npx npm-force-resolutions",
 | 
				
			||||||
 | 
					    "profile": "webpack --mode development --plugin webpack/lib/debug/ProfilingPlugin"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "phoenix": "file:../../../deps/phoenix",
 | 
					    "@fortawesome/fontawesome-free": "^5.14.0",
 | 
				
			||||||
    "phoenix_html": "file:../../../deps/phoenix_html"
 | 
					    "autoprefixer": "^9.8.6",
 | 
				
			||||||
 | 
					    "csswring": "^7.0.0",
 | 
				
			||||||
 | 
					    "glob": "^7.1.6",
 | 
				
			||||||
 | 
					    "gulp": "^4.0.2",
 | 
				
			||||||
 | 
					    "phoenix": "file:/../../../deps/phoenix",
 | 
				
			||||||
 | 
					    "phoenix_html": "file:/../../../deps/phoenix_html",
 | 
				
			||||||
 | 
					    "postcss-color-function": "^4.1.0",
 | 
				
			||||||
 | 
					    "simplemde": "^1.11.2",
 | 
				
			||||||
 | 
					    "stylelint": "^13.6.1",
 | 
				
			||||||
 | 
					    "tailwindcss": "^1.7.3"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@babel/core": "^7.0.0",
 | 
					    "@babel/core": "^7.0.0",
 | 
				
			||||||
| 
						 | 
					@ -16,12 +27,26 @@
 | 
				
			||||||
    "babel-loader": "^8.0.0",
 | 
					    "babel-loader": "^8.0.0",
 | 
				
			||||||
    "copy-webpack-plugin": "^5.1.1",
 | 
					    "copy-webpack-plugin": "^5.1.1",
 | 
				
			||||||
    "css-loader": "^3.4.2",
 | 
					    "css-loader": "^3.4.2",
 | 
				
			||||||
    "sass-loader": "^8.0.2",
 | 
					    "extract-text-webpack-plugin": "^3.0.2",
 | 
				
			||||||
    "node-sass": "^4.13.1",
 | 
					    "file-loader": "^6.0.0",
 | 
				
			||||||
 | 
					    "image-webpack-loader": "^6.0.0",
 | 
				
			||||||
 | 
					    "less": "^3.11.3",
 | 
				
			||||||
 | 
					    "less-loader": "^6.2.0",
 | 
				
			||||||
    "mini-css-extract-plugin": "^0.9.0",
 | 
					    "mini-css-extract-plugin": "^0.9.0",
 | 
				
			||||||
 | 
					    "node-sass": "^4.13.1",
 | 
				
			||||||
    "optimize-css-assets-webpack-plugin": "^5.0.1",
 | 
					    "optimize-css-assets-webpack-plugin": "^5.0.1",
 | 
				
			||||||
 | 
					    "postcss-css-variables": "^0.17.0",
 | 
				
			||||||
 | 
					    "postcss-import": "^12.0.1",
 | 
				
			||||||
 | 
					    "postcss-loader": "^3.0.0",
 | 
				
			||||||
 | 
					    "sass-loader": "^8.0.2",
 | 
				
			||||||
 | 
					    "style-loader": "^1.2.1",
 | 
				
			||||||
 | 
					    "stylelint-config-standard": "^20.0.0",
 | 
				
			||||||
 | 
					    "stylelint-order": "^4.1.0",
 | 
				
			||||||
    "terser-webpack-plugin": "^2.3.2",
 | 
					    "terser-webpack-plugin": "^2.3.2",
 | 
				
			||||||
    "webpack": "4.41.5",
 | 
					    "webpack": "4.41.5",
 | 
				
			||||||
    "webpack-cli": "^3.3.2"
 | 
					    "webpack-cli": "^3.3.2"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "resolutions": {
 | 
				
			||||||
 | 
					    "graceful-fs": "4.2.3"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB  | 
| 
		 Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB  | 
| 
		 Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB  | 
| 
		 Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB  | 
| 
						 | 
					@ -5,6 +5,8 @@ const TerserPlugin = require('terser-webpack-plugin');
 | 
				
			||||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
 | 
					const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
 | 
				
			||||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
					const CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const nodeModulesPath = path.resolve(__dirname, 'node_modules')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = (env, options) => {
 | 
					module.exports = (env, options) => {
 | 
				
			||||||
  const devMode = options.mode !== 'production';
 | 
					  const devMode = options.mode !== 'production';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,17 +17,42 @@ module.exports = (env, options) => {
 | 
				
			||||||
        new OptimizeCSSAssetsPlugin({})
 | 
					        new OptimizeCSSAssetsPlugin({})
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    mode: options.mode,
 | 
				
			||||||
 | 
					    devtool: devMode ? 'source-map' : undefined,
 | 
				
			||||||
    entry: {
 | 
					    entry: {
 | 
				
			||||||
      'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js'])
 | 
					      'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
 | 
				
			||||||
 | 
					      'content-editor': ['./js/content-editor.js'],
 | 
				
			||||||
 | 
					      'tailwind': ['./tailwind.config.js'],
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    output: {
 | 
					    output: {
 | 
				
			||||||
      filename: '[name].js',
 | 
					      filename: 'js/[name].js',
 | 
				
			||||||
      path: path.resolve(__dirname, '../priv/static/js'),
 | 
					      path: path.resolve(__dirname, '../priv/static/')
 | 
				
			||||||
      publicPath: '/js/'
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    devtool: devMode ? 'source-map' : undefined,
 | 
					 | 
				
			||||||
    module: {
 | 
					    module: {
 | 
				
			||||||
      rules: [
 | 
					      rules: [
 | 
				
			||||||
 | 
					        // For images and fonts found in our scss files
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          test: /\.(jpg|jpeg|gif|png)$/,
 | 
				
			||||||
 | 
					          use: [
 | 
				
			||||||
 | 
					            'file-loader',
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					              loader: 'image-webpack-loader',
 | 
				
			||||||
 | 
					              options: {
 | 
				
			||||||
 | 
					                disable: devMode,
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          test: /\.(woff2?|ttf|eot|svg)(\?[a-z0-9\=\.]+)?$/,
 | 
				
			||||||
 | 
					          loader: 'file-loader',
 | 
				
			||||||
 | 
					          options: {
 | 
				
			||||||
 | 
					            publicPath: '/fonts',
 | 
				
			||||||
 | 
					            outputPath: (url, resourcePath, context) => {
 | 
				
			||||||
 | 
					              return `/fonts/${url}`;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          test: /\.js$/,
 | 
					          test: /\.js$/,
 | 
				
			||||||
          exclude: /node_modules/,
 | 
					          exclude: /node_modules/,
 | 
				
			||||||
| 
						 | 
					@ -34,18 +61,45 @@ module.exports = (env, options) => {
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          test: /\.[s]?css$/,
 | 
					          test: /\.css$/,
 | 
				
			||||||
          use: [
 | 
					          use: [
 | 
				
			||||||
            MiniCssExtractPlugin.loader,
 | 
					            {loader: MiniCssExtractPlugin.loader, options: {sourceMap: true}},
 | 
				
			||||||
            'css-loader',
 | 
					            {loader: 'css-loader', options: {sourceMap: true}},
 | 
				
			||||||
            'sass-loader',
 | 
					            {loader: 'postcss-loader', options: {sourceMap: true}},
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    plugins: [
 | 
					    plugins: [
 | 
				
			||||||
      new MiniCssExtractPlugin({ filename: '../css/app.css' }),
 | 
					      new MiniCssExtractPlugin({
 | 
				
			||||||
      new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
 | 
					        filename: 'css/[name].css',
 | 
				
			||||||
    ]
 | 
					        chunkFilename: '[id].css',
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					      new CopyWebpackPlugin([
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          from: path.resolve(__dirname, 'static'),
 | 
				
			||||||
 | 
					          to: path.resolve(__dirname, '../priv/static'),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ]),
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    resolve: {
 | 
				
			||||||
 | 
					      alias: {
 | 
				
			||||||
 | 
					        "../webfonts/fa-brands-400.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.eot"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-brands-400.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff2"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-brands-400.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-brands-400.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.ttf"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-brands-400.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.svg"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-regular-400.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.eot"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-regular-400.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff2"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-regular-400.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-regular-400.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.ttf"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-regular-400.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.svg"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-solid-900.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.eot"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-solid-900.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-solid-900.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-solid-900.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.ttf"),
 | 
				
			||||||
 | 
					        "../webfonts/fa-solid-900.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.svg"),
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,8 @@ defmodule App.Application do
 | 
				
			||||||
      App.Repo,
 | 
					      App.Repo,
 | 
				
			||||||
      # Start the Telemetry supervisor
 | 
					      # Start the Telemetry supervisor
 | 
				
			||||||
      AppWeb.Telemetry,
 | 
					      AppWeb.Telemetry,
 | 
				
			||||||
 | 
					      # Set up the pubsub server
 | 
				
			||||||
 | 
					      {Phoenix.PubSub, name: App.PubSub},
 | 
				
			||||||
      # Start the Endpoint (http/https)
 | 
					      # Start the Endpoint (http/https)
 | 
				
			||||||
      AppWeb.Endpoint
 | 
					      AppWeb.Endpoint
 | 
				
			||||||
      # Start a worker by calling: AppWeb.Worker.start_link(arg)
 | 
					      # Start a worker by calling: AppWeb.Worker.start_link(arg)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,12 @@ defmodule AppWeb.Endpoint do
 | 
				
			||||||
    gzip: false,
 | 
					    gzip: false,
 | 
				
			||||||
    only: ~w(css fonts images js favicon.ico robots.txt)
 | 
					    only: ~w(css fonts images js favicon.ico robots.txt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  plug Plug.Static,
 | 
				
			||||||
 | 
					    at: "/kaffy",
 | 
				
			||||||
 | 
					    from: :kaffy,
 | 
				
			||||||
 | 
					    gzip: false,
 | 
				
			||||||
 | 
					    only: ~w(assets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Code reloading can be explicitly enabled under the
 | 
					  # Code reloading can be explicitly enabled under the
 | 
				
			||||||
  # :code_reloader configuration of your endpoint.
 | 
					  # :code_reloader configuration of your endpoint.
 | 
				
			||||||
  if code_reloading? do
 | 
					  if code_reloading? do
 | 
				
			||||||
| 
						 | 
					@ -50,5 +56,7 @@ defmodule AppWeb.Endpoint do
 | 
				
			||||||
  plug Plug.MethodOverride
 | 
					  plug Plug.MethodOverride
 | 
				
			||||||
  plug Plug.Head
 | 
					  plug Plug.Head
 | 
				
			||||||
  plug Plug.Session, @session_options
 | 
					  plug Plug.Session, @session_options
 | 
				
			||||||
 | 
					  plug Pow.Plug.Session, otp_app: :auth_web
 | 
				
			||||||
 | 
					  plug PowPersistentSession.Plug.Cookie
 | 
				
			||||||
  plug AppWeb.Router
 | 
					  plug AppWeb.Router
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,10 @@
 | 
				
			||||||
defmodule AppWeb.Router do
 | 
					defmodule AppWeb.Router do
 | 
				
			||||||
  use AppWeb, :router
 | 
					  use AppWeb, :router
 | 
				
			||||||
 | 
					  use Pow.Phoenix.Router
 | 
				
			||||||
 | 
					  use Pow.Extension.Phoenix.Router,
 | 
				
			||||||
 | 
					    extensions: [PowResetPassword, PowEmailConfirmation]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  alias AuthWeb.Plugs.{RequireAdmin}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :browser do
 | 
					  pipeline :browser do
 | 
				
			||||||
    plug :accepts, ["html"]
 | 
					    plug :accepts, ["html"]
 | 
				
			||||||
| 
						 | 
					@ -7,13 +12,21 @@ defmodule AppWeb.Router do
 | 
				
			||||||
    plug :fetch_flash
 | 
					    plug :fetch_flash
 | 
				
			||||||
    plug :protect_from_forgery
 | 
					    plug :protect_from_forgery
 | 
				
			||||||
    plug :put_secure_browser_headers
 | 
					    plug :put_secure_browser_headers
 | 
				
			||||||
    plug :put_layout, {CoreWeb.LayoutView, :app}
 | 
					    plug :put_layout, {AppWeb.LayoutView, :app}
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :api do
 | 
					  pipeline :api do
 | 
				
			||||||
    plug :accepts, ["json"]
 | 
					    plug :accepts, ["json"]
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pipeline :require_admin do
 | 
				
			||||||
 | 
					    plug(RequireAdmin)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pipeline :require_auth do
 | 
				
			||||||
 | 
					    plug Pow.Plug.RequireAuthenticated, error_handler: Pow.Phoenix.PlugErrorHandler
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Other scopes may use custom stacks.
 | 
					  # Other scopes may use custom stacks.
 | 
				
			||||||
  # scope "/api", AppWeb do
 | 
					  # scope "/api", AppWeb do
 | 
				
			||||||
  #   pipe_through :api
 | 
					  #   pipe_through :api
 | 
				
			||||||
| 
						 | 
					@ -33,5 +46,17 @@ defmodule AppWeb.Router do
 | 
				
			||||||
      pipe_through :browser
 | 
					      pipe_through :browser
 | 
				
			||||||
      live_dashboard "/dashboard", metrics: AppWeb.Telemetry
 | 
					      live_dashboard "/dashboard", metrics: AppWeb.Telemetry
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    forward "/sent_emails", Bamboo.SentEmailViewerPlug
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  scope "/" do
 | 
				
			||||||
 | 
					    pipe_through :browser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pow_routes()
 | 
				
			||||||
 | 
					    pow_extension_routes()
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  use Admin.Routes
 | 
				
			||||||
 | 
					  use Content.Routes
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,16 +20,16 @@
 | 
				
			||||||
      <% end %>
 | 
					      <% end %>
 | 
				
			||||||
      <%= if Pow.Plug.current_user(@conn) do %>
 | 
					      <%= if Pow.Plug.current_user(@conn) do %>
 | 
				
			||||||
        <li class="mr-3">
 | 
					        <li class="mr-3">
 | 
				
			||||||
          <%= link "Sign Out", to: AuthWeb.Router.Helpers.pow_session_path(%URI{path: "/auth"}, :delete), method: :delete, class: "inline-block text-white  no-underline hover:text-white hover:text-underline py-2 px-4" %>
 | 
					          <%= link "Sign Out", to: Routes.pow_session_path(@conn, :delete), method: :delete, class: "inline-block text-white  no-underline hover:text-white hover:text-underline py-2 px-4" %>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
      <% else %>
 | 
					      <% else %>
 | 
				
			||||||
        <li class="mr-3">
 | 
					        <li class="mr-3">
 | 
				
			||||||
          <%= link to: AuthWeb.Router.Helpers.pow_session_path(%URI{path: "/auth"}, :new), class: "inline-block text-white  no-underline hover:text-white hover:text-underline py-2 px-4" do %>
 | 
					          <%= link to: Routes.pow_session_path(@conn, :new), class: "inline-block text-white  no-underline hover:text-white hover:text-underline py-2 px-4" do %>
 | 
				
			||||||
            Log In
 | 
					            Log In
 | 
				
			||||||
          <% end %>
 | 
					          <% end %>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li class="mr-3">
 | 
					        <li class="mr-3">
 | 
				
			||||||
          <%= link to: AuthWeb.Router.Helpers.pow_registration_path(%URI{path: "/auth"}, :new), class: "inline-block text-white  no-underline hover:text-white hover:text-underline py-2 px-4" do %>
 | 
					          <%= link to: Routes.pow_registration_path(@conn, :new), class: "inline-block text-white  no-underline hover:text-white hover:text-underline py-2 px-4" do %>
 | 
				
			||||||
            Sign Up
 | 
					            Sign Up
 | 
				
			||||||
          <% end %>
 | 
					          <% end %>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,39 @@
 | 
				
			||||||
defmodule AppWeb.LayoutView do
 | 
					defmodule AppWeb.LayoutView do
 | 
				
			||||||
  use AppWeb, :view
 | 
					  use AppWeb, :view
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def title(view_module, template, assigns) do
 | 
				
			||||||
 | 
					    delegate_with_default(view_module, :title, [view_module, template, assigns], I18n.t!("en", "site.title"))
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def excerpt(view_module, template, assigns) do
 | 
				
			||||||
 | 
					    delegate_with_default(view_module, :excerpt, [view_module, template, assigns], I18n.t!("en", "site.excerpt"))
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def feed_tag(conn, view_module, view_template, assigns) do
 | 
				
			||||||
 | 
					    delegate_with_default(view_module, :feed_tag, [conn, view_module, view_template, assigns], nil)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  defp delegate_with_default(nil, _, _, default), do: default
 | 
				
			||||||
 | 
					  defp delegate_with_default(view_module, function_name, args, default) do
 | 
				
			||||||
 | 
					    sibling_layout = sibling_layout_view(view_module)
 | 
				
			||||||
 | 
					    if function_exported?(sibling_layout, function_name, args |> Enum.count()) do
 | 
				
			||||||
 | 
					      apply(sibling_layout, function_name, args)
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      default
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  defp sibling_layout_view(view_module) do
 | 
				
			||||||
 | 
					    view_module
 | 
				
			||||||
 | 
					    |> parent_module()
 | 
				
			||||||
 | 
					    |> Module.concat("LayoutView")
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  defp parent_module(mod) do
 | 
				
			||||||
 | 
					    [_|tail] = Module.split(mod) |> Enum.reverse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tail
 | 
				
			||||||
 | 
					    |> Enum.reverse()
 | 
				
			||||||
 | 
					    |> Module.concat()
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,8 @@ defmodule App.MixProject do
 | 
				
			||||||
  # Type `mix help deps` for examples and options.
 | 
					  # Type `mix help deps` for examples and options.
 | 
				
			||||||
  defp deps do
 | 
					  defp deps do
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
 | 
					      {:admin, in_umbrella: true},
 | 
				
			||||||
 | 
					      {:content, in_umbrella: true},
 | 
				
			||||||
      {:core, in_umbrella: true},
 | 
					      {:core, in_umbrella: true},
 | 
				
			||||||
      {:ecto_sql, "~> 3.4"},
 | 
					      {:ecto_sql, "~> 3.4"},
 | 
				
			||||||
      {:excoveralls, "~> 0.10", only: [:dev, :test]},
 | 
					      {:excoveralls, "~> 0.10", only: [:dev, :test]},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,31 @@
 | 
				
			||||||
defmodule App.LayoutViewTest do
 | 
					defmodule App.LayoutViewTest do
 | 
				
			||||||
  use App.ConnCase, async: true
 | 
					  use App.ConnCase, async: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # When testing helpers, you may want to import Phoenix.HTML and
 | 
					  import AppWeb.LayoutView
 | 
				
			||||||
  # use functions such as safe_to_string() to convert the helper
 | 
					
 | 
				
			||||||
  # result into an HTML string.
 | 
					  describe "title/3" do
 | 
				
			||||||
  # import Phoenix.HTML
 | 
					    def default_title do
 | 
				
			||||||
 | 
					      I18n.t! "en", "site.title"
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test "for nil" do
 | 
				
			||||||
 | 
					      assert title(nil, nil, nil) =~ default_title()
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe "excerpt/3" do
 | 
				
			||||||
 | 
					    def default_excerpt do
 | 
				
			||||||
 | 
					      I18n.t! "en", "site.excerpt"
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test "for nil" do
 | 
				
			||||||
 | 
					      assert excerpt(nil, nil, nil) =~ default_excerpt()
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe "feed_tag/4" do
 | 
				
			||||||
 | 
					    test "for nil" do
 | 
				
			||||||
 | 
					      assert feed_tag(nil, nil, nil, nil) == nil
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,6 @@ defmodule AuthWeb.Router do
 | 
				
			||||||
    plug :fetch_flash
 | 
					    plug :fetch_flash
 | 
				
			||||||
    plug :protect_from_forgery
 | 
					    plug :protect_from_forgery
 | 
				
			||||||
    plug :put_secure_browser_headers
 | 
					    plug :put_secure_browser_headers
 | 
				
			||||||
    plug :put_layout, {CoreWeb.LayoutView, :app}
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :api do
 | 
					  pipeline :api do
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,5 +5,4 @@ defmodule AuthWeb.EmailView do
 | 
				
			||||||
    pattern: "**/*"
 | 
					    pattern: "**/*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  import Phoenix.HTML, only: [raw: 1]
 | 
					  import Phoenix.HTML, only: [raw: 1]
 | 
				
			||||||
  import CoreWeb.EmailHelpers
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ defmodule Content.MarkupField do
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def render_index(conn, resource, field, _opts) do
 | 
					  def render_index(_conn, resource, field, _opts) do
 | 
				
			||||||
    case Map.get(resource, field) do
 | 
					    case Map.get(resource, field) do
 | 
				
			||||||
      nil ->
 | 
					      nil ->
 | 
				
			||||||
        ""
 | 
					        ""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,8 +77,14 @@ defmodule Content.PostsController do
 | 
				
			||||||
      e in Phoenix.Template.UndefinedError ->
 | 
					      e in Phoenix.Template.UndefinedError ->
 | 
				
			||||||
        case e do
 | 
					        case e do
 | 
				
			||||||
          %{template: ^path} ->
 | 
					          %{template: ^path} ->
 | 
				
			||||||
 | 
					            router =
 | 
				
			||||||
 | 
					              case conn do
 | 
				
			||||||
 | 
					                %{private: %{phoenix_router: router}} -> router
 | 
				
			||||||
 | 
					                _ -> Content.Router
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # The static page we're looking for is missing, so this is just a 404
 | 
					            # The static page we're looking for is missing, so this is just a 404
 | 
				
			||||||
            raise Phoenix.Router.NoRouteError.exception(conn: conn, router: Content.Router)
 | 
					            raise Phoenix.Router.NoRouteError.exception(conn: conn, router: router)
 | 
				
			||||||
          _ ->
 | 
					          _ ->
 | 
				
			||||||
            # We aren't missing the static page, we're missing a partial. This is probably
 | 
					            # We aren't missing the static page, we're missing a partial. This is probably
 | 
				
			||||||
            # a developer error, so bubble it up
 | 
					            # a developer error, so bubble it up
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,57 +8,19 @@ defmodule Content.Router do
 | 
				
			||||||
    plug :fetch_flash
 | 
					    plug :fetch_flash
 | 
				
			||||||
    plug :protect_from_forgery
 | 
					    plug :protect_from_forgery
 | 
				
			||||||
    plug :put_secure_browser_headers
 | 
					    plug :put_secure_browser_headers
 | 
				
			||||||
    plug :put_layout, {CoreWeb.LayoutView, :app}
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :api do
 | 
					  pipeline :api do
 | 
				
			||||||
    plug :accepts, ["json"]
 | 
					    plug :accepts, ["json"]
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :feed do
 | 
					  pipeline :require_admin do
 | 
				
			||||||
    plug :accepts, ["rss"]
 | 
					    plug(RequireAdmin)
 | 
				
			||||||
    plug :fetch_session
 | 
					 | 
				
			||||||
    plug :protect_from_forgery
 | 
					 | 
				
			||||||
    plug :put_secure_browser_headers
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :require_auth do
 | 
					  pipeline :require_auth do
 | 
				
			||||||
    plug Pow.Plug.RequireAuthenticated, error_handler: Pow.Phoenix.PlugErrorHandler
 | 
					    plug Pow.Plug.RequireAuthenticated, error_handler: Pow.Phoenix.PlugErrorHandler
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :require_admin do
 | 
					  use Content.Routes
 | 
				
			||||||
    plug(RequireAdmin)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pipeline :admin_layout do
 | 
					 | 
				
			||||||
    plug :put_layout, {Content.LayoutView, :admin}
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope "/", Content do
 | 
					 | 
				
			||||||
    pipe_through([:browser, :require_auth, :require_admin, :admin_layout])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    put "/posts/preview", PostsController, :preview
 | 
					 | 
				
			||||||
    post "/posts/preview", PostsController, :preview
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope "/", Content do
 | 
					 | 
				
			||||||
    pipe_through :feed # Use the default browser stack
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    get "/category/:category/feed.rss", FeedsController, :index, as: :category_feed
 | 
					 | 
				
			||||||
    get "/feed.rss", FeedsController, :index, as: :index_feed
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope "/", Content do
 | 
					 | 
				
			||||||
    pipe_through :browser # Use the default browser stack
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    resources "/comments", CommentController, as: :comment, only: [:create, :delete, :update]
 | 
					 | 
				
			||||||
    get "/page/:page", PostsController, :index_posts, as: :blog_page
 | 
					 | 
				
			||||||
    get "/category/:category", PostsController, :index_posts, as: :category
 | 
					 | 
				
			||||||
    get "/category/:category/page/:page", PostsController, :index, as: :category_page
 | 
					 | 
				
			||||||
    post "/wp-login.php", PostPasswordController, :create
 | 
					 | 
				
			||||||
    get "/", PostsController, :index
 | 
					 | 
				
			||||||
    resources "/sitemap", SitemapController, only: [:index]
 | 
					 | 
				
			||||||
    get "/:id", PostsController, :show
 | 
					 | 
				
			||||||
    get "/:id/:page", PostsController, :show, as: :paged_post
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								apps/content/lib/content_web/routes.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					defmodule Content.Routes do
 | 
				
			||||||
 | 
					  defmacro __using__(_opts \\ []) do
 | 
				
			||||||
 | 
					    quote do
 | 
				
			||||||
 | 
					      pipeline :feed do
 | 
				
			||||||
 | 
					        plug :accepts, ["rss"]
 | 
				
			||||||
 | 
					        plug :fetch_session
 | 
				
			||||||
 | 
					        plug :protect_from_forgery
 | 
				
			||||||
 | 
					        plug :put_secure_browser_headers
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      scope "/", Content do
 | 
				
			||||||
 | 
					        pipe_through([:browser, :require_auth, :require_admin])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        put "/posts/preview", PostsController, :preview
 | 
				
			||||||
 | 
					        post "/posts/preview", PostsController, :preview
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      scope "/", Content do
 | 
				
			||||||
 | 
					        pipe_through :feed # Use the default browser stack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        get "/category/:category/feed.rss", FeedsController, :index, as: :category_feed
 | 
				
			||||||
 | 
					        get "/feed.rss", FeedsController, :index, as: :index_feed
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      scope "/", Content do
 | 
				
			||||||
 | 
					        pipe_through :browser # Use the default browser stack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        resources "/comments", CommentController, as: :comment, only: [:create, :delete, :update]
 | 
				
			||||||
 | 
					        get "/page/:page", PostsController, :index_posts, as: :blog_page
 | 
				
			||||||
 | 
					        get "/category/:category", PostsController, :index_posts, as: :category
 | 
				
			||||||
 | 
					        get "/category/:category/page/:page", PostsController, :index, as: :category_page
 | 
				
			||||||
 | 
					        post "/wp-login.php", PostPasswordController, :create
 | 
				
			||||||
 | 
					        get "/", PostsController, :index
 | 
				
			||||||
 | 
					        resources "/sitemap", SitemapController, only: [:index]
 | 
				
			||||||
 | 
					        get "/:id", PostsController, :show
 | 
				
			||||||
 | 
					        get "/:id/:page", PostsController, :show, as: :paged_post
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										22
									
								
								apps/content/lib/content_web/templates/layout/app.html.eex
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					  <head>
 | 
				
			||||||
 | 
					    <meta charset="utf-8"/>
 | 
				
			||||||
 | 
					    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
 | 
				
			||||||
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 | 
				
			||||||
 | 
					    <title><%= title(@view_module, @view_template, assigns) %></title>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
 | 
				
			||||||
 | 
					    <%= feed_tag(@conn, @view_module, @view_template, assigns) %>
 | 
				
			||||||
 | 
					    <script defer type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
 | 
				
			||||||
 | 
					  </head>
 | 
				
			||||||
 | 
					  <body class="text-gray-800 antialiased">
 | 
				
			||||||
 | 
					    <main role="main">
 | 
				
			||||||
 | 
					      <!-- Page Contents -->
 | 
				
			||||||
 | 
					      <div class="bg-gray-100 min-h-screen">
 | 
				
			||||||
 | 
					        <%= flash_block(@conn) %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <%= @inner_content %>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </main>
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@
 | 
				
			||||||
    <div class="Article-content <%= if post.format, do: post.format.slug %> e-content">
 | 
					    <div class="Article-content <%= if post.format, do: post.format.slug %> e-content">
 | 
				
			||||||
      <%= render "thumb.html", post: post, thumbs: @thumbs %>
 | 
					      <%= render "thumb.html", post: post, thumbs: @thumbs %>
 | 
				
			||||||
      <div class="Article-content-words">
 | 
					      <div class="Article-content-words">
 | 
				
			||||||
        <%= raw post |> Content.Post.content_page(1) |> Content.Post.before_more |> process_content |> () |> raw %>
 | 
					        <%= raw post |> Content.Post.content_page(1) |> Content.Post.before_more |> process_content |> raw %>
 | 
				
			||||||
        <%= if post.content =~ "<!--more-->" do %>
 | 
					        <%= if post.content =~ "<!--more-->" do %>
 | 
				
			||||||
          <p>
 | 
					          <p>
 | 
				
			||||||
            <%= link "Keep Reading", to: Routes.posts_path(@conn, :show, post) %>
 | 
					            <%= link "Keep Reading", to: Routes.posts_path(@conn, :show, post) %>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,8 +20,8 @@
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="w-full lg:w-8/12 px-4 ml-auto mr-auto text-center my-12">
 | 
					        <div class="w-full lg:w-8/12 px-4 ml-auto mr-auto text-center my-12">
 | 
				
			||||||
          <%= styled_button_link "Log In", to: AuthWeb.Router.Helpers.pow_session_path(%URI{path: "/auth"}, :new) %>
 | 
					          <%= styled_button_link "Log In", to: "/session/new" %>
 | 
				
			||||||
          <%= styled_button_link "Sign Up", to: AuthWeb.Router.Helpers.pow_registration_path(%URI{path: "/auth"}, :new) %>
 | 
					          <%= styled_button_link "Sign Up", to: "/registration/new" %>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
| 
						 | 
					@ -160,8 +160,8 @@
 | 
				
			||||||
            </h1>
 | 
					            </h1>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <div class="w-full lg:w-8/12 px-4 ml-auto mr-auto text-center my-12">
 | 
					          <div class="w-full lg:w-8/12 px-4 ml-auto mr-auto text-center my-12">
 | 
				
			||||||
            <%= styled_button_link "Log In", to: AuthWeb.Router.Helpers.pow_session_path(%URI{path: "/auth"}, :new) %>
 | 
					            <%= styled_button_link "Log In", to: "/session/new" %>
 | 
				
			||||||
            <%= styled_button_link "Sign Up", to: AuthWeb.Router.Helpers.pow_registration_path(%URI{path: "/auth"}, :new) %>
 | 
					            <%= styled_button_link "Sign Up", to: "/registration/new" %>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +0,0 @@
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    "presets": [
 | 
					 | 
				
			||||||
        "@babel/preset-env"
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,57 +0,0 @@
 | 
				
			||||||
// We need to import the CSS so that webpack will load it.
 | 
					 | 
				
			||||||
// The MiniCssExtractPlugin is used to separate it out into
 | 
					 | 
				
			||||||
// its own CSS file.
 | 
					 | 
				
			||||||
import "../css/app.css"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// webpack automatically bundles all modules in your
 | 
					 | 
				
			||||||
// entry points. Those entry points can be configured
 | 
					 | 
				
			||||||
// in "webpack.config.js".
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Import deps with the dep name or local files with a relative path, for example:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     import {Socket} from "phoenix"
 | 
					 | 
				
			||||||
//     import socket from "./socket"
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
import "phoenix_html"
 | 
					 | 
				
			||||||
import { ready } from "./utils"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function togglePasswordFieldVisibility()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  const passwordFields = document.querySelectorAll('[name="user[password]"]')
 | 
					 | 
				
			||||||
  passwordFields.forEach((el) => {
 | 
					 | 
				
			||||||
    if (el.type == 'password')
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      el.type = 'text'
 | 
					 | 
				
			||||||
    } 
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      el.type = 'password'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const toggleSidebar = (event) => {
 | 
					 | 
				
			||||||
  document.querySelectorAll('.sidebar').forEach((el) => {
 | 
					 | 
				
			||||||
    el.classList.toggle('visible')
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ready(() => {
 | 
					 | 
				
			||||||
  document.getElementById('nav-toggle').onclick = function(){
 | 
					 | 
				
			||||||
    document.getElementById("nav-content").classList.toggle("hidden");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  document.querySelectorAll('.js-passwordRevealer').forEach((el) => {
 | 
					 | 
				
			||||||
    el.addEventListener('click', togglePasswordFieldVisibility)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  document.querySelectorAll('.js-SidebarOpener').forEach((el) => {
 | 
					 | 
				
			||||||
    el.addEventListener('click', toggleSidebar)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  document.querySelectorAll('.js-flash-closer').forEach((el) => {
 | 
					 | 
				
			||||||
    el.addEventListener('click', () => {
 | 
					 | 
				
			||||||
      el.closest('.js-flash').remove()
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,63 +0,0 @@
 | 
				
			||||||
// NOTE: The contents of this file will only be executed if
 | 
					 | 
				
			||||||
// you uncomment its entry in "assets/js/app.js".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// To use Phoenix channels, the first step is to import Socket,
 | 
					 | 
				
			||||||
// and connect at the socket path in "lib/web/endpoint.ex".
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Pass the token on params as below. Or remove it
 | 
					 | 
				
			||||||
// from the params if you are not using authentication.
 | 
					 | 
				
			||||||
import {Socket} from "phoenix"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let socket = new Socket("/socket", {params: {token: window.userToken}})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// When you connect, you'll often need to authenticate the client.
 | 
					 | 
				
			||||||
// For example, imagine you have an authentication plug, `MyAuth`,
 | 
					 | 
				
			||||||
// which authenticates the session and assigns a `:current_user`.
 | 
					 | 
				
			||||||
// If the current user exists you can assign the user's token in
 | 
					 | 
				
			||||||
// the connection for use in the layout.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// In your "lib/web/router.ex":
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     pipeline :browser do
 | 
					 | 
				
			||||||
//       ...
 | 
					 | 
				
			||||||
//       plug MyAuth
 | 
					 | 
				
			||||||
//       plug :put_user_token
 | 
					 | 
				
			||||||
//     end
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     defp put_user_token(conn, _) do
 | 
					 | 
				
			||||||
//       if current_user = conn.assigns[:current_user] do
 | 
					 | 
				
			||||||
//         token = Phoenix.Token.sign(conn, "user socket", current_user.id)
 | 
					 | 
				
			||||||
//         assign(conn, :user_token, token)
 | 
					 | 
				
			||||||
//       else
 | 
					 | 
				
			||||||
//         conn
 | 
					 | 
				
			||||||
//       end
 | 
					 | 
				
			||||||
//     end
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Now you need to pass this token to JavaScript. You can do so
 | 
					 | 
				
			||||||
// inside a script tag in "lib/web/templates/layout/app.html.eex":
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     <script>window.userToken = "<%= assigns[:user_token] %>";</script>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// You will need to verify the user token in the "connect/3" function
 | 
					 | 
				
			||||||
// in "lib/web/channels/user_socket.ex":
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//     def connect(%{"token" => token}, socket, _connect_info) do
 | 
					 | 
				
			||||||
//       # max_age: 1209600 is equivalent to two weeks in seconds
 | 
					 | 
				
			||||||
//       case Phoenix.Token.verify(socket, "user socket", token, max_age: 1209600) do
 | 
					 | 
				
			||||||
//         {:ok, user_id} ->
 | 
					 | 
				
			||||||
//           {:ok, assign(socket, :user, user_id)}
 | 
					 | 
				
			||||||
//         {:error, reason} ->
 | 
					 | 
				
			||||||
//           :error
 | 
					 | 
				
			||||||
//       end
 | 
					 | 
				
			||||||
//     end
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Finally, connect to the socket:
 | 
					 | 
				
			||||||
socket.connect()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Now that you are connected, you can join channels with a topic:
 | 
					 | 
				
			||||||
let channel = socket.channel("topic:subtopic", {})
 | 
					 | 
				
			||||||
channel.join()
 | 
					 | 
				
			||||||
  .receive("ok", resp => { console.log("Joined successfully", resp) })
 | 
					 | 
				
			||||||
  .receive("error", resp => { console.log("Unable to join", resp) })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default socket
 | 
					 | 
				
			||||||
							
								
								
									
										12798
									
								
								apps/core/assets/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						| 
						 | 
					@ -1,52 +0,0 @@
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  "repository": {},
 | 
					 | 
				
			||||||
  "description": " ",
 | 
					 | 
				
			||||||
  "license": "MIT",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					 | 
				
			||||||
    "deploy": "webpack --mode production",
 | 
					 | 
				
			||||||
    "watch": "webpack --mode development --watch",
 | 
					 | 
				
			||||||
    "preinstall": "npx npm-force-resolutions",
 | 
					 | 
				
			||||||
    "profile": "webpack --mode development --plugin webpack/lib/debug/ProfilingPlugin"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "@fortawesome/fontawesome-free": "^5.14.0",
 | 
					 | 
				
			||||||
    "autoprefixer": "^9.8.6",
 | 
					 | 
				
			||||||
    "csswring": "^7.0.0",
 | 
					 | 
				
			||||||
    "glob": "^7.1.6",
 | 
					 | 
				
			||||||
    "gulp": "^4.0.2",
 | 
					 | 
				
			||||||
    "phoenix": "file:../deps/phoenix",
 | 
					 | 
				
			||||||
    "phoenix_html": "file:../deps/phoenix_html",
 | 
					 | 
				
			||||||
    "postcss-color-function": "^4.1.0",
 | 
					 | 
				
			||||||
    "simplemde": "^1.11.2",
 | 
					 | 
				
			||||||
    "stylelint": "^13.6.1",
 | 
					 | 
				
			||||||
    "tailwindcss": "^1.7.3"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "devDependencies": {
 | 
					 | 
				
			||||||
    "@babel/core": "^7.0.0",
 | 
					 | 
				
			||||||
    "@babel/preset-env": "^7.0.0",
 | 
					 | 
				
			||||||
    "babel-loader": "^8.0.0",
 | 
					 | 
				
			||||||
    "copy-webpack-plugin": "^5.1.1",
 | 
					 | 
				
			||||||
    "css-loader": "^3.4.2",
 | 
					 | 
				
			||||||
    "extract-text-webpack-plugin": "^3.0.2",
 | 
					 | 
				
			||||||
    "file-loader": "^6.0.0",
 | 
					 | 
				
			||||||
    "image-webpack-loader": "^6.0.0",
 | 
					 | 
				
			||||||
    "less": "^3.11.3",
 | 
					 | 
				
			||||||
    "less-loader": "^6.2.0",
 | 
					 | 
				
			||||||
    "mini-css-extract-plugin": "^0.9.0",
 | 
					 | 
				
			||||||
    "node-sass": "^4.13.1",
 | 
					 | 
				
			||||||
    "optimize-css-assets-webpack-plugin": "^5.0.1",
 | 
					 | 
				
			||||||
    "postcss-css-variables": "^0.17.0",
 | 
					 | 
				
			||||||
    "postcss-import": "^12.0.1",
 | 
					 | 
				
			||||||
    "postcss-loader": "^3.0.0",
 | 
					 | 
				
			||||||
    "sass-loader": "^8.0.2",
 | 
					 | 
				
			||||||
    "style-loader": "^1.2.1",
 | 
					 | 
				
			||||||
    "stylelint-config-standard": "^20.0.0",
 | 
					 | 
				
			||||||
    "stylelint-order": "^4.1.0",
 | 
					 | 
				
			||||||
    "terser-webpack-plugin": "^2.3.2",
 | 
					 | 
				
			||||||
    "webpack": "4.41.5",
 | 
					 | 
				
			||||||
    "webpack-cli": "^3.3.2"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "resolutions": {
 | 
					 | 
				
			||||||
    "graceful-fs": "4.2.3"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB  | 
| 
						 | 
					@ -1,5 +0,0 @@
 | 
				
			||||||
# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# To ban all spiders from the entire site uncomment the next two lines:
 | 
					 | 
				
			||||||
# User-agent: *
 | 
					 | 
				
			||||||
# Disallow: /
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,105 +0,0 @@
 | 
				
			||||||
const path = require('path');
 | 
					 | 
				
			||||||
const glob = require('glob');
 | 
					 | 
				
			||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 | 
					 | 
				
			||||||
const TerserPlugin = require('terser-webpack-plugin');
 | 
					 | 
				
			||||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
 | 
					 | 
				
			||||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const nodeModulesPath = path.resolve(__dirname, 'node_modules')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = (env, options) => {
 | 
					 | 
				
			||||||
  const devMode = options.mode !== 'production';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    optimization: {
 | 
					 | 
				
			||||||
      minimizer: [
 | 
					 | 
				
			||||||
        new TerserPlugin({ cache: true, parallel: true, sourceMap: devMode }),
 | 
					 | 
				
			||||||
        new OptimizeCSSAssetsPlugin({})
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    mode: options.mode,
 | 
					 | 
				
			||||||
    devtool: devMode ? 'source-map' : undefined,
 | 
					 | 
				
			||||||
    entry: {
 | 
					 | 
				
			||||||
      'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
 | 
					 | 
				
			||||||
      'content-editor': ['./js/content-editor.js'],
 | 
					 | 
				
			||||||
      'tailwind': ['./tailwind.config.js'],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    output: {
 | 
					 | 
				
			||||||
      filename: 'js/[name].js',
 | 
					 | 
				
			||||||
      path: path.resolve(__dirname, '../priv/static/')
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    module: {
 | 
					 | 
				
			||||||
      rules: [
 | 
					 | 
				
			||||||
        // For images and fonts found in our scss files
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          test: /\.(jpg|jpeg|gif|png)$/,
 | 
					 | 
				
			||||||
          use: [
 | 
					 | 
				
			||||||
            'file-loader',
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              loader: 'image-webpack-loader',
 | 
					 | 
				
			||||||
              options: {
 | 
					 | 
				
			||||||
                disable: devMode,
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          test: /\.(woff2?|ttf|eot|svg)(\?[a-z0-9\=\.]+)?$/,
 | 
					 | 
				
			||||||
          loader: 'file-loader',
 | 
					 | 
				
			||||||
          options: {
 | 
					 | 
				
			||||||
            publicPath: '/fonts',
 | 
					 | 
				
			||||||
            outputPath: (url, resourcePath, context) => {
 | 
					 | 
				
			||||||
              return `/fonts/${url}`;
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          test: /\.js$/,
 | 
					 | 
				
			||||||
          exclude: /node_modules/,
 | 
					 | 
				
			||||||
          use: {
 | 
					 | 
				
			||||||
            loader: 'babel-loader'
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          test: /\.css$/,
 | 
					 | 
				
			||||||
          use: [
 | 
					 | 
				
			||||||
            {loader: MiniCssExtractPlugin.loader, options: {sourceMap: true}},
 | 
					 | 
				
			||||||
            {loader: 'css-loader', options: {sourceMap: true}},
 | 
					 | 
				
			||||||
            {loader: 'postcss-loader', options: {sourceMap: true}},
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    plugins: [
 | 
					 | 
				
			||||||
      new MiniCssExtractPlugin({
 | 
					 | 
				
			||||||
        filename: 'css/[name].css',
 | 
					 | 
				
			||||||
        chunkFilename: '[id].css',
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
      new CopyWebpackPlugin([
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          from: path.resolve(__dirname, 'static'),
 | 
					 | 
				
			||||||
          to: path.resolve(__dirname, '../priv/static'),
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ]),
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    resolve: {
 | 
					 | 
				
			||||||
      alias: {
 | 
					 | 
				
			||||||
        "../webfonts/fa-brands-400.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.eot"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-brands-400.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff2"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-brands-400.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-brands-400.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.ttf"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-brands-400.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.svg"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-regular-400.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.eot"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-regular-400.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff2"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-regular-400.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-regular-400.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.ttf"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-regular-400.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.svg"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-solid-900.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.eot"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-solid-900.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-solid-900.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-solid-900.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.ttf"),
 | 
					 | 
				
			||||||
        "../webfonts/fa-solid-900.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.svg"),
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ config :core,
 | 
				
			||||||
  ecto_repos: [Core.Repo]
 | 
					  ecto_repos: [Core.Repo]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Configures the endpoint
 | 
					# Configures the endpoint
 | 
				
			||||||
config :core, CoreWeb.Endpoint,
 | 
					config :core, AppWeb.Endpoint,
 | 
				
			||||||
  url: [host: "localhost"],
 | 
					  url: [host: "localhost"],
 | 
				
			||||||
  secret_key_base: "kNJbLKCmuZYSK99S55+DmirA2TlmOxzs/xz3xnlXtOhQCoBMmYRabaRLTXkcsw5d",
 | 
					  secret_key_base: "kNJbLKCmuZYSK99S55+DmirA2TlmOxzs/xz3xnlXtOhQCoBMmYRabaRLTXkcsw5d",
 | 
				
			||||||
  render_errors: [view: CoreWeb.ErrorView, accepts: ~w(html json), layout: false],
 | 
					  render_errors: [view: CoreWeb.ErrorView, accepts: ~w(html json), layout: false],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,20 +15,20 @@ config :core, Core.Repo,
 | 
				
			||||||
# The watchers configuration can be used to run external
 | 
					# The watchers configuration can be used to run external
 | 
				
			||||||
# watchers to your application. For example, we use it
 | 
					# watchers to your application. For example, we use it
 | 
				
			||||||
# with webpack to recompile .js and .css sources.
 | 
					# with webpack to recompile .js and .css sources.
 | 
				
			||||||
config :core, CoreWeb.Endpoint,
 | 
					# config :core, CoreWeb.Endpoint,
 | 
				
			||||||
  http: [port: 4000],
 | 
					#   http: [port: 4000],
 | 
				
			||||||
  debug_errors: true,
 | 
					#   debug_errors: true,
 | 
				
			||||||
  code_reloader: true,
 | 
					#   code_reloader: true,
 | 
				
			||||||
  check_origin: false,
 | 
					#   check_origin: false,
 | 
				
			||||||
  watchers: [
 | 
					#   watchers: [
 | 
				
			||||||
    node: [
 | 
					#     node: [
 | 
				
			||||||
      "node_modules/webpack/bin/webpack.js",
 | 
					#       "node_modules/webpack/bin/webpack.js",
 | 
				
			||||||
      "--mode",
 | 
					#       "--mode",
 | 
				
			||||||
      "development",
 | 
					#       "development",
 | 
				
			||||||
      "--watch-stdin",
 | 
					#       "--watch-stdin",
 | 
				
			||||||
      cd: Path.expand("../assets", __DIR__)
 | 
					#       cd: Path.expand("../assets", __DIR__)
 | 
				
			||||||
    ]
 | 
					#     ]
 | 
				
			||||||
  ]
 | 
					#   ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# ## SSL Support
 | 
					# ## SSL Support
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ use Mix.Config
 | 
				
			||||||
# manifest is generated by the `mix phx.digest` task,
 | 
					# manifest is generated by the `mix phx.digest` task,
 | 
				
			||||||
# which you should run after static files are built and
 | 
					# which you should run after static files are built and
 | 
				
			||||||
# before starting your production server.
 | 
					# before starting your production server.
 | 
				
			||||||
config :core, CoreWeb.Endpoint,
 | 
					config :core, AppWeb.Endpoint,
 | 
				
			||||||
  url: [host: "example.com", port: 80],
 | 
					  url: [host: "example.com", port: 80],
 | 
				
			||||||
  cache_static_manifest: "priv/static/cache_manifest.json"
 | 
					  cache_static_manifest: "priv/static/cache_manifest.json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ secret_key_base =
 | 
				
			||||||
    You can generate one by calling: mix phx.gen.secret
 | 
					    You can generate one by calling: mix phx.gen.secret
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config :core, CoreWeb.Endpoint,
 | 
					config :core, AppWeb.Endpoint,
 | 
				
			||||||
  http: [
 | 
					  http: [
 | 
				
			||||||
    port: String.to_integer(System.get_env("PORT") || "4000"),
 | 
					    port: String.to_integer(System.get_env("PORT") || "4000"),
 | 
				
			||||||
    transport_options: [socket_opts: [:inet6]]
 | 
					    transport_options: [socket_opts: [:inet6]]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ config :core, Core.Repo,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# We don't run a server during test. If one is required,
 | 
					# We don't run a server during test. If one is required,
 | 
				
			||||||
# you can enable the server option below.
 | 
					# you can enable the server option below.
 | 
				
			||||||
config :core, CoreWeb.Endpoint,
 | 
					config :core, AppWeb.Endpoint,
 | 
				
			||||||
  http: [port: 4002],
 | 
					  http: [port: 4002],
 | 
				
			||||||
  server: false
 | 
					  server: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,6 @@ defmodule CoreWeb.Router do
 | 
				
			||||||
    plug :fetch_flash
 | 
					    plug :fetch_flash
 | 
				
			||||||
    plug :protect_from_forgery
 | 
					    plug :protect_from_forgery
 | 
				
			||||||
    plug :put_secure_browser_headers
 | 
					    plug :put_secure_browser_headers
 | 
				
			||||||
    plug :put_layout, {CoreWeb.LayoutView, :app}
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pipeline :api do
 | 
					  pipeline :api do
 | 
				
			||||||
| 
						 | 
					@ -22,20 +21,4 @@ defmodule CoreWeb.Router do
 | 
				
			||||||
      live_dashboard "/dashboard", metrics: CoreWeb.Telemetry
 | 
					      live_dashboard "/dashboard", metrics: CoreWeb.Telemetry
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if Mix.env == :dev do
 | 
					 | 
				
			||||||
    # If using Phoenix
 | 
					 | 
				
			||||||
    forward "/sent_emails", Bamboo.SentEmailViewerPlug
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  scope "/", Content do
 | 
					 | 
				
			||||||
    pipe_through :browser
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    get "/", PostsController, :index
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Application.get_env(:core, :router_forwards, [])
 | 
					 | 
				
			||||||
  |> Enum.map(fn {router, path} ->
 | 
					 | 
				
			||||||
    forward path, router
 | 
					 | 
				
			||||||
  end)
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,10 +49,9 @@ defmodule CoreWeb.Helpers do
 | 
				
			||||||
  def styled_input(f, field, opts \\ [], options \\ nil, block_list \\ []) do
 | 
					  def styled_input(f, field, opts \\ [], options \\ nil, block_list \\ []) do
 | 
				
			||||||
    {content, _} = Keyword.pop(block_list, :do, "")
 | 
					    {content, _} = Keyword.pop(block_list, :do, "")
 | 
				
			||||||
    {type, rest_opts} = Keyword.pop(opts, :type, input_type(f, field))
 | 
					    {type, rest_opts} = Keyword.pop(opts, :type, input_type(f, field))
 | 
				
			||||||
    {icon, rest_opts} = Keyword.pop(rest_opts, :icon, "")
 | 
					 | 
				
			||||||
    {classes, rest_opts} = Keyword.pop(rest_opts, :class, default_classes_for_type(type))
 | 
					    {classes, rest_opts} = Keyword.pop(rest_opts, :class, default_classes_for_type(type))
 | 
				
			||||||
    {label_text, rest_opts} = Keyword.pop(rest_opts, :label)
 | 
					    {label_text, rest_opts} = Keyword.pop(rest_opts, :label)
 | 
				
			||||||
    {input_helper, rest_opts} = Keyword.pop(rest_opts, :input_helper, input_type(f, field))
 | 
					    {input_helper, _rest_opts} = Keyword.pop(rest_opts, :input_helper, input_type(f, field))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    error_classes =
 | 
					    error_classes =
 | 
				
			||||||
      if Keyword.get_values(f.errors, field) |> Enum.any?() do
 | 
					      if Keyword.get_values(f.errors, field) |> Enum.any?() do
 | 
				
			||||||
| 
						 | 
					@ -112,11 +111,11 @@ defmodule CoreWeb.Helpers do
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  defp do_styled_input_tag(type, input_helper, f, field, nil, opts, classes, error_classes) do
 | 
					  defp do_styled_input_tag(_type, input_helper, f, field, nil, opts, classes, error_classes) do
 | 
				
			||||||
    apply(Phoenix.HTML.Form, input_helper, [f, field, opts ++ [class: Enum.join([classes, error_classes], " ")]])
 | 
					    apply(Phoenix.HTML.Form, input_helper, [f, field, opts ++ [class: Enum.join([classes, error_classes], " ")]])
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  defp do_styled_input_tag(type, input_helper, f, field, options, opts, classes, error_classes) do
 | 
					  defp do_styled_input_tag(_type, input_helper, f, field, options, opts, classes, error_classes) do
 | 
				
			||||||
    apply(Phoenix.HTML.Form, input_helper, [f, field, options, opts ++ [class: Enum.join([classes, error_classes], " ")]])
 | 
					    apply(Phoenix.HTML.Form, input_helper, [f, field, options, opts ++ [class: Enum.join([classes, error_classes], " ")]])
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,39 +1,3 @@
 | 
				
			||||||
defmodule CoreWeb.LayoutView do
 | 
					defmodule CoreWeb.LayoutView do
 | 
				
			||||||
  use CoreWeb, :view
 | 
					  use CoreWeb, :view
 | 
				
			||||||
 | 
					 | 
				
			||||||
  def title(view_module, template, assigns) do
 | 
					 | 
				
			||||||
    delegate_with_default(view_module, :title, [view_module, template, assigns], I18n.t!("en", "site.title"))
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def excerpt(view_module, template, assigns) do
 | 
					 | 
				
			||||||
    delegate_with_default(view_module, :excerpt, [view_module, template, assigns], I18n.t!("en", "site.excerpt"))
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def feed_tag(conn, view_module, view_template, assigns) do
 | 
					 | 
				
			||||||
    delegate_with_default(view_module, :feed_tag, [conn, view_module, view_template, assigns], nil)
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  defp delegate_with_default(nil, _, _, default), do: default
 | 
					 | 
				
			||||||
  defp delegate_with_default(view_module, function_name, args, default) do
 | 
					 | 
				
			||||||
    sibling_layout = sibling_layout_view(view_module)
 | 
					 | 
				
			||||||
    if function_exported?(sibling_layout, function_name, args |> Enum.count()) do
 | 
					 | 
				
			||||||
      apply(sibling_layout, function_name, args)
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      default
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  defp sibling_layout_view(view_module) do
 | 
					 | 
				
			||||||
    view_module
 | 
					 | 
				
			||||||
    |> parent_module()
 | 
					 | 
				
			||||||
    |> Module.concat("LayoutView")
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  defp parent_module(mod) do
 | 
					 | 
				
			||||||
    [_|tail] = Module.split(mod) |> Enum.reverse()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    tail
 | 
					 | 
				
			||||||
    |> Enum.reverse()
 | 
					 | 
				
			||||||
    |> Module.concat()
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ defmodule Core.MixProject do
 | 
				
			||||||
      {:phoenix, "~> 1.5.3"},
 | 
					      {:phoenix, "~> 1.5.3"},
 | 
				
			||||||
      {:phoenix_ecto, "~> 4.1"},
 | 
					      {:phoenix_ecto, "~> 4.1"},
 | 
				
			||||||
      {:ecto_sql, "~> 3.4"},
 | 
					      {:ecto_sql, "~> 3.4"},
 | 
				
			||||||
      {:linguist, "0.3.0"},
 | 
					      {:linguist, "0.3.1"},
 | 
				
			||||||
      {:postgrex, ">= 0.0.0"},
 | 
					      {:postgrex, ">= 0.0.0"},
 | 
				
			||||||
      {:phoenix_html, "~> 2.11"},
 | 
					      {:phoenix_html, "~> 2.11"},
 | 
				
			||||||
      {:phoenix_live_reload, "~> 1.2", only: :dev},
 | 
					      {:phoenix_live_reload, "~> 1.2", only: :dev},
 | 
				
			||||||
| 
						 | 
					@ -73,7 +73,7 @@ defmodule Core.MixProject do
 | 
				
			||||||
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
 | 
					      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
 | 
				
			||||||
      "ecto.reset": ["ecto.drop", "ecto.setup"],
 | 
					      "ecto.reset": ["ecto.drop", "ecto.setup"],
 | 
				
			||||||
      test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
 | 
					      test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
 | 
				
			||||||
      "npm.install": ["cmd npm install --prefix assets"],
 | 
					      "npm.install": [],
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,31 +1,3 @@
 | 
				
			||||||
defmodule CoreWeb.LayoutViewTest do
 | 
					defmodule CoreWeb.LayoutViewTest do
 | 
				
			||||||
  use CoreWeb.ConnCase, async: true
 | 
					  use CoreWeb.ConnCase, async: true
 | 
				
			||||||
 | 
					 | 
				
			||||||
  import CoreWeb.LayoutView
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "title/3" do
 | 
					 | 
				
			||||||
    def default_title do
 | 
					 | 
				
			||||||
      I18n.t! "en", "site.title"
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test "for nil" do
 | 
					 | 
				
			||||||
      assert title(nil, nil, nil) =~ default_title()
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "excerpt/3" do
 | 
					 | 
				
			||||||
    def default_excerpt do
 | 
					 | 
				
			||||||
      I18n.t! "en", "site.excerpt"
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    test "for nil" do
 | 
					 | 
				
			||||||
      assert excerpt(nil, nil, nil) =~ default_excerpt()
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  describe "feed_tag/4" do
 | 
					 | 
				
			||||||
    test "for nil" do
 | 
					 | 
				
			||||||
      assert feed_tag(nil, nil, nil, nil) == nil
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ config :app, AppWeb.Endpoint,
 | 
				
			||||||
  url: [host: "localhost"],
 | 
					  url: [host: "localhost"],
 | 
				
			||||||
  secret_key_base: "r2eN53mJ9RmlGz9ZQ7xf43P3Or59aaO9rdf5D3hRcsuiH44pGW9kPGfl5mt9N1Gi",
 | 
					  secret_key_base: "r2eN53mJ9RmlGz9ZQ7xf43P3Or59aaO9rdf5D3hRcsuiH44pGW9kPGfl5mt9N1Gi",
 | 
				
			||||||
  render_errors: [view: AppWeb.ErrorView, accepts: ~w(html json), layout: false],
 | 
					  render_errors: [view: AppWeb.ErrorView, accepts: ~w(html json), layout: false],
 | 
				
			||||||
  pubsub_server: AppWeb.PubSub,
 | 
					  pubsub_server: App.PubSub,
 | 
				
			||||||
  live_view: [signing_salt: "g5ltUbnQ"]
 | 
					  live_view: [signing_salt: "g5ltUbnQ"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Configure Mix tasks and generators
 | 
					# Configure Mix tasks and generators
 | 
				
			||||||
| 
						 | 
					@ -67,14 +67,7 @@ config :content, Content.Endpoint,
 | 
				
			||||||
config :admin,
 | 
					config :admin,
 | 
				
			||||||
  ecto_repos: [Admin.Repo]
 | 
					  ecto_repos: [Admin.Repo]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config :core,
 | 
					config :core, email_from: "example@example.org"
 | 
				
			||||||
  router_forwards: [
 | 
					 | 
				
			||||||
    {Content.Router, "/pages"},
 | 
					 | 
				
			||||||
    {AuthWeb.Router, "/auth"},
 | 
					 | 
				
			||||||
    {Admin.Router, "/admin"},
 | 
					 | 
				
			||||||
    {AppWeb.Router, "/app"},
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  email_from: "example@example.org"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
config :content,
 | 
					config :content,
 | 
				
			||||||
  generators: [context_app: false]
 | 
					  generators: [context_app: false]
 | 
				
			||||||
| 
						 | 
					@ -82,7 +75,7 @@ config :content,
 | 
				
			||||||
config :content, Content.Endpoint, server: false
 | 
					config :content, Content.Endpoint, server: false
 | 
				
			||||||
config :auth_web, AuthWeb.Endpoint, server: false
 | 
					config :auth_web, AuthWeb.Endpoint, server: false
 | 
				
			||||||
config :admin, Admin.Endpoint, server: false
 | 
					config :admin, Admin.Endpoint, server: false
 | 
				
			||||||
config :app, AppWeb.Endpoint, server: false
 | 
					config :app, CoreWeb.Endpoint, server: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import_config "../apps/*/config/config.exs"
 | 
					import_config "../apps/*/config/config.exs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ use Mix.Config
 | 
				
			||||||
# The watchers configuration can be used to run external
 | 
					# The watchers configuration can be used to run external
 | 
				
			||||||
# watchers to your application. For example, we use it
 | 
					# watchers to your application. For example, we use it
 | 
				
			||||||
# with webpack to recompile .js and .css sources.
 | 
					# with webpack to recompile .js and .css sources.
 | 
				
			||||||
config :app, App.Endpoint,
 | 
					config :app, AppWeb.Endpoint,
 | 
				
			||||||
  http: [port: 4000],
 | 
					  http: [port: 4000],
 | 
				
			||||||
  debug_errors: true,
 | 
					  debug_errors: true,
 | 
				
			||||||
  code_reloader: true,
 | 
					  code_reloader: true,
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ config :app, App.Endpoint,
 | 
				
			||||||
# different ports.
 | 
					# different ports.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Watch static and templates for browser reloading.
 | 
					# Watch static and templates for browser reloading.
 | 
				
			||||||
config :app, App.Endpoint,
 | 
					config :app, AppWeb.Endpoint,
 | 
				
			||||||
  live_reload: [
 | 
					  live_reload: [
 | 
				
			||||||
    patterns: [
 | 
					    patterns: [
 | 
				
			||||||
      ~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
 | 
					      ~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								mix.lock
									
									
									
									
									
								
							
							
						
						| 
						 | 
					@ -3,7 +3,7 @@
 | 
				
			||||||
  "bcrypt_elixir": {:hex, :bcrypt_elixir, "1.1.1", "6b5560e47a02196ce5f0ab3f1d8265db79a23868c137e973b27afef928ed8006", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "10f658be786bd2daaadcd45cc5b598da01d5bbc313da4d0e3efb2d6a511d896d"},
 | 
					  "bcrypt_elixir": {:hex, :bcrypt_elixir, "1.1.1", "6b5560e47a02196ce5f0ab3f1d8265db79a23868c137e973b27afef928ed8006", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "10f658be786bd2daaadcd45cc5b598da01d5bbc313da4d0e3efb2d6a511d896d"},
 | 
				
			||||||
  "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
 | 
					  "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
 | 
				
			||||||
  "certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
 | 
					  "certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
 | 
				
			||||||
  "cldr_utils": {:hex, :cldr_utils, "2.9.1", "be714403abe1a7abed5ee4f7dd3823a9067f96ab4b0613a454177b51ca204236", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "6cba0a485f57feb773291ca1816469ddd887e22d73d9b12a1b207d82a67a4e71"},
 | 
					  "cldr_utils": {:hex, :cldr_utils, "2.11.0", "1822c5b246639aa106bb8aea674de183efe132f1bda23aa224000bfe6ee8e08d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "79451992a1617f0b9c06c7ae1dd5ffcf3e6ae6a616bb14dea86f7ee142db71d0"},
 | 
				
			||||||
  "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
 | 
					  "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
 | 
				
			||||||
  "comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm", "d8700a0ca4dbb616c22c9b3f6dd539d88deaafec3efe66869d6370c9a559b3e9"},
 | 
					  "comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm", "d8700a0ca4dbb616c22c9b3f6dd539d88deaafec3efe66869d6370c9a559b3e9"},
 | 
				
			||||||
  "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
 | 
					  "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
 | 
				
			||||||
| 
						 | 
					@ -13,10 +13,12 @@
 | 
				
			||||||
  "crontab": {:hex, :crontab, "1.1.10", "dc9bb1f4299138d47bce38341f5dcbee0aa6c205e864fba7bc847f3b5cb48241", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1347d889d1a0eda997990876b4894359e34bfbbd688acbb0ba28a2795ca40685"},
 | 
					  "crontab": {:hex, :crontab, "1.1.10", "dc9bb1f4299138d47bce38341f5dcbee0aa6c205e864fba7bc847f3b5cb48241", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1347d889d1a0eda997990876b4894359e34bfbbd688acbb0ba28a2795ca40685"},
 | 
				
			||||||
  "db_connection": {:hex, :db_connection, "2.2.2", "3bbca41b199e1598245b716248964926303b5d4609ff065125ce98bcd368939e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "642af240d8a8affb93b4ba5a6fcd2bbcbdc327e1a524b825d383711536f8070c"},
 | 
					  "db_connection": {:hex, :db_connection, "2.2.2", "3bbca41b199e1598245b716248964926303b5d4609ff065125ce98bcd368939e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "642af240d8a8affb93b4ba5a6fcd2bbcbdc327e1a524b825d383711536f8070c"},
 | 
				
			||||||
  "decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"},
 | 
					  "decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"},
 | 
				
			||||||
 | 
					  "dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
 | 
				
			||||||
  "earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
 | 
					  "earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
 | 
				
			||||||
  "ecto": {:hex, :ecto, "3.4.6", "08f7afad3257d6eb8613309af31037e16c36808dfda5a3cd0cb4e9738db030e4", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6f13a9e2a62e75c2dcfc7207bfc65645ab387af8360db4c89fee8b5a4bf3f70b"},
 | 
					  "ecto": {:hex, :ecto, "3.4.6", "08f7afad3257d6eb8613309af31037e16c36808dfda5a3cd0cb4e9738db030e4", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6f13a9e2a62e75c2dcfc7207bfc65645ab387af8360db4c89fee8b5a4bf3f70b"},
 | 
				
			||||||
  "ecto_sql": {:hex, :ecto_sql, "3.4.4", "d28bac2d420f708993baed522054870086fd45016a9d09bb2cd521b9c48d32ea", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.0", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "edb49af715dd72f213b66adfd0f668a43c17ed510b5d9ac7528569b23af57fe8"},
 | 
					  "ecto_sql": {:hex, :ecto_sql, "3.4.4", "d28bac2d420f708993baed522054870086fd45016a9d09bb2cd521b9c48d32ea", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.0", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "edb49af715dd72f213b66adfd0f668a43c17ed510b5d9ac7528569b23af57fe8"},
 | 
				
			||||||
  "elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"},
 | 
					  "elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"},
 | 
				
			||||||
 | 
					  "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
 | 
				
			||||||
  "ex_cldr": {:hex, :ex_cldr, "2.13.0", "742f14a4afcfea61a190d603d8e555d2c91d71e4e8fc2520d5dc35616969e225", [:mix], [{:cldr_utils, "~> 2.3", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "5e4cf3e945ee60156a3342e2a762f69036ffbe1f80520cc88592d68f12c5db55"},
 | 
					  "ex_cldr": {:hex, :ex_cldr, "2.13.0", "742f14a4afcfea61a190d603d8e555d2c91d71e4e8fc2520d5dc35616969e225", [:mix], [{:cldr_utils, "~> 2.3", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "5e4cf3e945ee60156a3342e2a762f69036ffbe1f80520cc88592d68f12c5db55"},
 | 
				
			||||||
  "ex_prompt": {:hex, :ex_prompt, "0.1.5", "b136642d0962f8ea37b3c9fa185ad1f42c71c3b9c6c3950f0358d7f3d2db2970", [:mix], [], "hexpm", "ad19a404708c9c7b05d36090b2d074ceafbed248a8de1a22d45a05ebe6994b83"},
 | 
					  "ex_prompt": {:hex, :ex_prompt, "0.1.5", "b136642d0962f8ea37b3c9fa185ad1f42c71c3b9c6c3950f0358d7f3d2db2970", [:mix], [], "hexpm", "ad19a404708c9c7b05d36090b2d074ceafbed248a8de1a22d45a05ebe6994b83"},
 | 
				
			||||||
  "excoveralls": {:hex, :excoveralls, "0.13.0", "4e1b7cc4e0351d8d16e9be21b0345a7e165798ee5319c7800b9138ce17e0b38e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "fe2a56c8909564e2e6764765878d7d5e141f2af3bc8ff3b018a68ee2a218fced"},
 | 
					  "excoveralls": {:hex, :excoveralls, "0.13.0", "4e1b7cc4e0351d8d16e9be21b0345a7e165798ee5319c7800b9138ce17e0b38e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "fe2a56c8909564e2e6764765878d7d5e141f2af3bc8ff3b018a68ee2a218fced"},
 | 
				
			||||||
| 
						 | 
					@ -24,7 +26,7 @@
 | 
				
			||||||
  "floki": {:hex, :floki, "0.25.0", "b1c9ddf5f32a3a90b43b76f3386ca054325dc2478af020e87b5111c19f2284ac", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "631f4e627c46d5ecd347df5a2accdaf0621c77c3693c5b75a8ad58e84c61f242"},
 | 
					  "floki": {:hex, :floki, "0.25.0", "b1c9ddf5f32a3a90b43b76f3386ca054325dc2478af020e87b5111c19f2284ac", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "631f4e627c46d5ecd347df5a2accdaf0621c77c3693c5b75a8ad58e84c61f242"},
 | 
				
			||||||
  "gen_stage": {:hex, :gen_stage, "1.0.0", "51c8ae56ff54f9a2a604ca583798c210ad245f415115453b773b621c49776df5", [:mix], [], "hexpm", "1d9fc978db5305ac54e6f5fec7adf80cd893b1000cf78271564c516aa2af7706"},
 | 
					  "gen_stage": {:hex, :gen_stage, "1.0.0", "51c8ae56ff54f9a2a604ca583798c210ad245f415115453b773b621c49776df5", [:mix], [], "hexpm", "1d9fc978db5305ac54e6f5fec7adf80cd893b1000cf78271564c516aa2af7706"},
 | 
				
			||||||
  "gen_state_machine": {:hex, :gen_state_machine, "2.1.0", "a38b0e53fad812d29ec149f0d354da5d1bc0d7222c3711f3a0bd5aa608b42992", [:mix], [], "hexpm", "ae367038808db25cee2f2c4b8d0531522ea587c4995eb6f96ee73410a60fa06b"},
 | 
					  "gen_state_machine": {:hex, :gen_state_machine, "2.1.0", "a38b0e53fad812d29ec149f0d354da5d1bc0d7222c3711f3a0bd5aa608b42992", [:mix], [], "hexpm", "ae367038808db25cee2f2c4b8d0531522ea587c4995eb6f96ee73410a60fa06b"},
 | 
				
			||||||
  "gettext": {:hex, :gettext, "0.18.0", "406d6b9e0e3278162c2ae1de0a60270452c553536772167e2d701f028116f870", [:mix], [], "hexpm", "c3f850be6367ebe1a08616c2158affe4a23231c70391050bf359d5f92f66a571"},
 | 
					  "gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
 | 
				
			||||||
  "hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
 | 
					  "hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
 | 
				
			||||||
  "html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"},
 | 
					  "html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"},
 | 
				
			||||||
  "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "c334e2835e094fb9c04658bd4cfc7533fa51a8f56f11343c57ab9cb2a01d8613"},
 | 
					  "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "c334e2835e094fb9c04658bd4cfc7533fa51a8f56f11343c57ab9cb2a01d8613"},
 | 
				
			||||||
| 
						 | 
					@ -32,7 +34,7 @@
 | 
				
			||||||
  "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
 | 
					  "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
 | 
				
			||||||
  "kaffy": {:hex, :kaffy, "0.9.0", "bef34c9729f6a3af4d0dea8eede8bcb9e11371a83ac9a8b393991bce81839517", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.11", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "d18ff57b8e68feb433aed11e71510cd357abc7034e75358af5deff7d0d4c6ed3"},
 | 
					  "kaffy": {:hex, :kaffy, "0.9.0", "bef34c9729f6a3af4d0dea8eede8bcb9e11371a83ac9a8b393991bce81839517", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.11", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "d18ff57b8e68feb433aed11e71510cd357abc7034e75358af5deff7d0d4c6ed3"},
 | 
				
			||||||
  "libring": {:hex, :libring, "1.5.0", "44313eb6862f5c9168594a061e9d5f556a9819da7c6444706a9e2da533396d70", [:mix], [], "hexpm", "04e843d4fdcff49a62d8e03778d17c6cb2a03fe2d14020d3825a1761b55bd6cc"},
 | 
					  "libring": {:hex, :libring, "1.5.0", "44313eb6862f5c9168594a061e9d5f556a9819da7c6444706a9e2da533396d70", [:mix], [], "hexpm", "04e843d4fdcff49a62d8e03778d17c6cb2a03fe2d14020d3825a1761b55bd6cc"},
 | 
				
			||||||
  "linguist": {:hex, :linguist, "0.3.0", "2984dfce6720d1212ddd7bba82496f92627a39aecd4d32c7016ec00393e1f925", [:mix], [{:ex_cldr, "~> 2.0", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "1923876545db22b63334c9d203ef56397a2946daa018117767b068f856be41e4"},
 | 
					  "linguist": {:hex, :linguist, "0.3.1", "8ce81114691be8ef4a122e7f57bd1842bc96b1f5650b66b246d7035238cab69d", [:mix], [{:ex_cldr, "~> 2.0", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "5b06f97912e298f60dd00bc6a588b1fe1ec8838b268e4fdbf4443a25511f0614"},
 | 
				
			||||||
  "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
 | 
					  "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
 | 
				
			||||||
  "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
 | 
					  "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
 | 
				
			||||||
  "mime": {:hex, :mime, "1.4.0", "5066f14944b470286146047d2f73518cf5cca82f8e4815cf35d196b58cf07c47", [:mix], [], "hexpm", "75fa42c4228ea9a23f70f123c74ba7cece6a03b1fd474fe13f6a7a85c6ea4ff6"},
 | 
					  "mime": {:hex, :mime, "1.4.0", "5066f14944b470286146047d2f73518cf5cca82f8e4815cf35d196b58cf07c47", [:mix], [], "hexpm", "75fa42c4228ea9a23f70f123c74ba7cece6a03b1fd474fe13f6a7a85c6ea4ff6"},
 | 
				
			||||||
| 
						 | 
					@ -69,5 +71,5 @@
 | 
				
			||||||
  "unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"},
 | 
					  "unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"},
 | 
				
			||||||
  "xml_builder": {:hex, :xml_builder, "2.1.2", "90cb9ad382958934c78c6ddfbe6d385a8ce147d84b61cbfa83ec93a169d0feab", [:mix], [], "hexpm", "b89046041da2fbc1d51d31493ba31b9d5fc6223c93384bf513a1a9e1df9ec081"},
 | 
					  "xml_builder": {:hex, :xml_builder, "2.1.2", "90cb9ad382958934c78c6ddfbe6d385a8ce147d84b61cbfa83ec93a169d0feab", [:mix], [], "hexpm", "b89046041da2fbc1d51d31493ba31b9d5fc6223c93384bf513a1a9e1df9ec081"},
 | 
				
			||||||
  "yamerl": {:hex, :yamerl, "0.8.0", "8214cfe16bbabe5d1d6c14a14aea11c784b9a21903dd6a7c74f8ce180adae5c7", [:rebar3], [], "hexpm", "010634477bf9c208a0767dcca89116c2442cf0b5e87f9c870f85cd1c3e0c2aab"},
 | 
					  "yamerl": {:hex, :yamerl, "0.8.0", "8214cfe16bbabe5d1d6c14a14aea11c784b9a21903dd6a7c74f8ce180adae5c7", [:rebar3], [], "hexpm", "010634477bf9c208a0767dcca89116c2442cf0b5e87f9c870f85cd1c3e0c2aab"},
 | 
				
			||||||
  "yaml_elixir": {:hex, :yaml_elixir, "2.4.0", "2f444abc3c994c902851fde56b6a9cb82895c291c05a0490a289035c2e62ae71", [:mix], [{:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "4e25a6d5c873e393689c6f1062c5ec90f6cd1be2527b073178ae37eae4c78bee"},
 | 
					  "yaml_elixir": {:hex, :yaml_elixir, "2.5.0", "45de762be6d75fa5a8b5f44ddff8c30f64c26526eab5b1d72e36d616007b7796", [:mix], [{:yamerl, "~> 0.7", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "80fe4e43f05582f2a90f2dcd73fc6171fbd65f2e6836f71fe4ce2154ef358c36"},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||