upstream: integrar Oasis 1.3.1
Base del merge a tres bandas: git 0.9.5 de epsylon, esta rama y el src de la
APK oficial 1.3.1 (la variante movil: OASIS_MOBILE, regex sin \p{}, audio y
video de Android). Corre en el mismo nodejs-mobile 18.20.4 que ya usabamos.
Se conserva de la rama: Karvan, identidades y multicuenta, topbar y barra
inferior, borrado de EXIF sin sharp, filtro hot del foro, RTC sin STUN y los
modulos apagados en movil (wallet, banking, torrents).
Se toma de upstream lo que ya hace de serie: respuesta citada en chats, ssb-lan
en movil, configuracion en ~/.ssb/oasis (sobrevive a reinstalar el backend).
El asistente de bienvenida deja elegir workflow tambien en movil.
BIN
src/client/assets/images/theme-clear-snh.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
src/client/assets/images/theme-dark-snh.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
src/client/assets/images/theme-matrix-snh.png
Normal file
|
After Width: | Height: | Size: 2 KiB |
BIN
src/client/assets/images/theme-purple-snh.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
src/client/assets/images/ux-feed.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
src/client/assets/images/ux-phone.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
|
@ -261,7 +261,7 @@ h3 { font-size: 1em !important; }
|
|||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
flex-wrap: wrap !important;
|
||||
justify-content: center !important;
|
||||
justify-content: flex-start !important;
|
||||
align-items: center !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
|
|
@ -288,8 +288,8 @@ h3 { font-size: 1em !important; }
|
|||
}
|
||||
.inhabitant-action .filter-btn {
|
||||
min-height: 0 !important;
|
||||
padding: 7px 12px !important;
|
||||
font-size: 13px !important;
|
||||
padding: 2px 9px !important;
|
||||
font-size: .75em !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.profile-sensors-box {
|
||||
|
|
@ -315,8 +315,8 @@ h3 { font-size: 1em !important; }
|
|||
.activity-filter-col .filter-btn,
|
||||
.activity-sub-filter .filter-btn {
|
||||
min-height: 0 !important;
|
||||
padding: 7px 12px !important;
|
||||
font-size: 13px !important;
|
||||
padding: 2px 9px !important;
|
||||
font-size: .75em !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
|
|
@ -450,10 +450,6 @@ h3 { font-size: 1em !important; }
|
|||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
}
|
||||
|
||||
.tribe-media-grid {
|
||||
grid-template-columns: repeat(2, 1fr) !important;
|
||||
}
|
||||
|
||||
.tribe-overview-grid {
|
||||
grid-template-columns: 1fr !important;
|
||||
}
|
||||
|
|
@ -466,24 +462,11 @@ h3 { font-size: 1em !important; }
|
|||
height: 180px !important;
|
||||
}
|
||||
|
||||
.tribe-votation-option {
|
||||
flex-direction: column !important;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.tribe-content-header {
|
||||
flex-direction: column !important;
|
||||
gap: 8px !important;
|
||||
}
|
||||
|
||||
.tribe-content-filters {
|
||||
flex-wrap: wrap !important;
|
||||
}
|
||||
|
||||
.tribe-media-filters {
|
||||
flex-wrap: wrap !important;
|
||||
}
|
||||
|
||||
.forum-card {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
|
@ -626,6 +609,7 @@ a.filter-btn,
|
|||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
flex: 0 0 auto !important;
|
||||
height: 42px !important;
|
||||
font-size: 16px !important;
|
||||
box-sizing: border-box !important;
|
||||
|
|
@ -672,7 +656,7 @@ a.filter-btn,
|
|||
padding: 9px 16px !important;
|
||||
}
|
||||
.filters .ui-toolbar--filters {
|
||||
justify-content: center !important;
|
||||
justify-content: flex-start !important;
|
||||
align-items: center !important;
|
||||
gap: 6px !important;
|
||||
}
|
||||
|
|
@ -728,6 +712,15 @@ a.filter-btn,
|
|||
max-width: 100% !important;
|
||||
overflow-wrap: anywhere !important;
|
||||
}
|
||||
.card-field .card-value.user-link,
|
||||
.card-field .card-value .user-link {
|
||||
display: inline-block !important;
|
||||
vertical-align: bottom !important;
|
||||
max-width: 100% !important;
|
||||
white-space: nowrap !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
}
|
||||
|
||||
.market-grid,
|
||||
.shop-products-grid,
|
||||
|
|
@ -817,14 +810,14 @@ a.filter-btn,
|
|||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.oasis-id-copy {
|
||||
input.oasis-id-copy[readonly] {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
font-family: monospace !important;
|
||||
font-size: 12px !important;
|
||||
font-size: clamp(8px, 2.5vw, 12px) !important;
|
||||
text-align: center !important;
|
||||
padding: 8px !important;
|
||||
padding: 8px 6px !important;
|
||||
border: 1px solid #FFA500 !important;
|
||||
border-radius: 8px !important;
|
||||
background: rgba(255, 165, 0, 0.08) !important;
|
||||
|
|
@ -849,6 +842,7 @@ a.create-button {
|
|||
|
||||
.peers-list .block-info-table,
|
||||
.peers-technical-block .block-info-table,
|
||||
.parliament-rows-table,
|
||||
.gov-overview {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
|
|
@ -859,17 +853,20 @@ a.create-button {
|
|||
}
|
||||
.peers-list .block-info-table tbody,
|
||||
.peers-technical-block .block-info-table tbody,
|
||||
.parliament-rows-table tbody,
|
||||
.gov-overview tbody {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.gov-overview thead { display: none !important; }
|
||||
.gov-overview thead,
|
||||
.parliament-rows-table thead { display: none !important; }
|
||||
.peers-list .block-info-table tr:first-child,
|
||||
.peers-technical-block .block-info-table tr:first-child {
|
||||
display: none !important;
|
||||
}
|
||||
.peers-list .block-info-table tr,
|
||||
.peers-technical-block .block-info-table tr,
|
||||
.parliament-rows-table tbody tr,
|
||||
.gov-overview tbody tr {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
|
|
@ -882,6 +879,7 @@ a.create-button {
|
|||
}
|
||||
.peers-list .block-info-table td,
|
||||
.peers-technical-block .block-info-table td,
|
||||
.parliament-rows-table tbody td,
|
||||
.gov-overview tbody td {
|
||||
display: flex !important;
|
||||
justify-content: space-between !important;
|
||||
|
|
@ -897,6 +895,7 @@ a.create-button {
|
|||
}
|
||||
.peers-list .block-info-table td::before,
|
||||
.peers-technical-block .block-info-table td::before,
|
||||
.parliament-rows-table tbody td::before,
|
||||
.gov-overview tbody td::before {
|
||||
content: attr(data-label);
|
||||
flex: 0 0 auto !important;
|
||||
|
|
@ -913,6 +912,121 @@ a.create-button {
|
|||
.peers-technical-block .block-info-table td[data-label=""]::before { content: none !important; }
|
||||
.peers-list .block-info-table td .peer-key,
|
||||
.peers-technical-block .block-info-table td .peer-key { text-align: right !important; }
|
||||
.phone-history td.phone-dir,
|
||||
.phone-contact .phone-dir,
|
||||
.phone-dir {
|
||||
display: none !important;
|
||||
}
|
||||
.phone-contact {
|
||||
gap: 6px !important;
|
||||
padding: 8px !important;
|
||||
}
|
||||
.phone-contact .user-link {
|
||||
flex: 1 1 100% !important;
|
||||
min-width: 0 !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.phone-contact .date-link {
|
||||
flex: 0 1 auto !important;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.phone-history,
|
||||
.phone-history tbody {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.phone-history tr:first-child {
|
||||
display: none !important;
|
||||
}
|
||||
.phone-history tr {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
border: 1px solid #444 !important;
|
||||
border-radius: 10px !important;
|
||||
margin: 0 0 8px 0 !important;
|
||||
padding: 4px 10px !important;
|
||||
}
|
||||
.phone-history td {
|
||||
display: flex !important;
|
||||
justify-content: space-between !important;
|
||||
align-items: baseline !important;
|
||||
gap: 10px !important;
|
||||
width: 100% !important;
|
||||
border: 0 !important;
|
||||
padding: 3px 0 !important;
|
||||
font-size: 12px !important;
|
||||
text-align: right !important;
|
||||
}
|
||||
.phone-history td::before {
|
||||
content: attr(data-label);
|
||||
flex: 0 0 auto !important;
|
||||
font-weight: 700 !important;
|
||||
text-transform: uppercase;
|
||||
font-size: 10px !important;
|
||||
letter-spacing: .03em;
|
||||
opacity: .7 !important;
|
||||
text-align: left !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.phone-history td.phone-row-actions {
|
||||
justify-content: flex-end !important;
|
||||
padding: 0 !important;
|
||||
margin-top: -6px !important;
|
||||
}
|
||||
.phone-history .phone-row-delete .btn-singleview,
|
||||
.phone-latest-row .phone-row-delete .btn-singleview {
|
||||
width: 32px !important;
|
||||
height: 32px !important;
|
||||
min-width: 0 !important;
|
||||
min-height: 0 !important;
|
||||
line-height: 1 !important;
|
||||
padding: 0 !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.phone-history td.phone-row-actions::before {
|
||||
content: none !important;
|
||||
}
|
||||
.phone-latest-row .phone-row-delete {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
.phone-history td .user-link {
|
||||
min-width: 0 !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
.peers-list .block-info-table td .ubi-tick-ok,
|
||||
.peers-list .block-info-table td .peer-tor-no,
|
||||
.peers-technical-block .block-info-table td .ubi-tick-ok,
|
||||
.peers-technical-block .block-info-table td .peer-tor-no {
|
||||
padding: 0 !important;
|
||||
line-height: 1.2 !important;
|
||||
}
|
||||
|
||||
.conn-actions,
|
||||
.peers-conn-actions {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
flex-wrap: wrap !important;
|
||||
gap: 8px !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.conn-actions form,
|
||||
.peers-conn-actions form {
|
||||
flex: 1 1 45% !important;
|
||||
min-width: 130px !important;
|
||||
max-width: 100% !important;
|
||||
margin: 0 !important;
|
||||
display: block !important;
|
||||
}
|
||||
.conn-actions form button,
|
||||
.peers-conn-actions form button {
|
||||
width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
.relationship-status .relationship-actions { flex-direction: column !important; align-items: stretch !important; gap: 8px !important; }
|
||||
.relationship-status .relationship-actions form,
|
||||
|
|
@ -921,10 +1035,21 @@ a.create-button {
|
|||
.profile-sensors-box { align-items: center !important; text-align: center !important; }
|
||||
.profile-sensors-box > * { margin-left: auto !important; margin-right: auto !important; justify-content: center !important; }
|
||||
|
||||
.tribe-feed .refeed-column,
|
||||
.tribe-feed-full .refeed-column { align-self: center !important; align-items: center !important; justify-content: center !important; }
|
||||
.tribe-feed .card-footer,
|
||||
.tribe-feed-full .card-footer { display: flex !important; flex-direction: column !important; align-items: center !important; text-align: center !important; gap: 2px !important; }
|
||||
.profile-layout,
|
||||
.profile-layout .tribe-side,
|
||||
.profile-layout .tribe-main {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.profile-side-description,
|
||||
.profile-side-description p,
|
||||
.trending-card .card-section,
|
||||
.feed-text {
|
||||
word-break: normal !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
|
||||
.invite-qr-card { display: flex !important; justify-content: center !important; border: none !important; background: transparent !important; padding: 0 !important; box-shadow: none !important; margin: 0 auto !important; }
|
||||
.invite-qr-img { display: block; margin: 0 auto; }
|
||||
|
|
@ -942,3 +1067,445 @@ a.create-button {
|
|||
.chat-messages-list { padding: 0 !important; }
|
||||
.chat-message { max-width: 92% !important; }
|
||||
.chat-message.chat-poll { max-width: 97% !important; }
|
||||
.feed-workspace {
|
||||
display: block !important;
|
||||
}
|
||||
.feed-side {
|
||||
display: none !important;
|
||||
}
|
||||
.tribe-info-table,
|
||||
.tribe-info-table tbody,
|
||||
.tribe-info-table tr,
|
||||
.tribe-info-table td {
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
text-align: left !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.tribe-info-table td .user-link {
|
||||
display: inline-block !important;
|
||||
max-width: 100% !important;
|
||||
white-space: nowrap !important;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
}
|
||||
.school-lesson-summary {
|
||||
flex-wrap: wrap !important;
|
||||
}
|
||||
.school-lesson-summary-title {
|
||||
flex: 1 1 100% !important;
|
||||
min-width: 0 !important;
|
||||
white-space: normal !important;
|
||||
overflow-wrap: anywhere !important;
|
||||
}
|
||||
.school-lesson-summary-meta {
|
||||
flex: 1 1 100% !important;
|
||||
white-space: normal !important;
|
||||
}
|
||||
.feed-votes-summary {
|
||||
flex-wrap: wrap !important;
|
||||
max-width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
.feed-votes-summary .vote-category {
|
||||
white-space: nowrap !important;
|
||||
flex: 0 0 auto !important;
|
||||
}
|
||||
.tribe-open-invite-code {
|
||||
font-size: .85em !important;
|
||||
}
|
||||
|
||||
.school-progress-row {
|
||||
flex-direction: column !important;
|
||||
align-items: flex-start !important;
|
||||
gap: 6px !important;
|
||||
}
|
||||
.school-progress-issue {
|
||||
width: 100% !important;
|
||||
}
|
||||
.school-progress-issue input[type="text"] {
|
||||
max-width: 100% !important;
|
||||
flex: 1 1 100% !important;
|
||||
}
|
||||
|
||||
.subscription-box-block {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
align-items: center !important;
|
||||
gap: 8px !important;
|
||||
}
|
||||
.subscription-box-block .subscription-form { margin: 0 !important; }
|
||||
|
||||
.profile-module-section,
|
||||
.profile-module-section .trending-card,
|
||||
.profile-module-section .card-body,
|
||||
.profile-module-section .card-section {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.card-section-action {
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
.card-section-action .keep-reading-link {
|
||||
text-align: center !important;
|
||||
}
|
||||
.card-field.image-container,.card-field.video-container,.card-field.audio-container { justify-content: center !important; }
|
||||
.card-field.media-left { justify-content: flex-start !important; }
|
||||
|
||||
.card-footer .date-link,
|
||||
.card-footer .user-link { padding: 0 10px !important; font-size: 12px !important; }
|
||||
.card-meta-row .opinions-summary,
|
||||
.card-meta-row .comments-summary-link { padding: 0 10px !important; font-size: 12px !important; }
|
||||
|
||||
.parliament-rows-table tbody td[data-label=""] { justify-content: center !important; }
|
||||
.parliament-rows-table tbody td[data-label=""]::before { content: none !important; }
|
||||
.parliament-rows-table tbody td .parliament-avatar-cell {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
gap: 8px !important;
|
||||
justify-content: flex-end !important;
|
||||
}
|
||||
.parliament-rows-table tbody td .parliament-leader-avatar { width: 32px !important; height: 32px !important; }
|
||||
.parliament-rows-table tbody td .parliament-method-img { max-height: 28px !important; width: auto !important; }
|
||||
.parliament-rows-table tbody td form { margin: 0 !important; }
|
||||
|
||||
.hemi-legend {
|
||||
flex-direction: column !important;
|
||||
align-items: flex-start !important;
|
||||
gap: 6px !important;
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
.hemi-legend-item {
|
||||
width: 100% !important;
|
||||
flex-wrap: nowrap !important;
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
.hemi-legend-count { margin-left: auto !important; }
|
||||
.hemi-modes { flex-wrap: wrap !important; }
|
||||
.room-item .mailing-archive-head{flex-wrap:wrap}
|
||||
|
||||
.oasis-nav-side-toggle {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
opacity: 0 !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
flex-wrap: wrap !important;
|
||||
align-items: center !important;
|
||||
gap: 8px 6px !important;
|
||||
padding: 8px 8px 4px !important;
|
||||
min-height: 60px !important;
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
z-index: 900 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header + * ,
|
||||
.oasis-nav-side-toggle ~ .header ~ .update-banner:first-of-type {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
body:has(.oasis-nav-side-toggle) {
|
||||
padding-top: 64px !important;
|
||||
}
|
||||
body:has(:is(input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]), textarea, select):focus) .oasis-nav-side-toggle ~ .header {
|
||||
position: absolute !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-mid {
|
||||
display: contents !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left a.logo-icon {
|
||||
order: 1 !important;
|
||||
flex: 0 0 auto !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left a.logo-icon img.logo-icon {
|
||||
width: 44px !important;
|
||||
height: 44px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .oasis-mobile-menus {
|
||||
order: 2 !important;
|
||||
display: flex !important;
|
||||
flex: 1 1 auto !important;
|
||||
flex-wrap: nowrap !important;
|
||||
justify-content: flex-end !important;
|
||||
align-items: center !important;
|
||||
gap: 5px !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .oasis-menu-slot {
|
||||
display: inline-flex !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .oasis-menu-btn {
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
gap: 4px !important;
|
||||
min-height: 44px !important;
|
||||
padding: 6px 9px !important;
|
||||
white-space: nowrap !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .oasis-menu-slot .oasis-menu-close {
|
||||
display: none !important;
|
||||
}
|
||||
#nav-left-toggle:checked ~ .header .oasis-menu-slot-left .oasis-menu-open,
|
||||
#nav-right-toggle:checked ~ .header .oasis-menu-slot-right .oasis-menu-open {
|
||||
display: none !important;
|
||||
}
|
||||
#nav-left-toggle:checked ~ .header .oasis-menu-slot-left .oasis-menu-close,
|
||||
#nav-right-toggle:checked ~ .header .oasis-menu-slot-right .oasis-menu-close {
|
||||
display: inline-flex !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav {
|
||||
order: 3 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav {
|
||||
order: 4 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav {
|
||||
flex: 1 1 calc(50% - 4px) !important;
|
||||
width: auto !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav ul,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav ul {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
|
||||
gap: 4px !important;
|
||||
list-style: none !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav ul li,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav ul li {
|
||||
margin: 0 !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav ul li a,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav ul li a {
|
||||
position: relative !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
width: 100% !important;
|
||||
min-height: 50px !important;
|
||||
padding: 0 !important;
|
||||
font-size: 0 !important;
|
||||
text-decoration: none !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header nav ul li a .nav-text {
|
||||
display: none !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header nav ul li a .emoji {
|
||||
font-size: 1.6rem !important;
|
||||
line-height: 1 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header nav ul li a .inbox-badge {
|
||||
position: absolute !important;
|
||||
top: 3px !important;
|
||||
right: 3px !important;
|
||||
margin: 0 !important;
|
||||
font-size: 0.66rem !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .main-column {
|
||||
order: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .sidebar-left,
|
||||
.oasis-nav-side-toggle ~ .main-content .sidebar-right {
|
||||
display: none !important;
|
||||
}
|
||||
#nav-left-toggle:checked ~ .main-content .sidebar-left,
|
||||
#nav-right-toggle:checked ~ .main-content .sidebar-right {
|
||||
display: block !important;
|
||||
order: -1 !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding: 0 4px !important;
|
||||
margin: 0 0 8px 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-header {
|
||||
margin: 0 0 6px 0 !important;
|
||||
padding: 12px !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .sidebar-left .oasis-nav-list,
|
||||
.oasis-nav-side-toggle ~ .main-content .sidebar-right .oasis-nav-list {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
|
||||
gap: 8px !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-list li {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-list li a {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
gap: 6px !important;
|
||||
min-height: 74px !important;
|
||||
height: 100% !important;
|
||||
padding: 8px 4px !important;
|
||||
margin: 0 !important;
|
||||
text-align: center !important;
|
||||
font-size: 0.72rem !important;
|
||||
opacity: 1 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-list li a .emoji {
|
||||
width: auto !important;
|
||||
font-size: 1.5rem !important;
|
||||
line-height: 1 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-list li a .nav-text {
|
||||
line-height: 1.15 !important;
|
||||
overflow-wrap: anywhere !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav,
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav {
|
||||
position: fixed !important;
|
||||
bottom: 0 !important;
|
||||
height: 66px !important;
|
||||
width: 50% !important;
|
||||
flex: none !important;
|
||||
z-index: 900 !important;
|
||||
margin: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav {
|
||||
left: 0 !important;
|
||||
right: auto !important;
|
||||
padding: 6px 2px 6px 6px !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav {
|
||||
right: 0 !important;
|
||||
left: auto !important;
|
||||
padding: 6px 6px 6px 2px !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .oasis-footer {
|
||||
padding-bottom: 84px !important;
|
||||
}
|
||||
body:has(:is(input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]), textarea, select):focus) .oasis-nav-side-toggle ~ .header .top-bar-left nav,
|
||||
body:has(:is(input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]), textarea, select):focus) .oasis-nav-side-toggle ~ .header .top-bar-right nav {
|
||||
display: none !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-left nav {
|
||||
width: calc(300% / 7) !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav {
|
||||
width: calc(400% / 7) !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .top-bar-right nav ul {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .sidebar-left nav > ul,
|
||||
.oasis-nav-side-toggle ~ .main-content .sidebar-right nav > ul {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
|
||||
grid-auto-flow: row dense !important;
|
||||
gap: 8px !important;
|
||||
list-style: none !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-group {
|
||||
display: contents !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-group > .oasis-nav-header {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
gap: 6px !important;
|
||||
min-height: 74px !important;
|
||||
margin: 0 !important;
|
||||
padding: 8px 4px !important;
|
||||
text-align: center !important;
|
||||
font-size: 0.68rem !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-group > .oasis-nav-header .emoji {
|
||||
width: auto !important;
|
||||
font-size: 1.5rem !important;
|
||||
line-height: 1 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-group > .oasis-nav-header .nav-text {
|
||||
flex: 0 0 auto !important;
|
||||
line-height: 1.15 !important;
|
||||
overflow-wrap: anywhere !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-group > .oasis-nav-header .oasis-nav-arrow {
|
||||
display: none !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-group > .oasis-nav-list {
|
||||
grid-column: 1 / -1 !important;
|
||||
max-height: none !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .main-content .oasis-nav-toggle:not(:checked) + .oasis-nav-header + .oasis-nav-list {
|
||||
display: none !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .oasis-phone-state {
|
||||
order: 1 !important;
|
||||
flex: 1 1 0 !important;
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
align-self: center !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header:has(.oasis-phone-state) .oasis-mobile-menus {
|
||||
flex: 0 1 auto !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .oasis-phone-state-btn {
|
||||
appearance: none !important;
|
||||
-webkit-appearance: none !important;
|
||||
font: inherit !important;
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
gap: 3px !important;
|
||||
min-height: 0 !important;
|
||||
justify-content: center !important;
|
||||
width: 38px !important;
|
||||
height: 38px !important;
|
||||
padding: 0 !important;
|
||||
font-size: 8.5px !important;
|
||||
line-height: 1.2 !important;
|
||||
white-space: nowrap !important;
|
||||
border-radius: 999px !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
.oasis-nav-side-toggle ~ .header .oasis-phone-state-btn .pm-exposition-icon {
|
||||
font-size: 22px !important;
|
||||
line-height: 1 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,32 +224,23 @@ footer a:hover {
|
|||
background: none;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link {
|
||||
color: #181818;
|
||||
background: #D94F4F;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link:hover {
|
||||
background: #D94F4F;
|
||||
color: #111;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link {
|
||||
a.user-link, button.user-link {
|
||||
background-color: #FFD600;
|
||||
color: #FFFFFF;
|
||||
border-color: #FFD600;
|
||||
transition: background-color 0.3s, color 0.3s, border-color 0.3s;
|
||||
}
|
||||
|
||||
a.user-link:hover {
|
||||
a.user-link:hover, button.user-link:hover {
|
||||
background-color: #FFD600;
|
||||
border-color: #FFD600;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link:focus {
|
||||
a.user-link:focus, button.user-link:focus {
|
||||
background-color: #9A2F2F;
|
||||
border-color: #9A2F2F;
|
||||
color: #FFFFFF;
|
||||
|
|
@ -302,7 +293,7 @@ a.user-link:focus {
|
|||
.stats-kpi-value { color: #007BFF !important; }
|
||||
.carbon-bar-note, .carbon-bar-formula { color: #007BFF !important; }
|
||||
.graphos-node-label { fill: #2C2C2C !important; }
|
||||
.graphos-node-label-me { fill: #cc7700 !important; }
|
||||
.graphos-node-label-me { fill: #1f6391 !important; }
|
||||
.data-best-label { color: #cc7700 !important; }
|
||||
.data-best-card { background: #FFF3E0 !important; border: 1px solid rgba(204, 119, 0, .4) !important; }
|
||||
.graphos-legend { color: #2C2C2C !important; }
|
||||
|
|
@ -327,6 +318,8 @@ a.user-link:focus {
|
|||
.btn-singleview:hover { background: #E0E0E0 !important; color: #FF8F00 !important; }
|
||||
.btn-spread-on, .content-actions .btn-pin-on { background: #FF6F00 !important; color: #FFFFFF !important; }
|
||||
.btn-spread-on:hover, .content-actions .btn-pin-on:hover { background: #FF8F00 !important; color: #FFFFFF !important; }
|
||||
.content-actions .btn-singleview.btn-content { border: 1px solid #FF6F00 !important; }
|
||||
.content-actions .btn-singleview.btn-content:hover { background: rgba(255, 111, 0, .18) !important; border-color: #FF6F00 !important; }
|
||||
.btn-back { background: #FF6F00 !important; color: #FFFFFF !important; }
|
||||
.btn-back:hover { background: #FF8F00 !important; color: #FFFFFF !important; }
|
||||
.block-info-table td, .pm-info-table td { border-color: #E0E0E0 !important; }
|
||||
|
|
@ -383,3 +376,48 @@ a.user-link:focus {
|
|||
.karvan-msg-self { background-color: #FFEFC2 !important; border-color: #D9A400 !important; }
|
||||
.karvan-msg .km-from { color: #8A6D00 !important; }
|
||||
.karvan-msg .km-text { color: #2C2C2C !important; }
|
||||
.map-viewer, .map-stage div, .map-hero, .map-toolbar, .map-toolbar div, .map-place-results, .map-markers-list, .map-markers-list div, .map-detail-grid, .map-card-thumb .map-viewer { background: transparent !important; border: 0 !important; }
|
||||
.map-pick-cell, .map-pick-cell:hover { border: 0 !important; padding: 0 !important; border-radius: 0 !important; box-shadow: none !important; }
|
||||
.map-pick-cell { background: transparent !important; }
|
||||
.map-pick-cell:hover { background: rgba(255, 111, 0, 0.18) !important; }
|
||||
.map-ctrl, .map-place-result { padding: 0 !important; border-radius: 6px !important; box-shadow: none !important; }
|
||||
.map-place-result { padding: 4px 10px !important; border-radius: 14px !important; }
|
||||
.map-stage { background: #cfe0ec !important; border: 1px solid #E0E0E0 !important; }
|
||||
.map-marker-row { border-bottom: 1px solid #E0E0E0 !important; }
|
||||
.map-label-country { fill: #4a4a4a; stroke: #ffffff; }
|
||||
.map-place-dot { fill: #333333; stroke: #ffffff; }
|
||||
.map-place-capital { fill: #E65100; }
|
||||
.map-place-label { fill: #222222; stroke: #ffffff; }
|
||||
.map-pin-label-bg { fill: rgba(255, 255, 255, 0.92); stroke: rgba(0, 0, 0, 0.3); }
|
||||
.map-pin-label { fill: #222222; }
|
||||
.map-pin-focus .map-pin-body, .map-cluster-dot { fill: #FF6F00; }
|
||||
.map-pin-focus .map-pin-label-bg { stroke: #FF6F00; }
|
||||
.map-cluster-ring { fill: rgba(255, 111, 0, 0.25); }
|
||||
.map-pick-ring, .map-pick-cross { stroke: #FF6F00; }
|
||||
.map-pins-layer a:hover .map-pin-body, .map-pins a:hover .map-pin-body { fill: #FF6F00; }
|
||||
.map-scale-line { stroke: #333333; }
|
||||
.map-scale-text { fill: #333333; stroke: #ffffff; }
|
||||
.map-attrib { fill: #777777; }
|
||||
.map-ctrl { background: rgba(255, 255, 255, 0.92) !important; color: #FF6F00 !important; border-color: #cccccc !important; }
|
||||
.map-ctrl:hover { background: #FF6F00 !important; color: #ffffff !important; border-color: #FF6F00 !important; }
|
||||
.map-ctrl-off:hover { background: rgba(255, 255, 255, 0.92) !important; color: #FF6F00 !important; border-color: #cccccc !important; }
|
||||
.map-pick-cell:hover { background: rgba(255, 111, 0, 0.18); outline-color: rgba(255, 111, 0, 0.7); }
|
||||
.map-place-result, .map-center-link { color: #FF6F00 !important; border-color: #cccccc !important; }
|
||||
.map-place-result:hover, .map-center-link:hover { background: #FF6F00 !important; color: #ffffff !important; border-color: #FF6F00 !important; }
|
||||
.map-picked { background: #F0F0F0 !important; color: #FF6F00 !important; }
|
||||
.map-picked-near { color: #555555 !important; }
|
||||
.map-markers-list .map-marker-row--focus { background: rgba(255, 111, 0, 0.08) !important; box-shadow: inset 3px 0 0 #FF6F00 !important; }
|
||||
.map-marker-row--focus .map-marker-idx { background: #FF6F00 !important; color: #ffffff !important; }
|
||||
.map-marker-label { color: #E65100 !important; }
|
||||
.map-marker-date { color: #777777 !important; }
|
||||
.map-marker-coords { color: #222222 !important; }
|
||||
.map-popup-pointer { fill: #ffffff; stroke: #cccccc; }
|
||||
.map-stage .map-popup-card { background: #ffffff !important; border: 1px solid #cccccc !important; color: #222222; }
|
||||
.map-stage .map-popup-text { color: #333333; }
|
||||
.map-popup-coords { color: #222222; }
|
||||
.map-stage .map-popup-meta { color: #777777; }
|
||||
.map-popup-close { color: #777777; }
|
||||
.map-popup-close:hover { color: #FF6F00; }
|
||||
.oasis-pager-info { color: #888888; }
|
||||
.oasis-pager-btn { background: #FFFFFF; color: #555555 !important; border: 1px solid #E0E0E0; text-decoration: none !important; }
|
||||
.oasis-pager-btn:hover, .oasis-pager-btn.active { border-color: #2C2C2C; color: #2C2C2C !important; text-decoration: none !important; }
|
||||
|
|
|
|||
|
|
@ -210,24 +210,9 @@ footer a:hover {
|
|||
gap: 9px;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link {
|
||||
text-decoration: none;
|
||||
color: #181818;
|
||||
background: #FFD600;
|
||||
padding: 5px 13px 4px 13px;
|
||||
border-radius: 7px;
|
||||
font-size: .98em;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link:hover {
|
||||
background: #ffe86a;
|
||||
color: #111;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link {
|
||||
a.user-link, button.user-link {
|
||||
background-color: #FFA500;
|
||||
color: #000;
|
||||
padding: 8px 16px;
|
||||
|
|
@ -241,14 +226,14 @@ a.user-link {
|
|||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
a.user-link:hover {
|
||||
a.user-link:hover, button.user-link:hover {
|
||||
background-color: #FFD700;
|
||||
border-color: #FFD700;
|
||||
color: #000;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link:focus {
|
||||
a.user-link:focus, button.user-link:focus {
|
||||
background-color: #007B9F;
|
||||
border-color: #007B9F;
|
||||
color: #fff;
|
||||
|
|
@ -316,7 +301,7 @@ a.user-link:focus {
|
|||
.stats-kpi-value { color: #FFD700 !important; }
|
||||
.carbon-bar-note, .carbon-bar-formula { color: #FFD700 !important; }
|
||||
.graphos-node-label { fill: #ddd !important; }
|
||||
.graphos-node-label-me { fill: #ffa500 !important; }
|
||||
.graphos-node-label-me { fill: #5dade2 !important; }
|
||||
.graphos-legend { color: #ddd !important; }
|
||||
.blockchain-view { background-color: #191b20 !important; color: #FFD700 !important; }
|
||||
.block { background: #23242a !important; }
|
||||
|
|
@ -333,6 +318,8 @@ a.user-link:focus {
|
|||
.btn-singleview:hover { background: #2d2e34 !important; color: #FFD700 !important; }
|
||||
.btn-spread-on, .content-actions .btn-pin-on { background: #ffa300 !important; color: #000000 !important; }
|
||||
.btn-spread-on:hover, .content-actions .btn-pin-on:hover { background: #ffb733 !important; color: #000000 !important; }
|
||||
.content-actions .btn-singleview.btn-content { border: 1px solid #ffa300 !important; }
|
||||
.content-actions .btn-singleview.btn-content:hover { background: rgba(255, 163, 0, .18) !important; border-color: #ffa300 !important; }
|
||||
.btn-back { background: #21232b !important; color: #ffa300 !important; }
|
||||
.btn-back:hover { background: #292b36 !important; color: #FFD700 !important; }
|
||||
.block-info-table td, .pm-info-table td { border-color: #444 !important; }
|
||||
|
|
|
|||
|
|
@ -241,32 +241,23 @@ footer a {
|
|||
color: #00FF00;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link {
|
||||
color: #00FF00;
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link:hover {
|
||||
background: #00FF00;
|
||||
color: #000000;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link {
|
||||
a.user-link, button.user-link {
|
||||
background-color: #00FF00;
|
||||
color: #000000;
|
||||
border-color: #00FF00;
|
||||
transition: background-color 0.3s, color 0.3s, border-color 0.3s;
|
||||
}
|
||||
|
||||
a.user-link:hover {
|
||||
a.user-link:hover, button.user-link:hover {
|
||||
background-color: #000000;
|
||||
border-color: #00FF00;
|
||||
color: #00FF00;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link:focus {
|
||||
a.user-link:focus, button.user-link:focus {
|
||||
background-color: #00FF00;
|
||||
border-color: #00FF00;
|
||||
color: #000000;
|
||||
|
|
@ -310,7 +301,7 @@ a.user-link:focus {
|
|||
.stats-kpi-value { color: #00FF00 !important; }
|
||||
.carbon-bar-note, .carbon-bar-formula { color: #00FF00 !important; }
|
||||
.graphos-node-label { fill: #00FF00 !important; }
|
||||
.graphos-node-label-me { fill: #ffa500 !important; font-weight: bold !important; }
|
||||
.graphos-node-label-me { fill: #5dade2 !important; font-weight: bold !important; }
|
||||
.graphos-legend { color: #00FF00 !important; }
|
||||
.graphos-edge { stroke: #003300 !important; }
|
||||
/* Blockexplorer */
|
||||
|
|
@ -329,6 +320,8 @@ a.user-link:focus {
|
|||
.btn-singleview:hover { background: #00FF00 !important; color: #000000 !important; }
|
||||
.btn-spread-on, .content-actions .btn-pin-on { background: #00FF00 !important; color: #000000 !important; }
|
||||
.btn-spread-on:hover, .content-actions .btn-pin-on:hover { background: #66FF66 !important; color: #000000 !important; }
|
||||
.content-actions .btn-singleview.btn-content { border: 1px solid #00FF00 !important; }
|
||||
.content-actions .btn-singleview.btn-content:hover { background: rgba(0, 255, 0, .18) !important; border-color: #00FF00 !important; }
|
||||
.btn-back { background: #000000 !important; color: #00FF00 !important; border: 1px solid #00FF00 !important; }
|
||||
.btn-back:hover { background: #00FF00 !important; color: #000000 !important; }
|
||||
.block-info-table td, .pm-info-table td { border-color: #00FF00 !important; }
|
||||
|
|
@ -379,4 +372,47 @@ nav, .sidebar-left nav, .sidebar-right nav, .sidebar-left ul, .sidebar-right ul
|
|||
.ai-nav-result-card a { color: #00FF00 !important; }
|
||||
.ai-nav-result-card a:hover { background: #00FF00 !important; color: #000000 !important; }
|
||||
.ai-nav-query { color: #00FF00 !important; }
|
||||
.trending-card.own-content { box-shadow: inset 3px 0 0 #00FF00; }
|
||||
.trending-card.own-content, .addr-card.ubi-pub-card.own-content { box-shadow: inset 3px 0 0 #00FF00; }
|
||||
.map-stage { background: #000000 !important; border-color: #00FF00 !important; }
|
||||
.map-label-country { fill: #00FF00; stroke: #000000; }
|
||||
.map-place-dot { fill: #00FF00; stroke: #000000; }
|
||||
.map-place-capital { fill: #66FF66; }
|
||||
.map-place-label { fill: #00FF00; stroke: #000000; }
|
||||
.map-pin-body { fill: #00aa00; stroke: #00FF00; }
|
||||
.map-pin-main .map-pin-body { fill: #00FF00; stroke: #000000; }
|
||||
.map-pin-focus .map-pin-body { fill: #ffffff; stroke: #00FF00; }
|
||||
.map-pin-eye { fill: #000000; }
|
||||
.map-pin-label-bg { fill: rgba(0, 0, 0, 0.9); stroke: #00FF00; }
|
||||
.map-pin-focus .map-pin-label-bg { stroke: #ffffff; }
|
||||
.map-pin-label { fill: #00FF00; }
|
||||
.map-pins-layer a:hover .map-pin-body, .map-pins a:hover .map-pin-body { fill: #ffffff; }
|
||||
.map-cluster-ring { fill: rgba(0, 255, 0, 0.25); }
|
||||
.map-cluster-dot { fill: #00FF00; stroke: #000000; }
|
||||
.map-pick-ring, .map-pick-cross { stroke: #00FF00; }
|
||||
.map-scale-line { stroke: #00FF00; }
|
||||
.map-scale-text { fill: #00FF00; stroke: #000000; }
|
||||
.map-attrib { fill: #008800; }
|
||||
.map-ctrl { background: rgba(0, 0, 0, 0.9) !important; color: #00FF00 !important; border-color: #00FF00 !important; }
|
||||
.map-ctrl:hover { background: #00FF00 !important; color: #000000 !important; }
|
||||
.map-ctrl-off:hover { background: rgba(0, 0, 0, 0.9) !important; color: #00FF00 !important; }
|
||||
.map-pick-cell:hover { background: rgba(0, 255, 0, 0.18); outline-color: rgba(0, 255, 0, 0.7); }
|
||||
.map-place-result, .map-center-link { color: #00FF00 !important; border-color: #00FF00 !important; }
|
||||
.map-place-result:hover, .map-center-link:hover { background: #00FF00 !important; color: #000000 !important; }
|
||||
.map-picked { background: #050505 !important; color: #00FF00 !important; }
|
||||
.map-picked-near { color: #00CC00 !important; }
|
||||
.map-markers-list .map-marker-row { border-color: #003300 !important; }
|
||||
.map-markers-list .map-marker-row--focus { background: rgba(0, 255, 0, 0.08) !important; box-shadow: inset 3px 0 0 #00FF00 !important; }
|
||||
.map-marker-idx { background: #004400 !important; color: #00FF00 !important; }
|
||||
.map-marker-idx--main, .map-marker-row--focus .map-marker-idx { background: #00FF00 !important; color: #000000 !important; }
|
||||
.map-marker-label { color: #00FF00 !important; }
|
||||
.map-marker-date { color: #00AA00 !important; }
|
||||
.map-popup-pointer { fill: #000000; stroke: #00FF00; }
|
||||
.map-stage .map-popup-card { background: #000000; border-color: #00FF00; color: #00FF00; }
|
||||
.map-stage .map-popup-text { color: #00FF00; }
|
||||
.map-popup-coords { color: #66FF66; }
|
||||
.map-stage .map-popup-meta { color: #00AA00; }
|
||||
.map-popup-close { color: #00AA00; }
|
||||
.map-popup-close:hover { color: #ffffff; }
|
||||
.oasis-pager-info { color: #008800; }
|
||||
.oasis-pager-btn { background: #0a0a0a; color: #00CC00; border: 1px solid #00FF00; }
|
||||
.oasis-pager-btn:hover, .oasis-pager-btn.active { border-color: #00FF00; color: #00FF00; }
|
||||
|
|
|
|||
|
|
@ -277,32 +277,23 @@ header {
|
|||
color: #B86ADE;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link {
|
||||
color: #FFFFFF;
|
||||
background: #D94F4F;
|
||||
}
|
||||
|
||||
.card-tags a.tag-link:hover {
|
||||
background: #B86ADE;
|
||||
color: #E5E5E5;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link {
|
||||
a.user-link, button.user-link {
|
||||
background-color: #FFD600;
|
||||
color: #3C1360;
|
||||
border-color: #FFD600;
|
||||
transition: background-color 0.3s, color 0.3s, border-color 0.3s;
|
||||
}
|
||||
|
||||
a.user-link:hover {
|
||||
a.user-link:hover, button.user-link:hover {
|
||||
background-color: #FFB600;
|
||||
border-color: #FFB600;
|
||||
color: #3C1360;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.user-link:focus {
|
||||
a.user-link:focus, button.user-link:focus {
|
||||
background-color: #9A2F2F;
|
||||
border-color: #9A2F2F;
|
||||
color: #E5E5E5;
|
||||
|
|
@ -346,7 +337,7 @@ a.user-link:focus {
|
|||
.stats-kpi-value { color: #FFEEDB !important; }
|
||||
.carbon-bar-note, .carbon-bar-formula { color: #FFEEDB !important; }
|
||||
.graphos-node-label { fill: #FFEEDB !important; }
|
||||
.graphos-node-label-me { fill: #ffa500 !important; }
|
||||
.graphos-node-label-me { fill: #5dade2 !important; }
|
||||
.graphos-legend { color: #FFEEDB !important; }
|
||||
/* Blockexplorer */
|
||||
.blockchain-view { background-color: #2D0B47 !important; color: #FFEEDB !important; }
|
||||
|
|
@ -364,6 +355,8 @@ a.user-link:focus {
|
|||
.btn-singleview:hover { background: #5A1A85 !important; color: #FFD600 !important; }
|
||||
.btn-spread-on, .content-actions .btn-pin-on { background: #B86ADE !important; color: #2A0E42 !important; }
|
||||
.btn-spread-on:hover, .content-actions .btn-pin-on:hover { background: #CE8CE9 !important; color: #2A0E42 !important; }
|
||||
.content-actions .btn-singleview.btn-content { border: 1px solid #B86ADE !important; }
|
||||
.content-actions .btn-singleview.btn-content:hover { background: rgba(184, 106, 222, .18) !important; border-color: #B86ADE !important; }
|
||||
.btn-back { background: #A34AD8 !important; color: #FFFFFF !important; }
|
||||
.btn-back:hover { background: #751E9F !important; color: #FFFFFF !important; }
|
||||
.block-info-table td, .pm-info-table td { border-color: #B86ADE !important; }
|
||||
|
|
@ -395,4 +388,41 @@ a.user-link:focus {
|
|||
.tribe-subtribe-link:hover { background: #5A1A85 !important; }
|
||||
.tribe-parent-image { border-color: #B86ADE !important; }
|
||||
.tribe-parent-box { background: #3C1360 !important; }
|
||||
.trending-card.own-content { box-shadow: inset 3px 0 0 #B86ADE; }
|
||||
.trending-card.own-content, .addr-card.ubi-pub-card.own-content { box-shadow: inset 3px 0 0 #B86ADE; }
|
||||
.map-stage { background: #2a0640 !important; border-color: #9B1C96 !important; }
|
||||
.map-label-country { fill: #E5E5E5; stroke: #2a0640; }
|
||||
.map-place-dot { fill: #ffffff; stroke: #2a0640; }
|
||||
.map-place-capital { fill: #B86ADE; }
|
||||
.map-place-label { fill: #E5E5E5; stroke: #2a0640; }
|
||||
.map-pin-focus .map-pin-body, .map-cluster-dot { fill: #B86ADE; }
|
||||
.map-pin-focus .map-pin-label-bg { stroke: #B86ADE; }
|
||||
.map-pins-layer a:hover .map-pin-body, .map-pins a:hover .map-pin-body { fill: #B86ADE; }
|
||||
.map-cluster-ring { fill: rgba(184, 106, 222, 0.28); }
|
||||
.map-pick-ring, .map-pick-cross { stroke: #B86ADE; }
|
||||
.map-scale-text { stroke: #2a0640; }
|
||||
.map-attrib { fill: #9B7CAA; }
|
||||
.map-ctrl { background: rgba(43, 10, 70, 0.9) !important; color: #E5E5E5 !important; border-color: #9B1C96 !important; }
|
||||
.map-ctrl:hover { background: #B86ADE !important; color: #000000 !important; border-color: #B86ADE !important; }
|
||||
.map-ctrl-off:hover { background: rgba(43, 10, 70, 0.9) !important; color: #E5E5E5 !important; border-color: #9B1C96 !important; }
|
||||
.map-pick-cell, .map-pick-cell:hover { border: 0 !important; padding: 0 !important; border-radius: 0 !important; box-shadow: none !important; }
|
||||
.map-pick-cell { background: transparent !important; }
|
||||
.map-pick-cell:hover { background: rgba(184, 106, 222, 0.22) !important; outline-color: rgba(184, 106, 222, 0.7); }
|
||||
.map-place-result, .map-center-link { color: #E5E5E5 !important; border-color: #9B1C96 !important; }
|
||||
.map-place-result:hover, .map-center-link:hover { background: #B86ADE !important; color: #000000 !important; border-color: #B86ADE !important; }
|
||||
.map-picked { background: #3C1360 !important; color: #E5E5E5 !important; }
|
||||
.map-picked-near { color: #C8C8C8 !important; }
|
||||
.map-markers-list .map-marker-row { border-color: #5A1A85 !important; }
|
||||
.map-markers-list .map-marker-row--focus { background: rgba(184, 106, 222, 0.1) !important; box-shadow: inset 3px 0 0 #B86ADE !important; }
|
||||
.map-marker-row--focus .map-marker-idx { background: #B86ADE !important; color: #000000 !important; }
|
||||
.map-marker-label { color: #B86ADE !important; }
|
||||
.map-marker-date { color: #C8C8C8 !important; }
|
||||
.map-popup-pointer { fill: #3C1360; stroke: #9B1C96; }
|
||||
.map-stage .map-popup-card { background: #3C1360; border-color: #9B1C96; color: #E5E5E5; }
|
||||
.map-stage .map-popup-text { color: #E5E5E5; }
|
||||
.map-popup-coords { color: #ffffff; }
|
||||
.map-stage .map-popup-meta { color: #C8C8C8; }
|
||||
.map-popup-close { color: #C8C8C8; }
|
||||
.map-popup-close:hover { color: #B86ADE; }
|
||||
.oasis-pager-info { color: #9B7CAA; }
|
||||
.oasis-pager-btn { background: #39006D; color: #C8C8C8; border: 1px solid #9B1C96; }
|
||||
.oasis-pager-btn:hover, .oasis-pager-btn.active { border-color: #E5E5E5; color: #E5E5E5; }
|
||||
|
|
|
|||
|
|
@ -1,15 +1,22 @@
|
|||
const path = require('path');
|
||||
let i18n = {};
|
||||
const languages = ['en', 'es', 'fr', 'eu', 'de', 'it', 'pt', 'zh', 'ar', 'hi', 'ru'];
|
||||
const i18n = {};
|
||||
const languages = ['en', 'es', 'ca', 'gl', 'fr', 'eu', 'de', 'it', 'pt', 'zh', 'ar', 'hi', 'ru'];
|
||||
|
||||
languages.forEach(language => {
|
||||
try {
|
||||
const languagePath = path.join(__dirname, `oasis_${language}.js`);
|
||||
const languageData = require(languagePath);
|
||||
i18n[language] = languageData[language];
|
||||
} catch (error) {
|
||||
console.error(`Failed to load language file for ${language}:`, error);
|
||||
}
|
||||
Object.defineProperty(i18n, language, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get() {
|
||||
let languageData;
|
||||
try {
|
||||
languageData = require(path.join(__dirname, `oasis_${language}.js`))[language];
|
||||
} catch (error) {
|
||||
console.error(`Failed to load language file for ${language}:`, error);
|
||||
}
|
||||
Object.defineProperty(i18n, language, { value: languageData, enumerable: true, configurable: true, writable: true });
|
||||
return languageData;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
|
|
|
|||
4880
src/client/assets/translations/oasis_ca.js
Normal file
4880
src/client/assets/translations/oasis_gl.js
Normal file
|
|
@ -10,10 +10,13 @@ const { printMetadata } = require('../server/ssb_metadata');
|
|||
const updateFlagPath = path.join(__dirname, "../server/.update_required");
|
||||
|
||||
let internalSSB = null;
|
||||
try {
|
||||
const { server } = require('../server/SSB_server');
|
||||
internalSSB = server;
|
||||
} catch {}
|
||||
let internalOpen = null;
|
||||
if (!process.env.OASIS_TEST) {
|
||||
try {
|
||||
const SSB_server = require('../server/SSB_server');
|
||||
internalOpen = () => SSB_server.open().then((srv) => { internalSSB = srv; return srv; });
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (process.env.OASIS_TEST) {
|
||||
ssbConfig.path = fs.mkdtempSync(path.join(os.tmpdir(), "oasis-"));
|
||||
|
|
@ -24,10 +27,33 @@ const socketPath = path.join(ssbConfig.path, "socket");
|
|||
const publicInteger = ssbConfig.keys.public.replace(".ed25519", "");
|
||||
const remote = `unix:${socketPath}~noauth:${publicInteger}`;
|
||||
|
||||
const windowLogStream = (ssb) => {
|
||||
if (!ssb || ssb._logStreamWindowed || typeof ssb.createLogStream !== "function") return ssb;
|
||||
const pull = require("../server/node_modules/pull-stream");
|
||||
const defer = require("../server/node_modules/pull-defer");
|
||||
const orig = ssb.createLogStream;
|
||||
ssb.createLogStream = function (opts) {
|
||||
const o = opts || {};
|
||||
const plain = o.limit && !o.reverse && !o.live && !o.raw && o.old === undefined && !o.gt && !o.lt;
|
||||
if (!plain) return orig.call(ssb, opts);
|
||||
const src = defer.source();
|
||||
pull(
|
||||
orig.call(ssb, { ...o, reverse: true }),
|
||||
pull.collect((err, msgs) => {
|
||||
if (err) return src.abort(err);
|
||||
src.resolve(pull.values(msgs.reverse()));
|
||||
})
|
||||
);
|
||||
return src;
|
||||
};
|
||||
ssb._logStreamWindowed = true;
|
||||
return ssb;
|
||||
};
|
||||
|
||||
const connect = (options) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ssbClient(process.env.OASIS_TEST ? ssbConfig.keys : null, options)
|
||||
.then(resolve)
|
||||
.then((ssb) => resolve(windowLogStream(ssb)))
|
||||
.catch(reject);
|
||||
});
|
||||
|
||||
|
|
@ -89,8 +115,15 @@ module.exports = ({ offline, port = 3000, host = 'localhost', isPublic = false }
|
|||
return new Promise((resolve, reject) => {
|
||||
if (internalSSB) {
|
||||
const { printMetadata, colors } = require('../server/ssb_metadata');
|
||||
printMetadata('OASIS GUI', colors.yellow, port, host, offline, isPublic);
|
||||
return resolve(internalSSB);
|
||||
printMetadata('OASIS UX', colors.yellow, port, host, offline, isPublic);
|
||||
return resolve(windowLogStream(internalSSB));
|
||||
}
|
||||
if (internalOpen) {
|
||||
return internalOpen().then((srv) => {
|
||||
const { printMetadata, colors } = require('../server/ssb_metadata');
|
||||
printMetadata('OASIS UX', colors.yellow, port, host, offline, isPublic);
|
||||
resolve(windowLogStream(srv));
|
||||
}).catch(reject);
|
||||
}
|
||||
|
||||
if (clientHandle && clientHandle.closed === false) {
|
||||
|
|
@ -105,7 +138,7 @@ module.exports = ({ offline, port = 3000, host = 'localhost', isPublic = false }
|
|||
reject(new Error("Closing Oasis"));
|
||||
} else {
|
||||
const { printMetadata, colors } = require('../server/ssb_metadata');
|
||||
printMetadata('OASIS GUI', colors.yellow, port, host, offline, isPublic);
|
||||
printMetadata('OASIS UX', colors.yellow, port, host, offline, isPublic);
|
||||
resolve(ssb);
|
||||
}
|
||||
}).catch(reject);
|
||||
|
|
|
|||
|
|
@ -8,20 +8,21 @@ const mount = require(path.join(__dirname, "../server/node_modules/koa-mount"));
|
|||
function obfuscateClearnetHtml(html) {
|
||||
if (typeof html !== 'string' || html.length === 0) return html;
|
||||
const preserve = [];
|
||||
const tag = require('crypto').randomBytes(12).toString('hex');
|
||||
const stash = (re) => {
|
||||
html = html.replace(re, (m) => {
|
||||
preserve.push(m);
|
||||
return `${preserve.length - 1}`;
|
||||
return `\u0001${tag}:${preserve.length - 1}\u0001`;
|
||||
});
|
||||
};
|
||||
stash(/<pre[\s\S]*?<\/pre>/gi);
|
||||
stash(/<textarea[\s\S]*?<\/textarea>/gi);
|
||||
stash(/<style[\s\S]*?<\/style>/gi);
|
||||
html = html.replace(/<!--[\s\S]*?-->/g, '');
|
||||
html = html.replace(/>[\s\n\r\t]+</g, '><');
|
||||
html = html.replace(/>[ \t]*[\r\n][\s]*</g, '><');
|
||||
html = html.replace(/[ \t]{2,}/g, ' ');
|
||||
html = html.replace(/[\r\n]+/g, '');
|
||||
html = html.replace(/(\d+)/g, (_, i) => preserve[Number(i)] || '');
|
||||
html = html.replace(new RegExp(`\\u0001${tag}:(\\d+)\\u0001`, 'g'), (_, i) => preserve[Number(i)] || '');
|
||||
return html;
|
||||
}
|
||||
|
||||
|
|
@ -42,42 +43,17 @@ const collectLocalIPs = () => {
|
|||
|
||||
module.exports = ({ host, port, middleware, allowHost }) => {
|
||||
const assets = new Koa()
|
||||
assets.use(koaStatic(join(__dirname, "..", "client", "assets"), { maxage: 60 * 60 * 1000 }));
|
||||
assets.use(async (ctx, next) => {
|
||||
ctx.set("Cache-Control", ctx.query && ctx.query.v ? "public, max-age=31536000, immutable" : "public, max-age=3600");
|
||||
await next();
|
||||
});
|
||||
assets.use(koaStatic(join(__dirname, "..", "client", "assets")));
|
||||
|
||||
const app = new Koa();
|
||||
const validHosts = [];
|
||||
|
||||
const isClearnetPath = (request) => {
|
||||
const url = String(request.url || '');
|
||||
return url === '/c' || url.startsWith('/c/') || url.startsWith('/c?');
|
||||
};
|
||||
|
||||
const isValidRequest = (request) => {
|
||||
if (isClearnetPath(request)) return request.method === 'GET';
|
||||
if (validHosts.includes(request.hostname) !== true) {
|
||||
return false;
|
||||
}
|
||||
if (request.method !== "GET") {
|
||||
if (request.header.referer == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const refererUrl = new URL(request.header.referer);
|
||||
if (validHosts.includes(refererUrl.hostname) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (refererUrl.pathname.startsWith("/blob/")) {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
const { isClearnetPath, isTrustedRequest, buildCsp } = require(path.join(__dirname, "..", "backend", "request_guards"));
|
||||
const isValidRequest = (request) => isTrustedRequest(request, validHosts);
|
||||
|
||||
const httpDebug = process.argv.includes('--debug') || process.env.OASIS_DEBUG === '1' || process.env.OASIS_DEBUG === 'true';
|
||||
|
||||
|
|
@ -98,17 +74,21 @@ module.exports = ({ host, port, middleware, allowHost }) => {
|
|||
});
|
||||
|
||||
app.use(mount("/assets", assets));
|
||||
app.use(mount("/c/assets", assets));
|
||||
|
||||
const maptiles = new Koa();
|
||||
maptiles.use(koaStatic(join(__dirname, "..", "maps", "tiles")));
|
||||
app.use(mount("/maptiles", maptiles));
|
||||
|
||||
const mapcache = new Koa();
|
||||
mapcache.use(koaStatic(join(__dirname, "..", "maps", "cache")));
|
||||
app.use(mount("/mapcache", mapcache));
|
||||
|
||||
const mapTiles = new Koa();
|
||||
mapTiles.use(koaStatic(join(__dirname, "..", "maps", "tiles"), { maxage: 30 * 24 * 60 * 60 * 1000, immutable: true }));
|
||||
app.use(mount("/maptiles", mapTiles));
|
||||
app.use(mount("/c/maptiles", mapTiles));
|
||||
|
||||
const gamesStatic = new Koa();
|
||||
gamesStatic.use(async (ctx, next) => {
|
||||
ctx.set("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' data: blob: mediastream:; connect-src 'none'; form-action 'none'; base-uri 'none'; object-src 'none'; frame-ancestors 'self'");
|
||||
ctx.set("X-Content-Type-Options", "nosniff");
|
||||
ctx.set("X-Frame-Options", "SAMEORIGIN");
|
||||
ctx.set("Referrer-Policy", "same-origin");
|
||||
await next();
|
||||
});
|
||||
gamesStatic.use(koaStatic(join(__dirname, "..", "games")));
|
||||
app.use(mount("/game-assets", gamesStatic));
|
||||
|
||||
|
|
@ -120,34 +100,7 @@ module.exports = ({ host, port, middleware, allowHost }) => {
|
|||
if (httpDebug) console.log(`[http] ${ctx.method} ${ctx.path}`);
|
||||
|
||||
const isClearnet = isClearnetPath(ctx.request);
|
||||
const csp = isClearnet
|
||||
? [
|
||||
"default-src 'self'",
|
||||
"script-src 'none'",
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data:",
|
||||
"media-src 'self' blob:",
|
||||
"connect-src 'self'",
|
||||
"form-action 'self'",
|
||||
"object-src 'none'",
|
||||
"base-uri 'none'",
|
||||
"frame-ancestors 'none'"
|
||||
].join("; ")
|
||||
: [
|
||||
"default-src 'self'",
|
||||
"script-src 'self' http://localhost:3000/js",
|
||||
"style-src 'self'",
|
||||
"img-src 'self'",
|
||||
"media-src 'self' blob:",
|
||||
"worker-src 'self' blob:",
|
||||
"frame-src 'self'",
|
||||
"form-action 'self'",
|
||||
"object-src 'none'",
|
||||
"base-uri 'none'",
|
||||
"frame-ancestors 'none'"
|
||||
].join("; ");
|
||||
|
||||
ctx.set("Content-Security-Policy", csp);
|
||||
ctx.set("Content-Security-Policy", buildCsp(isClearnet, { frames: ctx.method === "GET" && /^\/games\/[a-z0-9]+\/?$/.test(ctx.path) }));
|
||||
ctx.set("X-Frame-Options", "SAMEORIGIN");
|
||||
|
||||
ctx.set("X-Content-Type-Options", "nosniff");
|
||||
|
|
@ -155,12 +108,10 @@ module.exports = ({ host, port, middleware, allowHost }) => {
|
|||
ctx.set("Referrer-Policy", "same-origin");
|
||||
ctx.set("Permissions-Policy", "speaker=(self)");
|
||||
|
||||
const validHostsString = validHosts.join(" or ");
|
||||
|
||||
ctx.assert(
|
||||
isValidRequest(ctx.request),
|
||||
400,
|
||||
`Request must be addressed to ${validHostsString} and non-GET requests must contain non-blob referer.`
|
||||
"Request must be addressed to this node and non-GET requests must come from its own pages."
|
||||
);
|
||||
|
||||
await next();
|
||||
|
|
@ -173,13 +124,10 @@ module.exports = ({ host, port, middleware, allowHost }) => {
|
|||
}
|
||||
});
|
||||
|
||||
// pdf viewer
|
||||
const pdfjsPath = path.join(__dirname, '../server/node_modules/pdfjs-dist/build/pdf.min.js');
|
||||
app.use(koaStatic(pdfjsPath));
|
||||
|
||||
middleware.forEach((m) => app.use(m));
|
||||
|
||||
const server = app.listen({ host, port });
|
||||
const server = require("http").createServer({ maxHeaderSize: 256 * 1024 }, app.callback()).listen({ host, port });
|
||||
|
||||
|
||||
server.on("listening", () => {
|
||||
const address = server.address();
|
||||
|
|
|
|||
|
|
@ -1,115 +0,0 @@
|
|||
|
||||
ECOin - Copyright (c) - 2014/2025 - GPLv3 - epsylon@riseup.net (https://ecoin.03c8.net)
|
||||
|
||||
===========================================
|
||||
# SOURCES for P2P Crypto-Currency (ECOin) #
|
||||
===========================================
|
||||
|
||||
Testing machine is: Debian GNU/Linux 12 (bookworm) (x86_64).
|
||||
|
||||
All of the commands should be executed in a shell.
|
||||
|
||||
------------------------------
|
||||
|
||||
(0.) Clone the github tree to get the source code:
|
||||
|
||||
+ Official:
|
||||
|
||||
git clone http://code.03c8.net/epsylon/ecoin
|
||||
|
||||
+ Mirror:
|
||||
|
||||
git clone https://github.com/epsylon/ecoin
|
||||
|
||||
------------------------------
|
||||
|
||||
===================================================
|
||||
# SERVER -ecoind- for P2P Crypto-Currency (ECOin) #
|
||||
===================================================
|
||||
|
||||
(0.) Version libraries:
|
||||
|
||||
- Libboost -> source code 1.68 provided at: src/boost_1_68_0
|
||||
|
||||
(1.) Install dependencies:
|
||||
|
||||
sudo apt-get install build-essential libssl-dev libssl3 libdb5.3-dev libdb5.3++-dev libleveldb-dev miniupnpc libminiupnpc-dev
|
||||
|
||||
+ Optionally install qrencode (and set USE_QRCODE=1):
|
||||
|
||||
sudo apt-get install libqrencode-dev
|
||||
|
||||
(2.) Now you should be able to build ecoind:
|
||||
|
||||
cd src/
|
||||
make -f makefile.linux USE_UPNP=- USE_IPV6=-
|
||||
strip ecoind
|
||||
|
||||
An executable named 'ecoind' will be built.
|
||||
|
||||
Now you can launch: ./ecoind to run your ECOin server.
|
||||
|
||||
------------------------------
|
||||
|
||||
============================================
|
||||
# WALLET for P2P Crypto-Currency (ECOin) #
|
||||
============================================
|
||||
|
||||
(0.) Version libraries:
|
||||
|
||||
- Libboost -> source code 1.68 provided at: src/boost_1_68_0
|
||||
|
||||
(1.) First, make sure that the required packages for Qt5 development (an the others required for building the daemon) are installed:
|
||||
|
||||
sudo apt-get install qt5-qmake qtbase5-dev build-essential libssl-dev libssl3 libdb5.3-dev libdb5.3++-dev libleveldb-dev miniupnpc libminiupnpc-dev
|
||||
|
||||
+ Optionally install qrencode (and set USE_QRCODE=1):
|
||||
|
||||
sudo apt-get install libqrencode-dev
|
||||
|
||||
(2.) Then execute the following:
|
||||
|
||||
qmake USE_UPNP=- USE_IPV6=-
|
||||
make
|
||||
|
||||
An executable named 'ecoin-qt' will be built.
|
||||
|
||||
Now you can launch: ./ecoin-qt to run your ECOin wallet/GUI.
|
||||
|
||||
------------------------------
|
||||
========================================
|
||||
+ CPU MINER for ECOin (Unix/GNU-Linux) #
|
||||
========================================
|
||||
|
||||
See doc/MINING.txt for detailed instructions on running /ecoin-miner/ on different platforms.
|
||||
|
||||
+ GNU/Linux:
|
||||
|
||||
cd miner/
|
||||
sh build.sh
|
||||
|
||||
An executable named 'cpuminer' will be built.
|
||||
|
||||
Now you can launch: ./cpuminer to run your ECOin PoW miner.
|
||||
|
||||
======================================
|
||||
|
||||
For a list of command-line options:
|
||||
|
||||
./ecoind --help
|
||||
|
||||
To start the ECOin daemon:
|
||||
|
||||
./ecoind -daemon
|
||||
|
||||
For ECOin-QT Wallet
|
||||
|
||||
./ecoin-qt
|
||||
|
||||
For debugging:
|
||||
|
||||
tail -f /home/$USER/.ecoin/debug.log
|
||||
|
||||
======================================
|
||||
|
||||
|
||||
|
|
@ -1,32 +1,68 @@
|
|||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (typeof pdfjsLib === 'undefined') return;
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = '/js/pdf.worker.min.mjs';
|
||||
const showPdfFallback = () => {
|
||||
document.querySelectorAll('.pdf-viewer-container').forEach(container => {
|
||||
if (container.dataset.pdfReady) return;
|
||||
container.dataset.pdfReady = '1';
|
||||
container.textContent = '';
|
||||
const url = container.getAttribute('data-pdf-url');
|
||||
if (url) {
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.textContent = '📄 PDF';
|
||||
container.appendChild(link);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const initPdfViewers = async () => {
|
||||
let pdfjsLib;
|
||||
try {
|
||||
pdfjsLib = await import('/js/pdf.min.mjs?v=102');
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = '/js/pdf.worker.min.mjs?v=102';
|
||||
} catch (err) {
|
||||
showPdfFallback();
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelectorAll('.pdf-viewer-container').forEach(async container => {
|
||||
const pdfUrl = container.getAttribute('data-pdf-url');
|
||||
if (!pdfUrl) return;
|
||||
if (!pdfUrl || container.dataset.pdfReady) return;
|
||||
container.dataset.pdfReady = '1';
|
||||
|
||||
let pdf;
|
||||
try {
|
||||
pdf = await pdfjsLib.getDocument(pdfUrl).promise;
|
||||
} catch (err) {
|
||||
container.textContent = '';
|
||||
const fallback = document.createElement('a');
|
||||
fallback.href = pdfUrl;
|
||||
fallback.textContent = '📄 PDF';
|
||||
container.appendChild(fallback);
|
||||
return;
|
||||
}
|
||||
|
||||
const pdf = await pdfjsLib.getDocument(pdfUrl).promise;
|
||||
let currentPage = 1;
|
||||
let scale = 1.5;
|
||||
let rotation = 0;
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const canvasWrap = document.createElement('div');
|
||||
canvasWrap.className = 'pdf-canvas-wrap';
|
||||
canvasWrap.appendChild(canvas);
|
||||
container.innerHTML = '';
|
||||
container.appendChild(canvas);
|
||||
container.appendChild(canvasWrap);
|
||||
|
||||
const controls = document.createElement('div');
|
||||
controls.className = 'pdf-controls';
|
||||
controls.innerHTML = `
|
||||
<button id="prev">⬅️</button>
|
||||
<button id="next">➡️</button>
|
||||
<button id="zoomIn">🔍+</button>
|
||||
<button id="zoomOut">🔍−</button>
|
||||
<button id="rotate">↻</button>
|
||||
<button id="download">⬇️</button>
|
||||
<button id="fullscreen">🔲</button>
|
||||
<button id="metadata">ℹ️</button>
|
||||
<button class="pdf-prev">⬅️</button>
|
||||
<button class="pdf-next">➡️</button>
|
||||
<button class="pdf-zoom-in">🔍+</button>
|
||||
<button class="pdf-zoom-out">🔍−</button>
|
||||
<button class="pdf-rotate">↻</button>
|
||||
<button class="pdf-download">⬇️</button>
|
||||
<button class="pdf-fullscreen">🔲</button>
|
||||
<button class="pdf-metadata">ℹ️</button>
|
||||
`;
|
||||
|
||||
container.appendChild(controls);
|
||||
|
|
@ -48,29 +84,48 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const firstPage = await pdf.getPage(1);
|
||||
const baseViewport = firstPage.getViewport({ scale: 1, rotation: 0 });
|
||||
const avail = canvasWrap.clientWidth || container.clientWidth;
|
||||
if (avail > 0 && baseViewport.width > 0) {
|
||||
scale = Math.min(1.5, Math.max(0.5, (avail - 40) / baseViewport.width));
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
renderPage(currentPage);
|
||||
|
||||
controls.querySelector('#prev').onclick = () => goToPage(-1);
|
||||
controls.querySelector('#next').onclick = () => goToPage(1);
|
||||
controls.querySelector('#zoomIn').onclick = () => { scale += 0.2; renderPage(currentPage); };
|
||||
controls.querySelector('#zoomOut').onclick = () => { scale = Math.max(0.5, scale - 0.2); renderPage(currentPage); };
|
||||
controls.querySelector('#rotate').onclick = () => { rotation = (rotation + 90) % 360; renderPage(currentPage); };
|
||||
controls.querySelector('#download').onclick = () => {
|
||||
controls.querySelector('.pdf-prev').onclick = () => goToPage(-1);
|
||||
controls.querySelector('.pdf-next').onclick = () => goToPage(1);
|
||||
controls.querySelector('.pdf-zoom-in').onclick = () => { scale += 0.2; renderPage(currentPage); };
|
||||
controls.querySelector('.pdf-zoom-out').onclick = () => { scale = Math.max(0.5, scale - 0.2); renderPage(currentPage); };
|
||||
controls.querySelector('.pdf-rotate').onclick = () => { rotation = (rotation + 90) % 360; renderPage(currentPage); };
|
||||
controls.querySelector('.pdf-download').onclick = () => {
|
||||
const a = document.createElement('a');
|
||||
a.href = pdfUrl;
|
||||
a.download = 'document.pdf';
|
||||
a.click();
|
||||
};
|
||||
controls.querySelector('#fullscreen').onclick = () => {
|
||||
if (canvas.requestFullscreen) canvas.requestFullscreen();
|
||||
else if (canvas.webkitRequestFullscreen) canvas.webkitRequestFullscreen();
|
||||
else if (canvas.mozRequestFullScreen) canvas.mozRequestFullScreen();
|
||||
else if (canvas.msRequestFullscreen) canvas.msRequestFullscreen();
|
||||
controls.querySelector('.pdf-fullscreen').onclick = async () => {
|
||||
const maximized = container.classList.toggle('pdf-maximized');
|
||||
document.body.classList.toggle('pdf-maximized-body', maximized);
|
||||
try {
|
||||
const p1 = await pdf.getPage(currentPage);
|
||||
const vw1 = p1.getViewport({ scale: 1, rotation });
|
||||
const avail = Math.max(260, (maximized ? window.innerWidth : (canvasWrap.clientWidth || container.clientWidth || 360)) - 24);
|
||||
scale = maximized ? avail / vw1.width : Math.min(1.5, avail / vw1.width);
|
||||
await renderPage(currentPage);
|
||||
} catch (_) {}
|
||||
};
|
||||
controls.querySelector('#metadata').onclick = async () => {
|
||||
controls.querySelector('.pdf-metadata').onclick = async () => {
|
||||
const info = await pdf.getMetadata();
|
||||
alert(`Title: ${info.info.Title || 'N/A'}\nAuthor: ${info.info.Author || 'N/A'}\nPDF Producer: ${info.info.Producer || 'N/A'}`);
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initPdfViewers);
|
||||
} else {
|
||||
initPdfViewers();
|
||||
}
|
||||
|
|
|
|||