gulp and a lot of others updates

This commit is contained in:
root 2020-07-23 10:43:20 +00:00
parent 4a97c240eb
commit 2e6e64a6d3
57 changed files with 6411 additions and 2629 deletions

View file

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 101 KiB

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View file

Before

Width:  |  Height:  |  Size: 344 KiB

After

Width:  |  Height:  |  Size: 344 KiB

View file

Before

Width:  |  Height:  |  Size: 296 KiB

After

Width:  |  Height:  |  Size: 296 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View file

@ -1,37 +1,37 @@
let navOpened = false let navOpened = false;
let oldNavText = "" let oldNavText = "";
let oldNavIcon = "" let oldNavIcon = "";
let navEnabler = document.getElementById('nav-enabler') let navEnabler = document.getElementById('nav-enabler');
let navEnablerText = document.getElementById('nav-enabler-text') let navEnablerText = document.getElementById('nav-enabler-text');
let navEnablerIcon = document.getElementById('nav-enabler-icon') let navEnablerIcon = document.getElementById('nav-enabler-icon');
let navContent = document.getElementById('nav-content') let navContent = document.getElementById('nav-content');
let mosaic = document.getElementById('mosaic') let mosaic = document.getElementById('mosaic');
let mosaicHeader = document.getElementById('mosaic-header') let mosaicHeader = document.getElementById('mosaic-header');
navEnabler.onclick = async () => { navEnabler.onclick = async () => {
if (!navOpened) { if (!navOpened) {
// open the menu // open the menu
oldNavText = navEnablerText.textContent oldNavText = navEnablerText.textContent;
navEnablerText.textContent = "Minimiser le menu" navEnablerText.textContent = "Minimiser le menu";
navEnablerIcon.style.transform = "rotate(90eg)" navEnablerIcon.style.transform = "rotate(90eg)";
navContent.style.maxHeight = navContent.scrollHeight + "px" navContent.style.maxHeight = navContent.scrollHeight + "px";
} else { } else {
// close the menu // close the menu
navEnablerText.textContent = oldNavText navEnablerText.textContent = oldNavText;
navEnablerIcon.style.transform = "rotate(0deg)" navEnablerIcon.style.transform = "rotate(0deg)";
navContent.style.maxHeight = null navContent.style.maxHeight = null;
} }
navOpened = !navOpened navOpened = !navOpened;
} }
function createEl(className = false, elName = "div") { function createEl(className = false, elName = "div") {
let el = document.createElement(elName) let el = document.createElement(elName);
if (className != false) { if (className != false) {
el.className = className el.className = className;
} }
return el return el;
} }
function renderNavItem(tag) { function renderNavItem(tag) {
@ -51,26 +51,26 @@ function renderNavItem(tag) {
</div> </div>
*/ */
let navItem = createEl('nav-item') let navItem = createEl('nav-item');
let navIcon = createEl('nav-icon') let navIcon = createEl('nav-icon');
let icon = createEl(tag.icon, 'i') let icon = createEl(tag.icon, 'i');
navIcon.appendChild(icon) navIcon.appendChild(icon);
navItem.appendChild(navIcon) navItem.appendChild(navIcon);
let navItemContent = createEl('nav-item-content') let navItemContent = createEl('nav-item-content');
let navTitle = createEl('nav-title') let navTitle = createEl('nav-title');
navTitle.textContent = tag.name navTitle.textContent = tag.name;
navItemContent.appendChild(navTitle) navItemContent.appendChild(navTitle);
let navAccess = createEl('nav-access') let navAccess = createEl('nav-access');
let chevronIcon = createEl('fas fa-chevron-right', 'i') let chevronIcon = createEl('fas fa-chevron-right', 'i');
navAccess.appendChild(chevronIcon) navAccess.appendChild(chevronIcon);
navItemContent.appendChild(navTitle) navItemContent.appendChild(navTitle);
navItemContent.appendChild(navAccess) navItemContent.appendChild(navAccess);
navItem.appendChild(navItemContent) navItem.appendChild(navItemContent);
return navItem return navItem;
} }
function setAttributes(node, attrs) { function setAttributes(node, attrs) {

View file

@ -180,14 +180,13 @@
border-radius: 4px; border-radius: 4px;
margin-bottom: 1em; margin-bottom: 1em;
box-shadow: 0 0 8px 0px rgba(0,0,0,0.1); box-shadow: 0 0 8px 0px rgba(0,0,0,0.1);
transition: all 0.2s;
overflow: hidden; overflow: hidden;
text-decoration: none; text-decoration: none;
transition: transform 0.2s ease-in-out;
} }
.card:hover { .card:hover {
text-decoration: none; text-decoration: none;
transform: scale(1.02);
} }
.card-image-container { .card-image-container {
@ -206,8 +205,17 @@
background-position: center; background-position: center;
background-size: cover; background-size: cover;
transition: all 0.2s ease-in-out;
border: 0;
outline: 0;
box-shadow: 0;
} }
.card-image:hover {
transform: scale(1.1);
}
.card-content { .card-content {
width: 100%; width: 100%;
padding: 1.5em; padding: 1.5em;
@ -235,7 +243,6 @@
} }
.card-title { .card-title {
font-size: 1.6em;
color: #B12008; color: #B12008;
margin: 0; margin: 0;
margin-bottom: 0.5em; margin-bottom: 0.5em;

View file

@ -59,6 +59,7 @@ body {
border-radius: 7px; border-radius: 7px;
background: #2c3e50; background: #2c3e50;
border: 0; border: 0;
cursor: pointer;
} }
.btn:focus { .btn:focus {

View file

@ -194,7 +194,7 @@
} */ } */
.media { .media {
cursor: pointer; cursor: zoom-in;
height: 100%; height: 100%;
border-radius: 4px; border-radius: 4px;
background-size: cover; background-size: cover;
@ -561,6 +561,62 @@ section {
width: .75em; width: .75em;
} }
/**
People cards
***/
.peoples {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 1em;
}
.people-card {
width: 100%;
margin-right: 1em;
border-radius: 3px;
padding: 1.2em 1.5em;
border: 1px solid gray;
}
.people-card:last-of-type {
margin-right: 0;
}
.people-header {
}
.people-name {
font-size: 1.4em;
margin-bottom: .5em;
}
.people-contacts {
margin-top: .5em;
}
.people-contact {
padding-top: .5em;
padding-bottom: .5em;
display: flex;
align-items: center;
}
.people-name {
}
.people-role {
opacity: .8;
}
.people-contact-icon {
width: 1em;
height: 1em;
margin-right: 1em;
color: #B15808;
}
/* ***************************************************************************** /* *****************************************************************************
* FOOTER * FOOTER
@ -741,6 +797,29 @@ RESPONSIVE
.facebook .contact-content, .twitter .contact-content, .website .contact-content, .instagram .contact-content { .facebook .contact-content, .twitter .contact-content, .website .contact-content, .instagram .contact-content {
font-size: .8em; font-size: .8em;
} }
.peoples {
display: flex;
flex-direction: column;
}
.people-card {
width: auto;
text-align: center;
margin-bottom: 1em;
margin-right: 0;
}
.people-contacts {
display: flex;
flex-direction: column;
align-items: center;
}
.people-card:last-of-type {
margin-bottom: 0;
}
} }
@media (max-width: 600px) { @media (max-width: 600px) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View file

@ -0,0 +1 @@
let navOpened=!1,oldNavText="",oldNavIcon="",navEnabler=document.getElementById("nav-enabler"),navEnablerText=document.getElementById("nav-enabler-text"),navEnablerIcon=document.getElementById("nav-enabler-icon"),navContent=document.getElementById("nav-content"),mosaic=document.getElementById("mosaic"),mosaicHeader=document.getElementById("mosaic-header");function createEl(e=!1,t="div"){let n=document.createElement(t);return 0!=e&&(n.className=e),n}function renderNavItem(e){let t=createEl("nav-item"),n=createEl("nav-icon"),a=createEl(e.icon,"i");n.appendChild(a),t.appendChild(n);let r=createEl("nav-item-content"),l=createEl("nav-title");l.textContent=e.name,r.appendChild(l);let i=createEl("nav-access"),c=createEl("fas fa-chevron-right","i");return i.appendChild(c),r.appendChild(l),r.appendChild(i),t.appendChild(r),t}function setAttributes(e,t){for(var n in t)attr=document.createAttribute(n),attr.value=t[n],e.attributes.setNamedItem(attr)}function renderCard(e){let t=createEl("card","a"),n=createEl("card-image-container"),a=createEl("card-image");a.style=`background-image: url('${e.thumbnail}')`,n.appendChild(a),t.appendChild(n);let r=createEl("card-content"),l=createEl(),i=createEl("card-title-container"),c=createEl("card-title","h2");c.textContent=e.name,i.appendChild(c);let d=createEl("card-icon");if(Array.isArray(e.tags)&&e.tags.length>0){let t=tags.filter(t=>e.tags[0]===t._id)[0];d.innerHTML=`<svg\n aria-hidden="true"\n focusable="false"\n role="img"\n xmlns="http://www.w3.org/2000/svg"\n viewBox="0 0 ${t.icon.width} ${t.icon.height}">\n <path fill="currentColor" d="${t.icon.path}"></path>\n </svg>`}i.appendChild(d),l.appendChild(i);let o=createEl("card-description");o.textContent=e.description;let s="/association/"+e.slugs[e.slugs.length-1];return e.isProposed&&(s+="?version=proposed"),l.appendChild(o),r.appendChild(l),t.appendChild(r),t.href=s,t}function renderMosaic(e){let t=createEl("card-container");return e.forEach(e=>{t.appendChild(renderCard(e))}),t}navEnabler.onclick=async()=>{navOpened?(navEnablerText.textContent=oldNavText,navEnablerIcon.style.transform="rotate(0deg)",navContent.style.maxHeight=null):(oldNavText=navEnablerText.textContent,navEnablerText.textContent="Minimiser le menu",navEnablerIcon.style.transform="rotate(90eg)",navContent.style.maxHeight=navContent.scrollHeight+"px"),navOpened=!navOpened};let currentTag=null,currentCardContainer=null;function enableTag(e){let t="nav-all"===e.id,n="";t||(n=e.attributes["data-tag-id"].value);let a=organizations.filter(e=>e.tags.filter(e=>e===n).length>0||t),r=renderMosaic(a);null!==currentCardContainer&&mosaic.removeChild(currentCardContainer),currentCardContainer=r,mosaic.appendChild(r),e.className+=" enabled",null!==currentTag&&(currentTag.className=currentTag.className.replace("enabled","")),currentTag=e,null==a||a.length<=0?mosaicHeader.textContent="Aucune associations listées":1===a.length?mosaicHeader.textContent="Une association listée":mosaicHeader.textContent=a.length+" associations listées"}navContent.childNodes.forEach(e=>{e.onclick=()=>enableTag(e)}),enableTag(document.getElementById("nav-all"));

View file

@ -0,0 +1,124 @@
/**
* Schedule collapsable section animation
*/
document.querySelectorAll('.schedule-category').forEach(node => {
let opened = false
let icon = node.querySelector('.schedule-category-collapse-icon')
let content = node.querySelector('.schedule-category-table')
let header = node.querySelector('.schedule-category-header')
header.onclick = () => {
if (!opened) {
// open the table
icon.style.transform = "rotate(0deg)"
content.style.maxHeight = content.scrollHeight + "px"
} else {
// close the table
icon.style.transform = "rotate(180deg)"
content.style.maxHeight = null
}
opened = !opened
}
})
/**
* Description
*/
let description = document.querySelector('.description-cutted')
let descriptionActions = document.querySelector('.description-actions-container')
let descriptionOpened = false
let defaultMaxHeight = ""
if (description !== null) {
let btn = document.querySelector('.description-btn')
btn.onclick = () => {
if (!descriptionOpened) {
// open the full description
descriptionActions.className = descriptionActions.className.replace(' closed', '')
defaultMaxHeight = description.style.maxHeight
description.style.maxHeight = description.scrollHeight + "px"
btn.textContent = "Fermer la description"
} else {
// initial max Height
descriptionActions.className += ' closed'
description.style.maxHeight = defaultMaxHeight
btn.textContent = "Ouvrir la description"
}
descriptionOpened = !descriptionOpened
}
}
/**
* Gallery modal to view media in large
*/
let mediaModal = document.querySelector('#media-modal')
let mediaModalContent = document.querySelector('#media-modal-content')
// let mediaModalImage = document.querySelector('#media-modal img')
// let mediaModalVideo = document.querySelector('#media-modal video')
// let mediaModalSource = document.querySelector('#media-modal video source')
// function disableScroll() {
// // Get the current page scroll position
// scrollTop = window.pageYOffset || document.documentElement.scrollTop;
// scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
// // if any scroll is attempted, set this to the previous value
// window.onscroll = function() {
// window.scrollTo(scrollLeft, scrollTop);
// };
// }
// function enableScroll() {
// window.onscroll = function() {};
// }
let openModal = (url, isVideo) => {
mediaModal.style.visibility = 'visible'
mediaModal.style.opacity = 1
mediaModalContent.innerHTML = ""
let attr = document.createAttribute('src')
attr.value = url
let el = null
if (isVideo) {
el = document.createElement('video')
el.setAttribute('controls', '')
el.setAttribute('autoplay', '')
el.setAttribute('name', 'media')
let source = document.createElement('source')
source.setAttribute('src', url)
source.setAttribute('type', 'video/mp4')
el.appendChild(source)
} else {
el = document.createElement('img')
el.attributes.setNamedItem(attr)
}
mediaModalContent.appendChild(el)
//document.body.style.height = '100vh'
document.body.style.overflow = 'hidden'
document.body.style.touchAction = 'none'
setTimeout(() => {
const outsideClickListener = event => {
if (!mediaModalContent.contains(event.target) && isVisible(mediaModalContent)) {
closeModal()
document.removeEventListener('click', outsideClickListener)
}
}
document.addEventListener('click', outsideClickListener)
}, 100)
}
const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length )
let closeModal = () => {
mediaModal.style.visibility = 'hidden'
mediaModal.style.opacity = 0
document.body.style.overflow = 'initial'
document.body.style.height = 'initial'
let video = document.querySelector('#media-modal video')
if (video !== null) {
video.pause()
}
}

View file

@ -0,0 +1 @@
.error-container{width:100%;margin-top:4em}.error{width:60%;margin:0 auto;text-align:center;color:#2c3e50}.error-title{font-family:'Roboto Slab',serif}.error-icons{font-size:5em;margin-bottom:.25em}.expert{text-align:left;padding:1em;background-color:#000;color:rgba(0,255,0);border:2px solid gray;border-radius:3px}@media (max-width:1350px){.error{width:100%}}

View file

@ -0,0 +1 @@
.header{padding-bottom:1.5em;padding-top:1.5em;background-color:#d35400}.header-container{position:relative;display:flex;justify-content:space-between}.header-left{display:flex}.header-menu{position:absolute;right:0;bottom:0;display:flex;align-items:flex-end}.header-menu a{color:#fff;margin-right:1em}.header-menu a:last-of-type{margin-right:0}.header-image{margin-right:3em}.header-image img{width:7em}.header-content{display:flex;flex-direction:column;justify-content:space-between;padding-top:1em;padding-bottom:1em}.header-title{font-family:'Roboto Slab',serif;margin:0;color:#fff;font-weight:500;font-size:2.5em}.header-sub-title{margin:0;text-decoration:underline;font-weight:100;color:#ecf0f1;transition:opacity .2s}.header-sub-title:hover{opacity:.9;color:#ecf0f1}.header-description{color:#ecf0f1}.content{margin-top:1.5em;display:flex}.nav{margin-right:2em}.nav-item{width:15em;padding:1em;border-radius:4px;margin-bottom:.7em;border:3px solid rgba(255,111,10,.7);display:flex;cursor:pointer;transition:ease-in-out .1s;height:1.2em}.nav-item svg{width:.75em;height:.75em}.nav-icon{width:3em;padding-left:.5em;display:flex;justify-content:start;align-items:center;color:#c28200;font-size:1.5em;opacity:.7}.nav-item-content{display:flex;justify-content:space-between;width:100%}.nav-title{display:flex;align-items:center;opacity:.7}.nav-access{display:flex;align-items:center;color:#ff6f0a;opacity:.7}.nav-item.enabled{border-color:#ff6f0a}.nav-item.enabled .nav-access{opacity:1}.nav-item.enabled .nav-icon{opacity:1}.nav-item.enabled .nav-title{opacity:1}.nav-item:hover{transform:scale(1.05)}#nav-enabler{display:none}.mosaic{background:#fff;width:100%}.mosaic-header{width:100%;opacity:.8;text-align:right;margin-bottom:1.5em}.card-container{margin:0 auto;width:85%}.card{cursor:pointer;display:flex;border:1px solid #bdc3c7;border-radius:4px;margin-bottom:1em;box-shadow:0 0 8px 0 rgba(0,0,0,.1);overflow:hidden;text-decoration:none;transition:transform .2s ease-in-out}.card:hover{text-decoration:none}.card-image-container{border-right:1px solid #c4c4c4;display:flex;justify-content:center;align-items:center;padding:1em}.card-image{height:12em;width:12em;background-position:center;background-size:cover;transition:all .2s ease-in-out;border:0;outline:0;box-shadow:0}.card-image:hover{transform:scale(1.1)}.card-content{width:100%;padding:1.5em;display:flex;flex-direction:column;justify-content:space-between}.card-title-container{display:flex;justify-content:space-between}.card-icon{color:#c28200;opacity:.85;margin-top:-.5em;margin-right:-.5em;font-size:1.4em}.card-icon svg{width:1em;height:1em}.card-title{color:#b12008;margin:0;margin-bottom:.5em}.card-description{color:#34495e;margin:0;line-height:1.6em;position:relative}.card-link{position:absolute;right:.5em;bottom:0;margin-bottom:-.5em}@media (max-width:1350px){.card-container{width:100%}.header-left{padding-bottom:1em}}@media (max-width:1000px){.header{padding-top:1em;padding-bottom:1em}.header-container{display:block}.header-left{display:block}.header-menu{justify-content:center;position:relative;margin-top:0}.header-content{padding:0}.header-image{margin:0;text-align:center}.header-image img{width:6em}.header-sub-title{margin-top:1em;text-align:center}.header-title{text-align:center;margin-bottom:.25em}.header-description{text-align:center}.content{display:block}.nav{margin-right:0;user-select:none}#nav-enabler{display:flex}#nav-enabler-icon{transform:rotate(-90deg)}#nav-content{max-height:0;transition:max-height .1s ease-out}.nav-item{width:auto}.nav-mobile-enabler #nav-enabler-icon{transition:all .1s ease}.mosaic{position:relative;border-top:1px solid #c4c4c4;padding-top:1em}.mosaic-header{text-align:center}.card{display:block}.card-image-container{padding:0;margin:0;border-right:0;border-bottom:1px solid #c4c4c4}.card-content{width:auto}}

View file

@ -0,0 +1 @@
html{overflow-y:scroll}body{font-family:Roboto,sans-serif;margin:0}.container{width:60%;margin:0 auto}a{color:#3498db}a:hover{text-decoration:underline;transition:color .2s;color:#2980b9}body,html{height:100%}body{display:flex;flex-direction:column}.up-footer{flex:1 0 auto}.sticky-footer{flex-shrink:0}.proposed-alert{position:fixed;z-index:9999999;left:1em;bottom:2em;padding:1em;font-weight:700;border-radius:3px;text-transform:uppercase;border:1px solid #c0392b;background-color:#e74c3c;color:#fff}.btn{padding:.5em 1em;color:#fff;border-radius:7px;background:#2c3e50;border:0;cursor:pointer}.btn:focus{outline:0;opacity:.8}@media (max-width:1600px){.container{width:70%}}@media (max-width:1500px){.container{width:80%}}@media (max-width:900px){.container{width:92%}}

File diff suppressed because one or more lines are too long

35
gulpfile.js Normal file
View file

@ -0,0 +1,35 @@
const gulp = require('gulp')
const cleanCSS = require('gulp-clean-css')
const terser = require('gulp-terser')
const developmentPath = './assets/development'
const productionPath = './assets/production'
function minifyStyles() {
return gulp.src(developmentPath + '/styles/*.css')
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(gulp.dest(productionPath + '/styles'))
}
function minifyScripts() {
return gulp.src(developmentPath + '/scripts/home.js')
.pipe(terser())
.pipe(gulp.dest(productionPath + '/scripts'))
}
function copyFavicon() {
return gulp.src(developmentPath + '/favicon.ico')
.pipe(gulp.dest(productionPath))
}
function copyImages() {
return gulp.src(developmentPath + '/imgs/*')
.pipe(gulp.dest(productionPath + '/imgs'))
}
exports.build = gulp.series(
copyImages,
copyFavicon,
minifyScripts,
minifyStyles
)

2351
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,7 @@
"@types/cors": "^2.8.6", "@types/cors": "^2.8.6",
"@types/express": "^4.17.6", "@types/express": "^4.17.6",
"@types/html-to-text": "^5.1.1", "@types/html-to-text": "^5.1.1",
"@types/http-proxy-middleware": "^0.19.3",
"@types/ioredis": "^4.17.0", "@types/ioredis": "^4.17.0",
"@types/jest": "^26.0.4", "@types/jest": "^26.0.4",
"@types/moment": "^2.13.0", "@types/moment": "^2.13.0",
@ -25,6 +26,7 @@
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"express": "^4.17.1", "express": "^4.17.1",
"html-to-text": "^5.1.1", "html-to-text": "^5.1.1",
"http-proxy-middleware": "^1.0.5",
"ioredis": "^4.17.3", "ioredis": "^4.17.3",
"jest": "^26.1.0", "jest": "^26.1.0",
"moment": "^2.27.0", "moment": "^2.27.0",
@ -47,10 +49,17 @@
"test-watch": "jest --verbose --watchAll", "test-watch": "jest --verbose --watchAll",
"dev": "./node_modules/.bin/tsc --watch", "dev": "./node_modules/.bin/tsc --watch",
"serve": "./node_modules/.bin/nodemon dist/app.js", "serve": "./node_modules/.bin/nodemon dist/app.js",
"build": "./node_modules/.bin/tsc" "build": "./node_modules/.bin/tsc",
"assets": "./node_modules/.bin/gulp build",
"start": "node app.js"
}, },
"main": "dist/index.js", "main": "dist/index.js",
"devDependencies": { "devDependencies": {
"gulp": "^4.0.2",
"gulp-clean-css": "^4.3.0",
"gulp-minify": "^3.1.0",
"gulp-terser": "^1.2.0",
"gulp-uglify": "^3.0.2",
"nodemon": "^2.0.4", "nodemon": "^2.0.4",
"supertest": "^4.0.2" "supertest": "^4.0.2"
} }

View file

@ -72,7 +72,7 @@ export default class MediaService {
size: file.size, size: file.size,
// @ts-ignore // @ts-ignore
originalFileName: file.originalname, originalFileName: file.originalname,
type type: type === 'media' ? file.contentType.split('/')[0] : type
} }
} }
} }

View file

@ -15,6 +15,7 @@ import cors from 'cors'
import twig from 'twig' import twig from 'twig'
import EmailService from './EmailService' import EmailService from './EmailService'
import ErrorController from './controllers/ErrorController' import ErrorController from './controllers/ErrorController'
import { createProxyMiddleware, Filter, Options, RequestHandler } from 'http-proxy-middleware';
process.on('unhandledRejection', (err) => { process.on('unhandledRejection', (err) => {
console.error(err) console.error(err)
@ -27,7 +28,7 @@ dotenv.config({
}) })
const app: express.Application = express() const app: express.Application = express()
const host: string = "0.0.0.0" const host: string = process.env.HOST === undefined ? '127.0.0.1' : process.env.HOST
const port: number = 8001 const port: number = 8001
twig.cache(false) twig.cache(false)
@ -100,6 +101,14 @@ let main = async () => {
.delete('/', DelegateController.destroy) .delete('/', DelegateController.destroy)
) )
app.use('/proxy-s3', createProxyMiddleware({
target: 'https://fva-condorcet.s3.fr-par.scw.cloud',
changeOrigin: true,
pathRewrite: {
'^/proxy-s3/': '/'
},
}))
/* /*
.put('/tags/:id', AdminTagController.update) .put('/tags/:id', AdminTagController.update)
@ -111,8 +120,9 @@ let main = async () => {
//app.post('/api/media', MediaController.uploadRoute()) //app.post('/api/media', MediaController.uploadRoute())
//app.delete('/api/media/:key', MediaController.delete) //app.delete('/api/media/:key', MediaController.delete)
const assetsPath: string = process.env.ASSETS_PATH === undefined ? './assets/development' : process.env.ASSETS_PATH
app.use(express.static(path.resolve('./static'))) app.use(express.static(path.resolve(assetsPath)))
app.get('/500', ErrorController.internalError) app.get('/500', ErrorController.internalError)

View file

@ -180,6 +180,8 @@ export default class AdminOrganizationController {
extra.slugs = currentSlugs.concat([slug]) extra.slugs = currentSlugs.concat([slug])
} }
extra.adminName = proposedVersion.name extra.adminName = proposedVersion.name
// keep updated the contacts.email address with the root address
extra.email = proposedVersion.contacts.email extra.email = proposedVersion.contacts.email
/** /**

View file

@ -39,6 +39,11 @@ export default class DelegateController {
let proposedVersion: any = req.body let proposedVersion: any = req.body
proposedVersion.tags = tags proposedVersion.tags = tags
// remove useless isResponsable
if (Utils.isUsable(proposedVersion, 'contacts.peoples') && Array.isArray(proposedVersion.contacts.peoples)) {
proposedVersion.contacts.peoples = proposedVersion.contacts.peoples.filter((p: any) => !p.isResponsable)
}
// sanitize long description // sanitize long description
if (Utils.isStrUsable(proposedVersion.descriptionLong)) { if (Utils.isStrUsable(proposedVersion.descriptionLong)) {
proposedVersion.descriptionLong = proposedVersion.descriptionLong.replace(/\n/g, '') proposedVersion.descriptionLong = proposedVersion.descriptionLong.replace(/\n/g, '')
@ -127,6 +132,7 @@ export default class DelegateController {
Promise.all(promises).then(() => { Promise.all(promises).then(() => {
next(req.body.tags) next(req.body.tags)
}).catch((err) => { }).catch((err) => {
console.log(err)
return res.status(400).json({ success: false, errors: err, _note: 'One of the tag id provided is invalid' }) return res.status(400).json({ success: false, errors: err, _note: 'One of the tag id provided is invalid' })
}) })
} else { } else {

View file

@ -78,12 +78,7 @@ export default class PublicController {
// if (lastPublished !== null) { // if (lastPublished !== null) {
// lastPublished = lastPublished // lastPublished = lastPublished
// } // }
if (Utils.isUsable(version.contacts)) { let formatPhone = (phone: string) => {
if (Utils.isStrUsable(version.contacts, 'address')) {
version.contacts.address = version.contacts.address.split('\n')
}
if (Utils.isStrUsable(version.contacts, 'phone')) {
let phone = version.contacts.phone
if (phone.indexOf('+33') === 0) { if (phone.indexOf('+33') === 0) {
phone = '0' + phone.substr(3) phone = '0' + phone.substr(3)
} }
@ -96,8 +91,25 @@ export default class PublicController {
} }
partEnd = !partEnd partEnd = !partEnd
} }
version.contacts.phoneInt = "+33" + phone.substr(1) return [ "+33" + phone.substr(1), phoneSplit ]
version.contacts.phoneSplit = phoneSplit }
if (Utils.isUsable(version.contacts)) {
if (Utils.isStrUsable(version.contacts, 'address')) {
version.contacts.address = version.contacts.address.split('\n')
}
if (Utils.isStrUsable(version.contacts, 'phone')) {
let formated: any = formatPhone(version.contacts.phone)
version.contacts.phoneInt = formated[0]
version.contacts.phoneSplit = formated[1]
}
if (Utils.isUsable(version.contacts, 'peoples') && Array.isArray(version.contacts.peoples)) {
version.contacts.peoples = version.contacts.peoples.map((p: any) => {
let formated: any = formatPhone(p.phone)
p.phoneInt = formated[0]
p.phoneSplit = formated[1]
return p
})
} }
} }
if (Array.isArray(version.gallery)) { if (Array.isArray(version.gallery)) {

View file

@ -8,14 +8,14 @@ Github: https://github.com/lefuturiste
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width"> <meta name="viewport" content="width=device-width">
<link rel="icon" type="image/png" href="/assets/img/favicon.png" /> <link rel="icon" type="image/png" href="/imgs/favicon.png" />
<title>{% block title %}{% endblock %} | Forum des associations 2020</title> <title>{% block title %}{% endblock %} | Forum des associations 2020</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/assets/main.css" /> <link rel="stylesheet" href="/styles/main.css" />
{% if layout is not defined %} {% if layout is not defined %}
<link rel="stylesheet" href="/assets/home.css" /> <link rel="stylesheet" href="/styles/home.css" />
{% endif %} {% endif %}
{% block head %}{% endblock %} {% block head %}{% endblock %}
@ -27,7 +27,7 @@ Github: https://github.com/lefuturiste
<div class="container header-container"> <div class="container header-container">
<div class="header-left"> <div class="header-left">
<div class="header-image"> <div class="header-image">
<a href="/"><img src="/assets/img/espace_condorcet_logo.jpg" /></a> <a href="/"><img src="/imgs/espace_condorcet_logo.jpg" /></a>
</div> </div>
<div class="header-content"> <div class="header-content">
<a <a

View file

@ -1,7 +1,7 @@
{% extends "./base.twig" %} {% extends "./base.twig" %}
{% block title %}{{ title }}{% endblock %} {% block title %}{{ title }}{% endblock %}
{% block head %} {% block head %}
<link rel="stylesheet" href="/assets/error.css" /> <link rel="stylesheet" href="/styles/error.css" />
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="error-container"> <div class="error-container">

View file

@ -24,12 +24,7 @@
<div id="nav-content"> <div id="nav-content">
<div class="nav-item" id="nav-all"> <div class="nav-item" id="nav-all">
<div class="nav-icon"> <div class="nav-icon">
<svg <svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
aria-hidden="true"
focusable="false"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
<path fill="currentColor" d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"></path> <path fill="currentColor" d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"></path>
</svg> </svg>
</div> </div>
@ -45,12 +40,7 @@
{% for tag in tags %} {% for tag in tags %}
<div class="nav-item" data-tag-id="{{ tag._id }}"> <div class="nav-item" data-tag-id="{{ tag._id }}">
<div class="nav-icon"> <div class="nav-icon">
<svg <svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{ tag.icon.width }} {{ tag.icon.height }}">
aria-hidden="true"
focusable="false"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 {{ tag.icon.width }} {{ tag.icon.height }}">
<path <path
fill="currentColor" fill="currentColor"
d="{{ tag.icon.path }}" d="{{ tag.icon.path }}"
@ -62,15 +52,7 @@
{{ tag.name }} {{ tag.name }}
</div> </div>
<div class="nav-access"> <div class="nav-access">
<svg <svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="chevron-right"
class="svg-inline--fa fa-chevron-right fa-w-10"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 320 512">
<path <path
fill="currentColor" fill="currentColor"
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z" d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"
@ -93,5 +75,5 @@
let tags = JSON.parse(`{{ tagsJSON }}`) let tags = JSON.parse(`{{ tagsJSON }}`)
let organizations = JSON.parse(`{{ organizationsJSON }}`) let organizations = JSON.parse(`{{ organizationsJSON }}`)
</script> </script>
<script src="/assets/js/home.js"></script> <script src="/scripts/home.js"></script>
{% endblock %} {% endblock %}

View file

@ -1,7 +1,8 @@
{% extends "./base.twig" %} {% extends "./base.twig" %}
{% block title %}Association{% endblock %} {% block title %}{{ data.name }}{% endblock %}
{% block head %} {% block head %}
<link rel="stylesheet" href="/assets/organization.css" /> <link rel="stylesheet" href="/styles/organization.css" />
<meta name="description" content="{{ data.descriptionShort }}">
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="header"> <div class="header">
@ -105,13 +106,8 @@
<div class="schedule-category-name"> <div class="schedule-category-name">
{{ item.name }} {{ item.name }}
</div> </div>
<svg <svg class="schedule-category-collapse-icon"
class="schedule-category-collapse-icon" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
aria-hidden="true"
focusable="false"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">
<path fill="currentColor" d="M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z"></path> <path fill="currentColor" d="M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z"></path>
</svg> </svg>
</div> </div>
@ -167,7 +163,69 @@
<div class="section-divider"></div> <div class="section-divider"></div>
</div> </div>
<div class="org-container contact"> <div class="org-container contact">
{% if data.contacts.person|length > 0 %} {% if data.contacts.peoples|length > 0 %}
<div class="peoples">
<div class="people-card">
<div class="people-header">
<div class="people-name">
{{ data.contacts.person }}
</div>
<div class="people-role">
Responsable
</div>
</div>
<div class="people-contacts">
<div class="people-contact email">
<svg class="people-contact-icon" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z"></path>
</svg>
<a href="mailto:{{ data.contacts.email }}" class="people-email-content">
{{ data.contacts.email }}
</a>
</div>
<div class="people-contact phone">
<svg class="people-contact-icon" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"></path>
</svg>
<a href="telto:{{ data.contacts.phoneInt }}" class="people-email-content">
{{ data.contacts.phoneSplit }}
</a>
</div>
</div>
</div>
{% for people in data.contacts.peoples %}
<div class="people-card">
<div class="people-header">
<div class="people-name">
{{ people.name }}
</div>
<div class="people-role">
{{ people.role }}
</div>
</div>
<div class="people-contacts">
<div class="people-contact email">
<svg class="people-contact-icon" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z"></path>
</svg>
<a href="mailto:{{ people.email }}" class="people-email-content">
{{ people.email }}
</a>
</div>
<div class="people-contact phone">
<svg class="people-contact-icon" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"></path>
</svg>
<a href="telto:{{ people.phoneInt }}" class="people-email-content">
{{ people.phoneSplit }}
</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% if data.contacts.peoples|length == 0 and data.contacts.person|length > 0 %}
<div class="contact-item person"> <div class="contact-item person">
<div class="contact-icon"> <div class="contact-icon">
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"> <svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
@ -179,7 +237,7 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% if data.contacts.email|length > 0 %} {% if data.contacts.peoples|length == 0 and data.contacts.email|length > 0 %}
<div class="contact-item email"> <div class="contact-item email">
<div class="contact-icon"> <div class="contact-icon">
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
@ -191,6 +249,18 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% if data.contacts.peoples|length == 0 and data.contacts.phone|length > 0 %}
<div class="contact-item phone">
<div class="contact-icon">
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"></path>
</svg>
</div>
<div class="contact-content">
<a href="telto:{{ data.contacts.phoneInt }}">{{ data.contacts.phoneSplit }}</a>
</div>
</div>
{% endif %}
{% if data.contacts.address|length > 0 %} {% if data.contacts.address|length > 0 %}
<div class="contact-item address"> <div class="contact-item address">
<div class="contact-icon"> <div class="contact-icon">
@ -205,18 +275,6 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
{% if data.contacts.phone|length > 0 %}
<div class="contact-item phone">
<div class="contact-icon">
<svg aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"></path>
</svg>
</div>
<div class="contact-content">
<a href="telto:{{ data.contacts.phoneInt }}">{{ data.contacts.phoneSplit }}</a>
</div>
</div>
{% endif %}
{% if data.contacts.website|length > 0 %} {% if data.contacts.website|length > 0 %}
<div class="contact-item website"> <div class="contact-item website">
<div class="contact-icon"> <div class="contact-icon">
@ -308,5 +366,5 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script src="/assets/js/organization.js"></script> <script src="/scripts/organization.js"></script>
{% endblock %} {% endblock %}

File diff suppressed because it is too large Load diff

1518
yarn.lock

File diff suppressed because it is too large Load diff