├── src ├── views │ ├── ui │ │ ├── vendors │ │ │ ├── vendor │ │ │ │ ├── vendor.css │ │ │ │ └── vendor.ts │ │ │ ├── vendors.ts │ │ │ └── vendors.css │ │ ├── copyright │ │ │ ├── copyright.css │ │ │ └── copyright.ts │ │ ├── titles │ │ │ ├── page-title │ │ │ │ ├── page-title.css │ │ │ │ └── page-title.ts │ │ │ └── paragraph-title │ │ │ │ ├── paragraph-title.css │ │ │ │ └── paragraph-title.ts │ │ ├── socs │ │ │ ├── socs.css │ │ │ ├── socs.ts │ │ │ └── soc │ │ │ │ ├── soc.css │ │ │ │ └── soc.ts │ │ ├── links │ │ │ ├── introduction-main-links │ │ │ │ ├── introduction-main-link.ts │ │ │ │ └── introduction-main-link.css │ │ │ └── header-link │ │ │ │ ├── header-link.ts │ │ │ │ └── header-link.css │ │ ├── buttons │ │ │ ├── burger-button │ │ │ │ ├── burger-button.css │ │ │ │ └── burger-button.ts │ │ │ ├── header-button │ │ │ │ ├── header-button.ts │ │ │ │ └── header-button.css │ │ │ └── solid-button │ │ │ │ ├── solid-button.ts │ │ │ │ └── solid-button.css │ │ ├── calc-msg │ │ │ ├── calc-msg.ts │ │ │ └── calc-msg.css │ │ ├── socs-mobile │ │ │ ├── socs-mobile.css │ │ │ ├── socs-mobile.ts │ │ │ └── soc-mobile │ │ │ │ ├── soc-mobile.css │ │ │ │ └── soc-mobile.ts │ │ ├── project-item │ │ │ ├── project-item.css │ │ │ └── project-item.ts │ │ ├── socials │ │ │ ├── socials.ts │ │ │ └── socials.css │ │ ├── parag-link │ │ │ └── parag-link.ts │ │ ├── chat-banner │ │ │ ├── chat-banner.ts │ │ │ └── chat-banner.css │ │ ├── column-titles │ │ │ ├── column-titles.ts │ │ │ └── column-titles.css │ │ ├── letters │ │ │ ├── letters.ts │ │ │ └── letters.css │ │ ├── donate-banner │ │ │ ├── donate-banner.ts │ │ │ └── donate-banner.css │ │ ├── calc-partit-chart │ │ │ ├── calc-partit-chart.css │ │ │ └── calc-partit-chart.ts │ │ ├── team-card │ │ │ ├── team-card.ts │ │ │ └── team-card.css │ │ └── calc-table │ │ │ ├── calc-table.css │ │ │ └── calc-table.ts │ ├── content │ │ ├── introduction │ │ │ ├── supporters │ │ │ │ ├── supporters.css │ │ │ │ ├── supporters.ts │ │ │ │ └── supporters-list │ │ │ │ │ ├── supporters-list.ts │ │ │ │ │ └── supporters-list.css │ │ │ ├── alliance │ │ │ │ ├── alliance.css │ │ │ │ └── alliance.ts │ │ │ ├── introduction.css │ │ │ └── introduction.ts │ │ ├── supported-hardware │ │ │ ├── supported-hardware.css │ │ │ └── supported-hardware.ts │ │ ├── firmware-partition-calculator │ │ │ ├── firmware-partition-calculator.css │ │ │ └── firmware-partition-caclucator.ts │ │ ├── our-channels │ │ │ ├── our-channels.css │ │ │ └── our-channels.ts │ │ ├── our-team │ │ │ ├── our-team.css │ │ │ └── our-team.ts │ │ ├── our-projects │ │ │ ├── our-projects.css │ │ │ └── our-projects.ts │ │ └── support-open-source │ │ │ ├── support-open-source.css │ │ │ └── support-open-source.ts │ └── layout │ │ ├── main │ │ ├── main.css │ │ └── main.ts │ │ ├── layout.ts │ │ ├── header │ │ ├── mobile-dropdown │ │ │ ├── mobile-dropdown.ts │ │ │ └── mobile-dropdown.css │ │ ├── dropdown │ │ │ ├── dropdown.ts │ │ │ └── dropdown.css │ │ ├── mobile-routes │ │ │ └── mobile-routes.ts │ │ ├── header.css │ │ └── header.ts │ │ └── footer │ │ ├── footer.ts │ │ └── footer.css ├── shared │ ├── constants │ │ ├── breakpoints.js │ │ ├── supported-hardware │ │ │ ├── vendors.ts │ │ │ └── socs.ts │ │ ├── footer.ts │ │ ├── our-team │ │ │ ├── texts.ts │ │ │ └── team.ts │ │ ├── socials.ts │ │ ├── main-nav-list.ts │ │ ├── titles.ts │ │ ├── supporters.ts │ │ ├── support-open-source │ │ │ └── texts.ts │ │ ├── our-channels │ │ │ └── our-channels.ts │ │ ├── texts.ts │ │ └── our-projects │ │ │ └── our-projects.ts │ ├── icons │ │ ├── supporters │ │ │ ├── osc_mini.png │ │ │ ├── vtl_mini.png │ │ │ ├── dozor_mini.png │ │ │ ├── gain_mini.png │ │ │ ├── ipeye_mini.png │ │ │ ├── yucca_mini.png │ │ │ ├── dvor24_mini.png │ │ │ ├── goodcam_mini.png │ │ │ ├── megacam_mini.png │ │ │ ├── s-video_mini.png │ │ │ ├── skycam_mini.png │ │ │ ├── sputnik_mini.png │ │ │ ├── ufanet_mini.png │ │ │ ├── vixand_mini.png │ │ │ ├── keytelecom_mini.png │ │ │ ├── mywifi-cc_mini.png │ │ │ ├── webglazok_mini.png │ │ │ ├── alarmsystem_mini.png │ │ │ ├── lifecontrol_mini.png │ │ │ ├── linuxchenxing_mini.png │ │ │ ├── techno-shield_mini.png │ │ │ └── binary-machines_mini.png │ │ ├── alliance │ │ │ ├── index.ts │ │ │ ├── openipc.svg │ │ │ └── majestic.svg │ │ ├── triangle.svg │ │ ├── burger.svg │ │ ├── index.ts │ │ ├── socials.ts │ │ ├── socs-info │ │ │ ├── grey-frame.svg │ │ │ ├── socs-icons.ts │ │ │ ├── blue-arrow-frame.svg │ │ │ ├── done.svg │ │ │ ├── hlp.svg │ │ │ ├── mvp.svg │ │ │ ├── neq.svg │ │ │ ├── rnd.svg │ │ │ ├── wip.svg │ │ │ └── blue-info-frame.svg │ │ ├── twitter.svg │ │ ├── opencollective.svg │ │ ├── gitter.svg │ │ ├── telegram.svg │ │ ├── youtube.svg │ │ └── github.svg │ ├── styles │ │ ├── global.css │ │ ├── palette.css │ │ └── fonts.css │ ├── utils │ │ └── parag-links.ts │ └── images │ │ └── logo.svg └── index.ts ├── babel.config.json ├── yarnrc.yml ├── public ├── supporters │ ├── osc_mini.png │ ├── vtl_mini.png │ ├── dozor_mini.png │ ├── gain_mini.png │ ├── ipeye_mini.png │ ├── yucca_mini.png │ ├── dvor24_mini.png │ ├── goodcam_mini.png │ ├── megacam_mini.png │ ├── s-video_mini.png │ ├── skycam_mini.png │ ├── sputnik_mini.png │ ├── ufanet_mini.png │ ├── vixand_mini.png │ ├── keytelecom_mini.png │ ├── mywifi-cc_mini.png │ ├── webglazok_mini.png │ ├── alarmsystem_mini.png │ ├── lifecontrol_mini.png │ ├── linuxchenxing_mini.png │ ├── techno-shield_mini.png │ └── binary-machines_mini.png ├── fonts │ ├── IBMPlexSans-Bold.woff2 │ ├── IBMPlexSans-Regular.woff2 │ ├── IBMPlexSans-SemiBold.woff2 │ └── share-tech-mono-v15-latin-regular.woff2 └── index.html ├── .yarnrc.yml_temp ├── decs.d.ts ├── netlify.toml ├── .gitignore ├── tsconfig.json ├── postcss.config.js ├── .github └── workflows │ └── build.yml ├── LICENSE ├── package.json ├── webpack.config.js └── README.md /src/views/ui/vendors/vendor/vendor.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | enableGlobalCache: false 3 | -------------------------------------------------------------------------------- /src/views/ui/copyright/copyright.css: -------------------------------------------------------------------------------- 1 | .copyright { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | -------------------------------------------------------------------------------- /public/supporters/osc_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/osc_mini.png -------------------------------------------------------------------------------- /public/supporters/vtl_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/vtl_mini.png -------------------------------------------------------------------------------- /src/shared/constants/breakpoints.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mobile: '728px', 3 | desktop: '1440px', 4 | }; 5 | -------------------------------------------------------------------------------- /public/supporters/dozor_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/dozor_mini.png -------------------------------------------------------------------------------- /public/supporters/gain_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/gain_mini.png -------------------------------------------------------------------------------- /public/supporters/ipeye_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/ipeye_mini.png -------------------------------------------------------------------------------- /public/supporters/yucca_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/yucca_mini.png -------------------------------------------------------------------------------- /public/fonts/IBMPlexSans-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/fonts/IBMPlexSans-Bold.woff2 -------------------------------------------------------------------------------- /public/supporters/dvor24_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/dvor24_mini.png -------------------------------------------------------------------------------- /public/supporters/goodcam_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/goodcam_mini.png -------------------------------------------------------------------------------- /public/supporters/megacam_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/megacam_mini.png -------------------------------------------------------------------------------- /public/supporters/s-video_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/s-video_mini.png -------------------------------------------------------------------------------- /public/supporters/skycam_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/skycam_mini.png -------------------------------------------------------------------------------- /public/supporters/sputnik_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/sputnik_mini.png -------------------------------------------------------------------------------- /public/supporters/ufanet_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/ufanet_mini.png -------------------------------------------------------------------------------- /public/supporters/vixand_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/vixand_mini.png -------------------------------------------------------------------------------- /.yarnrc.yml_temp: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | yarnPath: .yarn/releases/yarn-4.2.1.cjs 6 | -------------------------------------------------------------------------------- /public/supporters/keytelecom_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/keytelecom_mini.png -------------------------------------------------------------------------------- /public/supporters/mywifi-cc_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/mywifi-cc_mini.png -------------------------------------------------------------------------------- /public/supporters/webglazok_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/webglazok_mini.png -------------------------------------------------------------------------------- /src/views/content/introduction/supporters/supporters.css: -------------------------------------------------------------------------------- 1 | .supporters { 2 | display: flex; 3 | flex-flow: column; 4 | } 5 | -------------------------------------------------------------------------------- /public/fonts/IBMPlexSans-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/fonts/IBMPlexSans-Regular.woff2 -------------------------------------------------------------------------------- /public/fonts/IBMPlexSans-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/fonts/IBMPlexSans-SemiBold.woff2 -------------------------------------------------------------------------------- /public/supporters/alarmsystem_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/alarmsystem_mini.png -------------------------------------------------------------------------------- /public/supporters/lifecontrol_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/lifecontrol_mini.png -------------------------------------------------------------------------------- /public/supporters/linuxchenxing_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/linuxchenxing_mini.png -------------------------------------------------------------------------------- /public/supporters/techno-shield_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/techno-shield_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/osc_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/osc_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/vtl_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/vtl_mini.png -------------------------------------------------------------------------------- /decs.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'mithril' 2 | 3 | declare module '*.svg' { 4 | const content: any; 5 | export default content; 6 | } 7 | -------------------------------------------------------------------------------- /public/supporters/binary-machines_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/supporters/binary-machines_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/dozor_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/dozor_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/gain_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/gain_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/ipeye_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/ipeye_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/yucca_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/yucca_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/dvor24_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/dvor24_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/goodcam_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/goodcam_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/megacam_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/megacam_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/s-video_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/s-video_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/skycam_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/skycam_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/sputnik_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/sputnik_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/ufanet_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/ufanet_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/vixand_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/vixand_mini.png -------------------------------------------------------------------------------- /src/views/layout/main/main.css: -------------------------------------------------------------------------------- 1 | .main { 2 | width: min(calc(100vw - 20px), 1440px); 3 | flex: 1 1 auto; 4 | padding: 0 0 40px 0; 5 | } 6 | -------------------------------------------------------------------------------- /src/shared/icons/supporters/keytelecom_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/keytelecom_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/mywifi-cc_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/mywifi-cc_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/webglazok_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/webglazok_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/alarmsystem_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/alarmsystem_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/lifecontrol_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/lifecontrol_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/linuxchenxing_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/linuxchenxing_mini.png -------------------------------------------------------------------------------- /src/shared/icons/supporters/techno-shield_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/techno-shield_mini.png -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "build" 3 | command = "yarn run build" 4 | [[redirects]] 5 | status=200 6 | from="/*" 7 | to="/index.html" 8 | -------------------------------------------------------------------------------- /public/fonts/share-tech-mono-v15-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/public/fonts/share-tech-mono-v15-latin-regular.woff2 -------------------------------------------------------------------------------- /src/shared/icons/supporters/binary-machines_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenIPC/interface/main/src/shared/icons/supporters/binary-machines_mini.png -------------------------------------------------------------------------------- /src/views/content/supported-hardware/supported-hardware.css: -------------------------------------------------------------------------------- 1 | .socs-section__header { 2 | font: normal 400 28px/1.2 'IBM Plex Sans', sans-serif; 3 | } 4 | -------------------------------------------------------------------------------- /src/shared/icons/alliance/index.ts: -------------------------------------------------------------------------------- 1 | import Openipc from './openipc.svg'; 2 | import Majestic from './majestic.svg'; 3 | 4 | export default { 5 | openipc: Openipc, 6 | majestic: Majestic, 7 | }; 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .yarn/* 2 | build 3 | 4 | # Swap the comments on the following lines if you don't wish to use zero-installs 5 | # Documentation here: https://yarnpkg.com/features/zero-installs 6 | .pnp.* 7 | tags 8 | -------------------------------------------------------------------------------- /src/shared/icons/triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/views/ui/titles/page-title/page-title.css: -------------------------------------------------------------------------------- 1 | .page-title { 2 | font: normal 700 clamp(25px, 7.1vw, 32px)/1.2 'IBM Plex Sans', sans-serif; 3 | margin: 0; 4 | padding: 16px 0 24px; 5 | color: var(--blue); 6 | } 7 | -------------------------------------------------------------------------------- /src/views/ui/titles/paragraph-title/paragraph-title.css: -------------------------------------------------------------------------------- 1 | .paragraph-title { 2 | color: var(--black); 3 | font: normal normal 28px/1.2 'IBM Plex Sans', sans-serif; 4 | margin: 0; 5 | padding: 0 0 24px 0; 6 | } 7 | -------------------------------------------------------------------------------- /src/views/content/firmware-partition-calculator/firmware-partition-calculator.css: -------------------------------------------------------------------------------- 1 | .fw-partit-calc { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | justify-content: flex-start; 5 | align-items: center; 6 | } 7 | -------------------------------------------------------------------------------- /src/shared/icons/burger.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/views/ui/socs/socs.css: -------------------------------------------------------------------------------- 1 | .socs { 2 | width: 100%; 3 | 4 | @media(max-width: $mobile) { 5 | display: none; 6 | } 7 | 8 | &__list { 9 | list-style: none; 10 | margin: 0; 11 | padding: 0; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/shared/styles/global.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | .page { 7 | height: 100vh; 8 | display: flex; 9 | flex-flow: column nowrap; 10 | justify-content: flex-start; 11 | align-items: center; 12 | } 13 | -------------------------------------------------------------------------------- /src/views/ui/titles/paragraph-title/paragraph-title.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './paragraph-title.css'; 4 | 5 | export const ParagraphTitle = { 6 | view: ({ attrs: { title }}) => 7 | m('h2.paragraph-title', title), 8 | }; 9 | -------------------------------------------------------------------------------- /src/shared/icons/index.ts: -------------------------------------------------------------------------------- 1 | import Triangle from './triangle.svg'; 2 | import Burger from './burger.svg'; 3 | import Gitter from './gitter.svg'; 4 | 5 | export default { 6 | triangle: Triangle, 7 | burger: Burger, 8 | gitter: Gitter, 9 | }; 10 | -------------------------------------------------------------------------------- /src/views/ui/titles/page-title/page-title.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './page-title.css'; 4 | 5 | interface attrs { 6 | text: string 7 | } 8 | 9 | export const PageTitle = { 10 | view: ({ attrs: { text }}) => m('h1.page-title', text), 11 | }; 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "noImplicitAny": false, 5 | "module": "es6", 6 | "target": "es5", 7 | "allowJs": true, 8 | "moduleResolution": "Node", 9 | "lib": ["DOM", "ES2020"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/shared/constants/supported-hardware/vendors.ts: -------------------------------------------------------------------------------- 1 | export const vendors = [ 2 | 'Ambarella', 3 | 'Anyka', 4 | 'Fullhan', 5 | 'Goke', 6 | 'GrainMedia', 7 | 'HiSilicon', 8 | 'Ingenic', 9 | 'MStar', 10 | 'Novatek', 11 | 'SigmaStar', 12 | 'Xiongmai', 13 | ]; 14 | -------------------------------------------------------------------------------- /src/views/ui/links/introduction-main-links/introduction-main-link.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './introduction-main-link.css'; 4 | 5 | export const IntroductionMainLink = { 6 | view: ({ attrs: { label }}) => 7 | m('a.introduction-main-link[href=#blank]', label), 8 | }; 9 | -------------------------------------------------------------------------------- /src/views/ui/buttons/burger-button/burger-button.css: -------------------------------------------------------------------------------- 1 | .burger-button { 2 | width: 56px; 3 | height: 38px; 4 | border: 1px solid var(--light-grey-30); 5 | border-radius: 8px; 6 | background: none; 7 | 8 | & > svg { 9 | width: 30px; 10 | height: 30px; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/views/content/introduction/alliance/alliance.css: -------------------------------------------------------------------------------- 1 | .alliance { 2 | padding: 0 0 20px 0; 3 | display: flex; 4 | flex-flow: row wrap; 5 | justify-content: space-around; 6 | 7 | & > .paragraph-title { 8 | flex: 1 1 100%; 9 | } 10 | 11 | & > svg { 12 | width: 48% 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | const breakpoints = require('./src/shared/constants/breakpoints'); 2 | 3 | module.exports = { 4 | plugins: [ 5 | "postcss-preset-env", 6 | "postcss-mixins", 7 | ['postcss-simple-vars', { 8 | variables: breakpoints, 9 | }], 10 | "postcss-nested", 11 | ], 12 | } 13 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Proposal OpenIPC Site 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/views/ui/copyright/copyright.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './copyright.css'; 4 | 5 | export const Copyright = { 6 | view: () => 7 | m('p.copyright', [ 8 | 'Copyright 2022 ', 9 | m('a.copyright__link[href=https://openipc.org]', 'OpenIPC'), 10 | '.', 11 | ]), 12 | }; 13 | -------------------------------------------------------------------------------- /src/views/ui/calc-msg/calc-msg.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './calc-msg.css'; 4 | 5 | export const CalcMsg = { 6 | view: ({ attrs: { msg }}: { attrs: { msg: string }}) => 7 | m('.calc-msg', 8 | m('.calc-msg__msg-container', 9 | m('p.calc-msg__msg', msg), 10 | ), 11 | ), 12 | } 13 | -------------------------------------------------------------------------------- /src/views/ui/socs-mobile/socs-mobile.css: -------------------------------------------------------------------------------- 1 | .socs-mobile { 2 | display: none; 3 | 4 | @media(max-width: $mobile) { 5 | display: block; 6 | list-style: none; 7 | margin: 0; 8 | padding: 0; 9 | display: flex; 10 | flex-flow: column; 11 | gap: 16px 0; 12 | font: normal normal 13px/1.2 'IBM Plex Sans', sans-serif; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/shared/utils/parag-links.ts: -------------------------------------------------------------------------------- 1 | export const paragLink = { 2 | split: (text: string) => { 3 | return text.split(/(\[.*?\]\(.*?\))/ig); 4 | }, 5 | getTextLink: (chunk: string) => { 6 | return { 7 | text: Array.from(chunk.matchAll(/\[(.*?)\]\((.*?)\)/gi))[0][1], 8 | link: Array.from(chunk.matchAll(/\[(.*?)\]\((.*?)\)/gi))[0][2] 9 | }; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/views/ui/project-item/project-item.css: -------------------------------------------------------------------------------- 1 | .projects_list__link { 2 | text-decoration: underline; 3 | color: var(--button-blue); 4 | font: normal 700 16px/24px 'IBM Plex Sans', sans-serif; 5 | width: max-content; 6 | } 7 | 8 | .projects_list__description { 9 | padding: 0 0 8px 0; 10 | margin: 0; 11 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 12 | } 13 | -------------------------------------------------------------------------------- /src/views/ui/links/header-link/header-link.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './header-link.css'; 4 | 5 | interface IHeaderLink { 6 | label: string 7 | href: string 8 | } 9 | 10 | export const HeaderLink = { 11 | view: ({ attrs }) => 12 | m( 13 | 'a.header-link', 14 | { 15 | href: attrs.href, 16 | }, 17 | attrs.label, 18 | ), 19 | }; 20 | -------------------------------------------------------------------------------- /src/views/ui/buttons/burger-button/burger-button.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import icons from '../../../../shared/icons'; 4 | import './burger-button.css'; 5 | 6 | export const BurgerButton = { 7 | view: ({ attrs : { clickHandler }}) => 8 | m('button.burger-button[name=burger-button]', 9 | { onclick: clickHandler }, 10 | m.trust(icons.burger), 11 | ) 12 | }; 13 | -------------------------------------------------------------------------------- /src/shared/icons/socials.ts: -------------------------------------------------------------------------------- 1 | import Github from './github.svg'; 2 | import Twitter from './twitter.svg'; 3 | import Youtube from './youtube.svg'; 4 | import Opencollective from './opencollective.svg'; 5 | import Telegram from './telegram.svg'; 6 | 7 | export default { 8 | github: Github, 9 | twitter: Twitter, 10 | youtube: Youtube, 11 | opencollective: Opencollective, 12 | telegram: Telegram, 13 | }; 14 | -------------------------------------------------------------------------------- /src/views/ui/socs-mobile/socs-mobile.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { SocMobile } from './soc-mobile/soc-mobile'; 3 | 4 | import { SoC } from '../../content/supported-hardware/supported-hardware'; 5 | import './socs-mobile.css'; 6 | 7 | export const SocsMobile = { 8 | view: ({ attrs: { socs }}) => 9 | m('ul.socs-mobile', 10 | socs.map((soc: SoC) => m(SocMobile, { soc })) 11 | ), 12 | } 13 | -------------------------------------------------------------------------------- /src/views/layout/layout.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { Header } from './header/header'; 3 | import { Main } from './main/main'; 4 | import { Footer } from './footer/footer'; 5 | 6 | export const Layout = { 7 | view: ({ attrs: { pageTitle, choosenSoC }, children }) => 8 | m('.page', [ 9 | m(Header), 10 | m(Main, { pageTitle, choosenSoC }, children), 11 | m(Footer), 12 | ]), 13 | }; 14 | -------------------------------------------------------------------------------- /src/views/layout/main/main.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { PageTitle } from '../../ui/titles/page-title/page-title'; 3 | import { pageTitles } from '../../../shared/constants/titles'; 4 | 5 | import './main.css'; 6 | 7 | export const Main = { 8 | view: ({ attrs: { pageTitle }, children }) => 9 | m('main.main', [ 10 | m(PageTitle, { text: pageTitles[pageTitle] }), 11 | children 12 | ]), 13 | }; 14 | -------------------------------------------------------------------------------- /src/shared/constants/footer.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | text: 'The information contained on this site is for general informational purposes only and is not intended to be relied upon by the visitor. All software and firmware available on this site is provided AS IS and for research purposes only. OpenIPC shall not be liable for any loss or damage caused by the use of these files or the use of, or reliance upon, any information contained in this site.', 3 | } 4 | -------------------------------------------------------------------------------- /src/views/ui/project-item/project-item.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './project-item.css'; 4 | 5 | export const ProjectItem = { 6 | view: ({ attrs: { link, title, description }}: { attrs: { link: string, title: string, description: string }}) => [ 7 | m('dt.projects_list__project', 8 | m(`a.projects_list__link[href=${link}]`, 9 | title 10 | ), 11 | ), 12 | m('dd.projects_list__description', description), 13 | ] 14 | }; 15 | -------------------------------------------------------------------------------- /src/views/ui/vendors/vendors.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { Vendor } from './vendor/vendor'; 3 | 4 | import './vendors.css'; 5 | 6 | export const Vendors = { 7 | view: ({ attrs: { letter, vendors, selectedVendor }}) => 8 | m('nav.vendors', 9 | m('ul.vendors__list', 10 | vendors.map((vendor: string) => 11 | m(Vendor, { 12 | letter, 13 | vendor, 14 | isChoosen: vendor === selectedVendor, 15 | })) 16 | ), 17 | ), 18 | }; 19 | -------------------------------------------------------------------------------- /src/shared/constants/our-team/texts.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | 'our-team': 'OpenIPC is a community-driven open source project, and many people contribute to its codebase. Koodos to them! There is also a core team of skilled developers who work hard to expand the list of [supported hardware platforms](https://openipc.org/supported-hardware), extend the functionality and stability of the firmware, review submitted code, and coordinate community efforts. Get to know the team and their areas of expertise:', 3 | } 4 | -------------------------------------------------------------------------------- /src/views/ui/links/header-link/header-link.css: -------------------------------------------------------------------------------- 1 | .header-link { 2 | background: none; 3 | border: none; 4 | outline: none; 5 | font: normal normal 16px/1.1 sans-serif; 6 | color: #fff; 7 | opacity: .55; 8 | transition: opacity .2s ease-in; 9 | margin: 0; 10 | padding: 0; 11 | font: normal normal 16px/1.1 'IBM Plex Sans', sans-serif; 12 | text-decoration: none; 13 | 14 | &:hover { 15 | cursor: pointer; 16 | color: #fff; 17 | opacity: .8; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /src/views/content/introduction/alliance/alliance.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagraphTitle } from '../../../ui/titles/paragraph-title/paragraph-title'; 3 | 4 | import allianceIcons from '../../../../shared/icons/alliance/index'; 5 | import './alliance.css'; 6 | 7 | export const Alliance = { 8 | view: ({ attrs: { title }}) => 9 | m('.alliance', [ 10 | m(ParagraphTitle, { title: title }), 11 | m.trust(allianceIcons.openipc), 12 | m.trust(allianceIcons.majestic), 13 | ]), 14 | }; 15 | -------------------------------------------------------------------------------- /src/views/content/introduction/supporters/supporters.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagraphTitle } from '../../../ui/titles/paragraph-title/paragraph-title'; 3 | import { SupportersList } from './supporters-list/supporters-list'; 4 | 5 | import './supporters.css'; 6 | 7 | export const Supporters = { 8 | view: ({ attrs: { title, supporters }}) => 9 | m('.supporters', [ 10 | m(ParagraphTitle, { title: title }), 11 | m(SupportersList, { supporters: supporters }), 12 | ]), 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | workflow_dispatch: 4 | 5 | permissions: 6 | id-token: write 7 | pages: write 8 | contents: write 9 | 10 | jobs: 11 | deploy: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | 17 | - name: Build 18 | run: npm run deploy 19 | 20 | - name: Release 21 | uses: softprops/action-gh-release@v2 22 | with: 23 | tag_name: latest 24 | files: build.tgz 25 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/grey-frame.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/views/ui/socs/socs.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ColumnTitles } from '../column-titles/column-titles'; 3 | import { Soc } from './soc/soc'; 4 | 5 | import { SoC } from '../../content/supported-hardware/supported-hardware'; 6 | import './socs.css'; 7 | 8 | export const Socs = { 9 | view: ({ attrs: { socs }}) => 10 | m('.socs', [ 11 | m(ColumnTitles), 12 | m('ul.socs__list', 13 | m('li.socs__item', 14 | socs.map((soc: SoC) => m(Soc, { soc })), 15 | ), 16 | ), 17 | ]), 18 | } 19 | -------------------------------------------------------------------------------- /src/views/content/introduction/supporters/supporters-list/supporters-list.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './supporters-list.css'; 4 | 5 | export const SupportersList = { 6 | view: ({ attrs: { supporters }}) => 7 | m('ul.supporters-list', 8 | supporters.map((sup: {}) => 9 | m('li.supporters-list__item', [ 10 | m(`a.supporters-list__link[href=${sup['href']}]`, [ 11 | m(`img.supporters-list__image[src=/supporters/${sup['src']}]`), 12 | ]), 13 | ]) 14 | ), 15 | ), 16 | }; 17 | -------------------------------------------------------------------------------- /src/views/ui/calc-msg/calc-msg.css: -------------------------------------------------------------------------------- 1 | .calc-msg { 2 | width: 100%; 3 | padding: 20px 0 0 0; 4 | 5 | &__msg-container { 6 | background: var(--green-like-bg); 7 | height: 76px; 8 | display: flex; 9 | flex-flow: column; 10 | justify-content: center; 11 | border: 1px solid var(--light-grey); 12 | border-radius: 6px; 13 | } 14 | 15 | &__msg { 16 | margin: 0; 17 | padding: 0; 18 | color: var(--greenish-text); 19 | font: normal normal 28px/1.2 'IBM Plex Sans', sans-serif; 20 | text-align: center; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/shared/styles/palette.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --white: #fff; 3 | --red: #ff0000; 4 | --orange: #ffa500; 5 | --green: #00ff00; 6 | --pure-blue: #0000ff; 7 | 8 | --deep-blue-text: #084298; 9 | --blue: #4c60d8; 10 | --button-blue: #0e6efd; 11 | --button-blue-hover: #0a59cb; 12 | --blue-like-bg: #cfe2ff; 13 | 14 | --green-like-bg: #cff4fc; 15 | --greenish-text: #055160; 16 | 17 | --black: #212529; 18 | --grey: #6c757d; 19 | --lines-grey: #acb0b2; 20 | --light-grey: #e9ecef; 21 | --light-grey-30: #e9ecef30; 22 | --grey-bg: #f8f9fa; 23 | } 24 | -------------------------------------------------------------------------------- /src/views/ui/buttons/header-button/header-button.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import icons from '../../../../shared/icons/index'; 3 | import './header-button.css'; 4 | 5 | export const HeaderButton = { 6 | view: ({ attrs: { label, clickHandler, isClicked }}) => 7 | m( 8 | 'button.header-button', 9 | { 10 | name: label, 11 | onclick: clickHandler, 12 | class: isClicked ? 'header-button_clicked' : 'header-button_unclicked', 13 | }, 14 | [ 15 | label, 16 | m.trust(icons.triangle), 17 | ], 18 | ), 19 | } 20 | -------------------------------------------------------------------------------- /src/views/ui/socials/socials.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './socials.css'; 4 | import socials from '../../../shared/constants/socials'; 5 | 6 | export const Socials = { 7 | view: () => 8 | m('ul.socials', 9 | socials.map((social) => { 10 | const socialName = Object.keys(social)[0]; 11 | return m('li.socials__item', [ 12 | m('a.socials__link', { 13 | href: social[socialName].link, 14 | }, [ 15 | m.trust(social[socialName].icon), 16 | ]) 17 | ]) 18 | }), 19 | ), 20 | }; 21 | -------------------------------------------------------------------------------- /src/views/layout/header/mobile-dropdown/mobile-dropdown.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import './mobile-dropdown.css'; 3 | 4 | export const MobileDropdown = { 5 | view: ({ attrs: { navElements, isOpen }}) => 6 | m('ul.mobile-dropdown', { 7 | class: isOpen ? 'mobile-dropdown_open' : 'mobile-dropdown_close', 8 | }, 9 | navElements.map((el: {}[]) => 10 | m('li.mobile-dropdown__item', 11 | m(`a.mobile-dropdown__link[href=${el[Object.keys(el)[0]]}]`, 12 | Object.keys(el)[0] 13 | ) 14 | ), 15 | ) 16 | ) 17 | }; 18 | -------------------------------------------------------------------------------- /src/views/layout/footer/footer.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { Socials } from '../../ui/socials/socials'; 3 | import { Copyright } from '../../ui/copyright/copyright'; 4 | 5 | import footerContent from '../../../shared/constants/footer'; 6 | 7 | import './footer.css'; 8 | 9 | export const Footer = { 10 | view: () => 11 | m('footer.footer', [ 12 | m('.footer__wrapper', [ 13 | m('.footer__left', 14 | m(Copyright), 15 | ), 16 | m('.footer__right', m(Socials)), 17 | m('.footer__bottom', footerContent.text), 18 | ]) 19 | ]), 20 | }; 21 | -------------------------------------------------------------------------------- /src/views/ui/links/introduction-main-links/introduction-main-link.css: -------------------------------------------------------------------------------- 1 | .introduction-main-link { 2 | text-decoration: none; 3 | display: inline-block; 4 | color: var(--white); 5 | background-color: var(--button-blue); 6 | border: 1px solid var(--button-blue); 7 | border-radius: 8px; 8 | font: normal 400 20px/30px 'IBM Plex Sans', sans-serif; 9 | padding: 8px 0; 10 | width: 250px; 11 | max-height: 30px; 12 | text-align: center; 13 | transition: background .2s ease-in; 14 | 15 | &:hover { 16 | cursor: pointer; 17 | background: var(--button-blue-hover); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/views/ui/parag-link/parag-link.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { paragLink } from '../../../shared/utils/parag-links'; 3 | 4 | export const ParagLink = { 5 | view: ({ attrs: { text, pClass }}: {attrs: { text: string, pClass: string}}) => 6 | m(`p.${pClass}`, 7 | paragLink.split(text).map((chunk: string) => { 8 | if (/^\[.*?\]\(.*?\)$/ig.test(chunk)) { 9 | return m(`a[href=${paragLink.getTextLink(chunk).link}]`, paragLink.getTextLink(chunk).text); 10 | } 11 | else { 12 | return chunk; 13 | } 14 | }), 15 | ), 16 | } 17 | -------------------------------------------------------------------------------- /src/views/ui/chat-banner/chat-banner.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import icons from '../../../shared/icons/index'; 3 | 4 | import './chat-banner.css'; 5 | 6 | export const ChatBanner = { 7 | view: ({ attrs: { title, link }}: { attrs: {title: string, link: string}}) => 8 | m('.chat-banner', [ 9 | m('.chat-banner__chat-data', [ 10 | m('.chat-banner__chat-title', title), 11 | m(`a.chat-banner__chat-link[href=${link}]`, 12 | link 13 | ), 14 | ]), 15 | m('.chat-banner__chat-icon', 16 | m.trust(icons.gitter), 17 | ), 18 | ]), 19 | } 20 | -------------------------------------------------------------------------------- /src/views/ui/buttons/solid-button/solid-button.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './solid-button.css'; 4 | 5 | interface ISolidButton { 6 | attrs: { 7 | label: string 8 | bgColor: 'button-blue' | 'grey' 9 | labelColor: string 10 | } 11 | } 12 | 13 | export const SolidButton = { 14 | view: ({ attrs: { label, bgColor, labelColor }}: ISolidButton) => 15 | m('button.solid-button[type=text]', { 16 | class:` 17 | solid-button_bg_${bgColor || 'white'} 18 | solid-button_color_${labelColor || 'black'} 19 | `, 20 | }, 21 | label 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /src/views/ui/buttons/solid-button/solid-button.css: -------------------------------------------------------------------------------- 1 | .solid-button { 2 | padding: 0; 3 | margin: 0; 4 | width: 110px; 5 | height: 38px; 6 | border: none; 7 | border-radius: 6px; 8 | font: normal normal 16px/1.2 'IBM Plex Sans', sans-serif; 9 | text-align: center; 10 | transition: background .2s ease-in; 11 | 12 | &:hover { 13 | cursor: pointer; 14 | } 15 | 16 | &_bg_button-blue { 17 | background: var(--button-blue); 18 | } 19 | 20 | &_bg_button-blue:hover { 21 | background: var(--button-blue-hover); 22 | } 23 | 24 | &_color_white { 25 | color: var(--white); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/socs-icons.ts: -------------------------------------------------------------------------------- 1 | import EmptyFrame from './grey-frame.svg'; 2 | import DownArrowFrame from './blue-arrow-frame.svg'; 3 | import InfoFrame from './blue-info-frame.svg'; 4 | import Neq from './neq.svg'; 5 | import RnD from './rnd.svg'; 6 | import Hlp from './hlp.svg'; 7 | import Wip from './wip.svg'; 8 | import Mvp from './mvp.svg'; 9 | import Done from './done.svg'; 10 | 11 | export default { 12 | emptyFrame: EmptyFrame, 13 | downArrowFrame: DownArrowFrame, 14 | infoFrame: InfoFrame, 15 | neq: Neq, 16 | rnd: RnD, 17 | hlp: Hlp, 18 | wip: Wip, 19 | mvp: Mvp, 20 | done: Done, 21 | }; 22 | -------------------------------------------------------------------------------- /src/views/ui/column-titles/column-titles.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './column-titles.css'; 4 | 5 | export const ColumnTitles = { 6 | view: () => 7 | m('ul.column-titles', [ 8 | m('li.column-titles__title', 'Stage'), 9 | m('li.column-titles__title', 'SoC Model'), 10 | m('li.column-titles__title', 'Docs'), 11 | m('li.column-titles__title', 'U-Boot'), 12 | m('li.column-titles__title', 'Linux'), 13 | m('li.column-titles__title', 'SDK'), 14 | m('li.column-titles__title', 'Load address'), 15 | m('li.column-titles__title', 'Build status'), 16 | ]), 17 | } 18 | -------------------------------------------------------------------------------- /src/views/ui/letters/letters.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './letters.css'; 4 | 5 | export const Letters = { 6 | view: ({ attrs: { letters, selectedLetter }}) => 7 | m('.letters', 8 | m('ul.letters__list', 9 | letters.map((letter: String) => 10 | m('li.letters__letter', 11 | m(m.route.Link, { 12 | href: `/cameras/vendors/${letter}`, 13 | selector: `a.letters__link${selectedLetter === letter ? '.letters__link_choosen' : ''}`, 14 | }, 15 | letter 16 | ), 17 | ) 18 | ) 19 | ) 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /src/views/content/our-channels/our-channels.css: -------------------------------------------------------------------------------- 1 | .our-channels { 2 | display: flex; 3 | gap: 20px; 4 | flex-flow: row wrap; 5 | } 6 | 7 | .channels { 8 | box-sizing: border-box; 9 | flex: 1 0 50%; 10 | padding: 0 0 20px 0; 11 | } 12 | 13 | .chats { 14 | box-sizing: border-box; 15 | min-width: 263px; 16 | flex: 1 0 20%; 17 | display: flex; 18 | flex-flow: column; 19 | } 20 | 21 | .chats__banners { 22 | width: 100%; 23 | } 24 | 25 | .chat-banner { 26 | box-sizing: border-box; 27 | } 28 | 29 | .chat-banner:first-child { 30 | margin: 0 0 20px 0; 31 | } 32 | 33 | .our-channels > .donate-us { 34 | flex: 1 1 100%; 35 | } 36 | -------------------------------------------------------------------------------- /src/shared/icons/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/views/content/introduction/supporters/supporters-list/supporters-list.css: -------------------------------------------------------------------------------- 1 | .supporters-list { 2 | list-style: none; 3 | padding: 0; 4 | margin: 0; 5 | display: flex; 6 | flex-flow: row wrap; 7 | gap: 25px 10px; 8 | 9 | @media(max-width: $mobile) { 10 | gap: 20px 10px; 11 | } 12 | 13 | &__item { 14 | height: 50px; 15 | flex: 0 1 30%; 16 | display: flex; 17 | justify-content: center; 18 | align-items: center; 19 | 20 | @media(max-width: $mobile) { 21 | flex: 1 1 23%; 22 | max-width: 33%; 23 | } 24 | } 25 | 26 | &__image { 27 | max-width: 100%; 28 | object-fit: contain; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/views/content/our-team/our-team.css: -------------------------------------------------------------------------------- 1 | .team { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | align-items: center; 5 | 6 | &__intro { 7 | margin: 0; 8 | padding: 0 0 16px 0; 9 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 10 | } 11 | 12 | &__list { 13 | margin: 0; 14 | padding: 0 0 40px 0; 15 | list-style: none; 16 | width: 100%; 17 | display: grid; 18 | grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); 19 | grid-auto-rows: 334px; 20 | gap: 20px; 21 | 22 | @media(max-width: $mobile) { 23 | grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/shared/constants/socials.ts: -------------------------------------------------------------------------------- 1 | import socialIcons from '../icons/socials'; 2 | 3 | export default [ 4 | { 5 | github: { 6 | icon: socialIcons.github, 7 | link: 'https://github.com/openipc', 8 | }, 9 | }, 10 | { 11 | twitter: { 12 | icon: socialIcons.twitter, 13 | link: 'https://twitter.com/openipc', 14 | }, 15 | }, 16 | { 17 | youtube: { 18 | icon: socialIcons.youtube, 19 | link: 'https://www.youtube.com/channel/UCaXlbR2uGTRFh8jQ2lCFd2g' 20 | }, 21 | }, 22 | { 23 | opencollective: { 24 | icon: socialIcons.opencollective, 25 | link: 'https://opencollective.com/openipc', 26 | }, 27 | }, 28 | ]; 29 | -------------------------------------------------------------------------------- /src/views/content/our-projects/our-projects.css: -------------------------------------------------------------------------------- 1 | .our-projects { 2 | display: flex; 3 | flex-flow: row wrap; 4 | gap: 20px; 5 | } 6 | 7 | .core { 8 | box-sizing: border-box; 9 | min-width: 344px; 10 | flex: 1 1 calc(50% - 20px); 11 | } 12 | 13 | .umbrella { 14 | box-sizing: border-box; 15 | min-width: 344px; 16 | flex: 1 1 calc(50% - 20px); 17 | 18 | &__mention { 19 | color: var(--greenish-text); 20 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 21 | padding: 16px; 22 | margin: 0 0 16px 0; 23 | background: var(--green-like-bg); 24 | border-radius: 6px; 25 | } 26 | } 27 | 28 | .projects-list { 29 | margin: 0; 30 | padding: 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/views/ui/vendors/vendor/vendor.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './vendor.css'; 4 | 5 | export const Vendor = { 6 | view: ({ attrs: { letter, vendor, isChoosen }}) => 7 | m('li.vendors__vendor', 8 | m(m.route.Link, { 9 | class: `vendors__link ${isChoosen ? 'vendors__link_choosen' : ''}`, 10 | href: vendor === 'Full list' && letter === undefined 11 | ? `/supported-hardware` 12 | : vendor === 'Full list' 13 | ? `/cameras/vendors/${letter}/${vendor.replace(' ', '-').toLowerCase()}` 14 | : `/cameras/vendors/${vendor.slice(0,1)}/${vendor.replace(' ', '-').toLowerCase()}` 15 | }, 16 | vendor) 17 | ), 18 | }; 19 | -------------------------------------------------------------------------------- /src/views/content/introduction/introduction.css: -------------------------------------------------------------------------------- 1 | .introduction { 2 | display: flex; 3 | flex-flow: row nowrap; 4 | gap: 0 4%; 5 | 6 | @media(max-width: $mobile) { 7 | flex-flow: column nowrap; 8 | } 9 | 10 | &__main { 11 | flex: 1 10 1000px; 12 | } 13 | 14 | &__collab { 15 | flex: 1 6 430px; 16 | } 17 | } 18 | 19 | .main-text { 20 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 21 | margin: 0; 22 | padding: 0 0 16px 0; 23 | } 24 | 25 | .main-links { 26 | width: 100%; 27 | margin: 0; 28 | padding: 12px 0 28px 0; 29 | display: flex; 30 | flex-flow: row wrap; 31 | justify-content: center; 32 | align-items: center; 33 | gap: 10px 5px; 34 | } 35 | -------------------------------------------------------------------------------- /src/views/ui/column-titles/column-titles.css: -------------------------------------------------------------------------------- 1 | .column-titles { 2 | margin: 0; 3 | padding: 0 0 15px 0; 4 | box-sizing: border-box; 5 | height: 30px; 6 | list-style: none; 7 | display: grid; 8 | grid-template-columns: 4fr 12fr repeat(4, 4fr) 10fr 12fr; 9 | font: normal 700 14px/1.2 'IBM Plex Sans', sans-serif; 10 | border-bottom: 1px solid var(--lines-grey); 11 | 12 | &__title { 13 | display: flex; 14 | flex-flow: row nowrap; 15 | justify-content: flex-start; 16 | align-items: flex-start; 17 | 18 | &:nth-child(1) { 19 | justify-content: center; 20 | } 21 | 22 | &:nth-child(n+3):nth-child(-n+6) { 23 | justify-content: center; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/views/layout/header/dropdown/dropdown.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './dropdown.css'; 4 | 5 | interface IAttrs { 6 | nestedElems: {}[] 7 | isOpen: boolean 8 | } 9 | 10 | export const DropDown = { 11 | view: ({ attrs: { isOpen, nestedElems }}) => 12 | m( 'ul.dropdown', { 13 | class: isOpen ? 'dropdown_show' : 'dropdown_hide', 14 | }, 15 | nestedElems.map((el: {}) => { 16 | const elementName = Object.keys(el)[0]; 17 | return m( 'li.dropdown__item', 18 | m('a.dropdown__link', 19 | { 20 | href: el[elementName], 21 | }, 22 | elementName, 23 | ) 24 | ); 25 | }) 26 | ), 27 | }; 28 | -------------------------------------------------------------------------------- /src/shared/icons/opencollective.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shared/icons/gitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/blue-arrow-frame.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/shared/styles/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'IBM Plex Sans'; 3 | font-style: normal; 4 | font-weight: normal; 5 | src: url('../../../public/fonts/IBMPlexSans-Regular.woff2'); 6 | } 7 | 8 | @font-face { 9 | font-family: 'IBM Plex Sans'; 10 | font-style: normal; 11 | font-weight: bold; 12 | src: url('../../../public/fonts/IBMPlexSans-Bold.woff2'); 13 | } 14 | 15 | @font-face { 16 | font-family: 'IBM Plex Sans'; 17 | font-style: normal; 18 | font-weight: 500; 19 | src: url('../../../public/fonts/IBMPlexSans-SemiBold.woff2'); 20 | } 21 | 22 | @font-face { 23 | font-family: 'Share Tech Mono'; 24 | font-style: normal; 25 | font-weight: normal; 26 | src: url('../../../public/fonts/share-tech-mono-v15-latin-regular.woff2'); 27 | } 28 | -------------------------------------------------------------------------------- /src/shared/constants/main-nav-list.ts: -------------------------------------------------------------------------------- 1 | const navigation = [ 2 | { 3 | 'Introduction': '/introduction', 4 | }, 5 | { 6 | 'Supported Hardware': '/supported-hardware', 7 | }, 8 | { 9 | 'Support Open Source': '/support-open-source', 10 | }, 11 | { 12 | 'About': [ 13 | { 14 | 'Our Team': '/our-team', 15 | }, 16 | { 17 | 'Our Projects': '/our-projects', 18 | }, 19 | { 20 | 'Our Channels': '/our-channels', 21 | }, 22 | { 23 | 'Our Wiki': '/wiki', 24 | }, 25 | ], 26 | }, 27 | { 28 | 'Tools': [ 29 | { 30 | 'Firmware Partition Calculator': '/firmware-partition-calculator', 31 | }, 32 | ], 33 | }, 34 | ] 35 | 36 | export default navigation; 37 | -------------------------------------------------------------------------------- /src/views/content/support-open-source/support-open-source.css: -------------------------------------------------------------------------------- 1 | .support-open-source { 2 | display: flex; 3 | flex-flow: row wrap; 4 | gap: 25px 25px; 5 | } 6 | 7 | .sos-illustration { 8 | flex: 1 1 calc(25% - 10px); 9 | 10 | &__picture { 11 | width: 100%; 12 | } 13 | } 14 | 15 | .sos-text { 16 | flex: 1 1 calc(75% - 15px); 17 | 18 | &__h3 { 19 | margin: 0; 20 | padding: 0 0 16px 0; 21 | font: normal normal 20px/24px 'IBM Plex Sans', sans-serif; 22 | } 23 | 24 | &__h4 { 25 | margin: 0; 26 | padding: 0 0 8px 0; 27 | font: normal normal 24px/1.2 'IBM Plex Sans', sans-serif; 28 | } 29 | 30 | &__p { 31 | margin: 0; 32 | padding: 0 0 16px 0; 33 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/views/ui/socs/soc/soc.css: -------------------------------------------------------------------------------- 1 | .soc { 2 | list-style: none; 3 | margin: 0; 4 | padding: 0; 5 | display: grid; 6 | grid-template-columns: 4fr 12fr repeat(4, 4fr) 10fr 12fr; 7 | border-bottom: 1px solid var(--lines-grey); 8 | 9 | &__cell { 10 | padding: 0; 11 | box-sizing: border-box; 12 | height: 54px; 13 | display: flex; 14 | flex-flow: row nowrap; 15 | justify-content: flex-start; 16 | align-items: center; 17 | font: normal 400 16px/1.2 'IBM Plex Sans', sans-serif; 18 | 19 | &:nth-child(1) { 20 | justify-content: center; 21 | } 22 | 23 | &:nth-child(n+3):nth-child(-n+6) { 24 | justify-content: center; 25 | } 26 | } 27 | 28 | &__cell > svg { 29 | width: 30px; 30 | height: 30px; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/shared/icons/telegram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/views/layout/header/mobile-dropdown/mobile-dropdown.css: -------------------------------------------------------------------------------- 1 | .mobile-dropdown { 2 | list-style: none; 3 | margin: 0; 4 | padding: 10px 0 0 10px; 5 | color: var(--white); 6 | opacity: .55; 7 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 8 | overflow: hidden; 9 | 10 | &_open { 11 | max-height: 400px; 12 | padding-top: 10px; 13 | transition: max-height .2s ease-in, 14 | padding-top .2s ease-in; 15 | } 16 | 17 | &_close { 18 | max-height: 0; 19 | padding-top: 0px; 20 | transition: max-height .2s ease-out, 21 | padding-top .2s ease-out; 22 | } 23 | 24 | &__item { 25 | padding: 0 0 10px 0; 26 | } 27 | 28 | &__link { 29 | color: var(--white); 30 | text-decoration: none; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/views/content/firmware-partition-calculator/firmware-partition-caclucator.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { CalcTable } from '../../ui/calc-table/calc-table'; 3 | import { CalcPartitChart } from '../../ui/calc-partit-chart/calc-partit-chart'; 4 | import { CalcMsg } from '../../ui/calc-msg/calc-msg'; 5 | 6 | import './firmware-partition-calculator.css'; 7 | 8 | export const FirmwarePartitionCalculator = { 9 | view: () => 10 | m('section.fw-partit-calc', [ 11 | m(CalcTable), 12 | m(CalcPartitChart, { 13 | fSize: 16 * 1024, 14 | p1Size: 256, 15 | p2Size: 64, 16 | p3Size: 2048, 17 | p4Size: 5120, 18 | }), 19 | m(CalcMsg, { 20 | msg: 'Please enter MTD device name to generate mtdpars string', 21 | }), 22 | ]), 23 | } 24 | -------------------------------------------------------------------------------- /src/views/ui/donate-banner/donate-banner.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagLink } from '../parag-link/parag-link'; 3 | 4 | import './donate-banner.css'; 5 | 6 | export const DonateBanner = { 7 | view: () => 8 | m('section.donate-us', 9 | m('.donate-us__wrapper', 10 | m('.donate-us__content', [ 11 | m('.donate-us__button', 12 | m('img[src=https://opencollective.com/webpack/donate/button.png?color=blue]'), 13 | ), 14 | m('.donate-us__text', [ 15 | m('h5.donate-us__text-header', 'Do you like what we do?'), 16 | m(ParagLink, { text: 'Please consider [supporting our projects](https://openipc.org/support-open-source)', pClass: 'donate-us__text-body' }), 17 | ]), 18 | ]), 19 | ), 20 | ), 21 | } 22 | -------------------------------------------------------------------------------- /src/views/layout/footer/footer.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | background-color: var(--grey-bg); 3 | width: 100%; 4 | } 5 | 6 | .footer__wrapper { 7 | width: min(calc(100vw - 20px), 1440px); 8 | margin: 0 auto; 9 | height: 100%; 10 | display: flex; 11 | flex-flow: row wrap; 12 | justify-content: space-between; 13 | } 14 | 15 | .footer__left { 16 | height: 38px; 17 | padding: 10px 0; 18 | display: flex; 19 | flex-flow: row nowrap; 20 | justify-content: flex-start; 21 | align-items: center; 22 | } 23 | 24 | .footer__right { 25 | padding: 10px 0; 26 | display: flex; 27 | flex-flow: column; 28 | justify-content: center; 29 | } 30 | 31 | .footer__bottom { 32 | padding: 18px 0 28px 0; 33 | flex: 1 1 100%; 34 | color: var(--black); 35 | font: normal normal 12px/1.4 'IBM Plex Sans', sans-serif; 36 | } 37 | -------------------------------------------------------------------------------- /src/views/ui/chat-banner/chat-banner.css: -------------------------------------------------------------------------------- 1 | .chat-banner { 2 | padding: 16px; 3 | background: var(--blue-like-bg); 4 | display: flex; 5 | flex-flow: row nowrap; 6 | place-content: center space-between; 7 | border-radius: 6px; 8 | border: 1px solid var(--lines-grey); 9 | 10 | &__chat-title { 11 | padding: 0 0 4px 0; 12 | font: normal normal clamp(18px, 2.11vw, 24px)/1.2 'IBM Plex Sans', sans-serif; 13 | color: var(--deep-blue-text); 14 | } 15 | 16 | &__chat-link { 17 | font: normal normal clamp(12px, 1.11vw, 16px)/1.2 'IBM Plex Sans', sans-serif; 18 | color: var(--button-blue); 19 | display: flex; 20 | } 21 | 22 | &__chat-icon { 23 | display: flex; 24 | flex-flow: column nowrap; 25 | place-content: center center; 26 | } 27 | 28 | &__chat-icon > svg { 29 | width: 40px; 30 | height: 40px; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/views/ui/calc-partit-chart/calc-partit-chart.css: -------------------------------------------------------------------------------- 1 | .calc-partit-chart { 2 | padding: 20px 0 0 0; 3 | width: 100%; 4 | 5 | &__wrapper { 6 | height: 32px; 7 | border: 1px solid transparent; 8 | border-radius: 6px; 9 | display: flex; 10 | flex-flow: row nowrap; 11 | } 12 | 13 | &__p1-size { 14 | border: 1px solid transparent; 15 | border-top-left-radius: 6px; 16 | border-bottom-left-radius: 6px; 17 | background: var(--red); 18 | flex: 1 1 auto; 19 | } 20 | 21 | &__p2-size { 22 | background: var(--orange); 23 | } 24 | 25 | &__p3-size { 26 | background: var(--green); 27 | } 28 | 29 | &__p4-size { 30 | background: var(--pure-blue); 31 | } 32 | 33 | &__p5-size { 34 | border: 1px solid transparent; 35 | border-top-right-radius: 6px; 36 | border-bottom-right-radius: 6px; 37 | background: var(--grey); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/done.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/hlp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/mvp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/neq.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/rnd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/wip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shared/icons/youtube.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/shared/constants/titles.ts: -------------------------------------------------------------------------------- 1 | export const pageTitles = { 2 | introduction: 'Introduction', 3 | 'supported-hardware': 'Supported Hardware by SoC', 4 | 'support-open-source': 'Support Open Source', 5 | 'our-team': 'Our Team', 6 | 'our-projects': 'Our Projects', 7 | 'our-channels': 'Our Channels', 8 | wiki: 'OpenIPC Wiki', 9 | 'firmware-partition-calculator': 'Firmware Partitions Calculator', 10 | } 11 | 12 | export const paragraphTitles = { 13 | introduction: { 14 | open: 'OpenIPC is an alternative open firmware for your IP camera.', 15 | why: 'Why OpenIPC Firmware?', 16 | alliance: 'Alliance', 17 | supporters: 'Supporters', 18 | }, 19 | 'support-open-source': { 20 | become: 'Become a Sponsor', 21 | donations: 'Donations', 22 | }, 23 | 'our-projects': { 24 | core: 'Core projects', 25 | umbrella: 'OpenIPC umbrella projects', 26 | }, 27 | 'our-channels': { 28 | chat: 'Chat in browser', 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /src/views/layout/header/dropdown/dropdown.css: -------------------------------------------------------------------------------- 1 | .dropdown { 2 | display: flex; 3 | flex-flow: column; 4 | justify-content: flex-start; 5 | gap: 10px; 6 | padding: 8px 0; 7 | margin: 0; 8 | position: absolute; 9 | right: 0; 10 | top: 30px; 11 | list-style: none; 12 | background: var(--blue); 13 | border-radius: 4px; 14 | border: 1px solid var(--blue); 15 | border-top: none; 16 | 17 | &_show { 18 | display: flex; 19 | } 20 | 21 | &_hide { 22 | display: none 23 | } 24 | 25 | &__item { 26 | width: min-content; 27 | } 28 | 29 | &__link { 30 | display: inline-block; 31 | width: max-content; 32 | height: 24px; 33 | padding: 4px 16px; 34 | margin: 0; 35 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 36 | text-decoration: none; 37 | color: var(--white); 38 | opacity: .55; 39 | transition: opacity .2s ease-in; 40 | 41 | &:hover { 42 | opacity: .8; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/views/ui/donate-banner/donate-banner.css: -------------------------------------------------------------------------------- 1 | .donate-us { 2 | width: 100%; 3 | margin: 0; 4 | padding: 26px 0; 5 | 6 | &__wrapper { 7 | background: var(--blue-like-bg); 8 | border-radius: 6px; 9 | border: 1px solid var(--lines-grey); 10 | } 11 | 12 | &__content { 13 | padding: 22px 0; 14 | margin: 0 auto; 15 | width: min(100%, 610px); 16 | display: flex; 17 | flex-flow: row wrap; 18 | place-content: center center; 19 | gap: 20px; 20 | } 21 | 22 | &__button { 23 | display: flex; 24 | flex-flow: column; 25 | place-content: center center; 26 | } 27 | 28 | &__text-header { 29 | margin: 0; 30 | padding: 0 0 10px 0; 31 | color: var(--deep-blue-text); 32 | font: normal normal 24px/1.1 'IBM Plex Sans', sans-serif; 33 | } 34 | 35 | &__text-body { 36 | margin: 0; 37 | padding: 0; 38 | color: var(--deep-blue-text); 39 | font: normal normal 16px/1.1 'IBM Plex Sans', sans-serif; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/views/content/our-team/our-team.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagLink } from '../../ui/parag-link/parag-link'; 3 | import { TeamCard } from '../../ui/team-card/team-card'; 4 | import { IntroductionMainLink } from '../../ui/links/introduction-main-links/introduction-main-link'; 5 | import { DonateBanner } from '../../ui/donate-banner/donate-banner'; 6 | import OTtexts from '../../../shared/constants/our-team/texts'; 7 | import team from '../../../shared/constants/our-team/team'; 8 | import './our-team.css'; 9 | 10 | export interface Person { 11 | nick: string 12 | descr: string 13 | img: string 14 | githubNick: string 15 | telegramNick: string 16 | } 17 | 18 | export const OurTeam = { 19 | view: () => [ 20 | m('section.our-team', 21 | m('article.team', [ 22 | m(ParagLink, { text: OTtexts['our-team'], pClass: 'team__intro' }), 23 | m('ul.team__list', 24 | team.map((person: Person) => m(TeamCard, { person })) 25 | ), 26 | m(IntroductionMainLink, { label: 'View list of all contributors' }), 27 | ]), 28 | ), 29 | m(DonateBanner), 30 | ], 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 OpenIPC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/views/ui/buttons/header-button/header-button.css: -------------------------------------------------------------------------------- 1 | .header-button { 2 | background: none; 3 | border: none; 4 | outline: none; 5 | font: normal normal 16px/1.1 sans-serif; 6 | color: var(--white); 7 | opacity: .55; 8 | transition: opacity .2s ease-in; 9 | margin: 0; 10 | padding: 0; 11 | font: normal normal 16px/1.1 'IBM Plex Sans', sans-serif; 12 | 13 | &:hover { 14 | cursor: pointer; 15 | color: var(--white); 16 | opacity: .8; 17 | } 18 | 19 | & > svg { 20 | width: 10px; 21 | height: 8px; 22 | margin: 0 0 0 3px; 23 | } 24 | 25 | &_clicked > svg { 26 | animation: triangle-rotate .4s linear forwards; 27 | } 28 | 29 | &_unclicked > svg { 30 | transform: translateY(-2px); 31 | animation: triangle-rotate-back .4s linear forwards; 32 | } 33 | } 34 | 35 | @keyframes triangle-rotate { 36 | from { 37 | transform: rotate(0); 38 | } 39 | 40 | to { 41 | transform: rotate(-180deg); 42 | } 43 | } 44 | 45 | @keyframes triangle-rotate-back { 46 | from { 47 | transform: rotate(-180deg); 48 | } 49 | 50 | to { 51 | transform: rotate(0); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/views/ui/socs/soc/soc.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import socsIcons from '../../../../shared/icons/socs-info/socs-icons'; 3 | 4 | import './soc.css'; 5 | 6 | export const Soc = { 7 | view: ({ attrs: { soc }}) => { 8 | const { 9 | stage, 10 | socModel, 11 | docs, 12 | uBoot, 13 | linux, 14 | sdk, 15 | loadAddress, 16 | buildStatus, 17 | } = soc; 18 | 19 | return m('ul.soc', [ 20 | m('li.soc__cell', m.trust(socsIcons[stage.toLowerCase()])), 21 | m('li.soc__cell', socModel), 22 | m('li.soc__cell', 23 | docs ? m.trust(socsIcons.infoFrame) : m.trust(socsIcons.emptyFrame) 24 | ), 25 | m('li.soc__cell', 26 | uBoot ? m.trust(socsIcons.downArrowFrame) : m.trust(socsIcons.emptyFrame) 27 | ), 28 | m('li.soc__cell', 29 | linux ? m.trust(socsIcons.downArrowFrame) : m.trust(socsIcons.emptyFrame) 30 | ), 31 | m('li.soc__cell', 32 | sdk ? m.trust(socsIcons.downArrowFrame) : m.trust(socsIcons.emptyFrame) 33 | ), 34 | m('li.soc__cell', loadAddress), 35 | m('li.soc__cell', 'buildStatus'), 36 | ]) 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /src/views/ui/team-card/team-card.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import socialIcons from '../../../shared/icons/socials'; 3 | import { Person } from '../../content/our-team/our-team'; 4 | import './team-card.css'; 5 | 6 | export const TeamCard = { 7 | view: ({ attrs: { person }}: { attrs: { person: Person }}) => 8 | m('li.team-card', [ 9 | m('img.team-card__img', { 10 | src: person.img, 11 | alt: 'Person picture', 12 | }), 13 | m('.team-card__body', [ 14 | m('h5.team-card__nick', person.nick), 15 | m('p.team-card__descr', person.descr), 16 | m('ul.team-card__socials', [ 17 | m('li.team-card__social', 18 | m('a.team-card__social-link', { 19 | href: `https://github.com/${person.githubNick}`, 20 | }, 21 | m.trust(socialIcons.github), 22 | ), 23 | ), 24 | m('li.team-card__social', 25 | m('a.team-card__social-link', { 26 | href: `https://t.me/${person.telegramNick}`, 27 | }, 28 | m.trust(socialIcons.telegram), 29 | ), 30 | ), 31 | ]), 32 | ]), 33 | ]), 34 | } 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openipc-interface", 3 | "type": "commonjs", 4 | "packageManager": "yarn@4.2.1", 5 | "scripts": { 6 | "dev": "webpack serve --mode development -o ./public -d eval-source-map", 7 | "build": "webpack --mode production -o ./build && cp -r ./public/supporters ./build", 8 | "deploy": "corepack enable && yarn install && yarn build && tar cfz build.tgz build" 9 | }, 10 | "dependencies": { 11 | "@types/mithril": "^2.0.11", 12 | "mithril": "^2.2.2" 13 | }, 14 | "devDependencies": { 15 | "@babel/core": "^7.18.9", 16 | "babel-loader": "^8.2.5", 17 | "css-loader": "^6.7.1", 18 | "css-modules-typescript-loader": "^4.0.1", 19 | "html-webpack-plugin": "^5.6.0", 20 | "path": "^0.12.7", 21 | "postcss": "^8.4.14", 22 | "postcss-loader": "^7.0.1", 23 | "postcss-mixins": "^9.0.3", 24 | "postcss-nested": "^5.0.6", 25 | "postcss-preset-env": "^7.7.2", 26 | "postcss-simple-vars": "^6.0.3", 27 | "style-loader": "^3.3.1", 28 | "svg-inline-loader": "^0.8.2", 29 | "ts-loader": "^9.3.1", 30 | "typescript": "^4.7.4", 31 | "webpack": "^5.73.0", 32 | "webpack-cli": "^4.10.0", 33 | "webpack-dev-server": "^4.9.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/views/ui/calc-partit-chart/calc-partit-chart.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | 3 | import './calc-partit-chart.css'; 4 | 5 | interface ICalcPartitChart { 6 | attrs: { 7 | fSize: number 8 | p1Size: number 9 | p2Size: number 10 | p3Size: number 11 | p4Size: number 12 | p5Size?: number 13 | } 14 | } 15 | 16 | export const CalcPartitChart = { 17 | view: ({ attrs: { fSize, p1Size, p2Size, p3Size, p4Size, p5Size }}: ICalcPartitChart) => 18 | m('.calc-partit-chart', 19 | m('.calc-partit-chart__wrapper', [ 20 | m('.calc-partit-chart__p1-size', { 21 | style: `flex: 0 0 ${p1Size / fSize * 100}%;`, 22 | }), 23 | m('.calc-partit-chart__p2-size', { 24 | style: `flex: 0 0 ${p2Size / fSize * 100}%;`, 25 | }), 26 | m('.calc-partit-chart__p3-size', { 27 | style: `flex: 0 0 ${p3Size / fSize * 100}%;`, 28 | }), 29 | m('.calc-partit-chart__p4-size', { 30 | style: `flex: 0 0 ${p4Size / fSize * 100}%;`, 31 | }), 32 | m('.calc-partit-chart__p5-size', { 33 | style: `flex: 0 0 ${p5Size ? (p5Size / fSize * 100) : ((fSize - (p1Size + p2Size + p3Size + p4Size)) / fSize * 100)}%;`, 34 | }), 35 | ]), 36 | ), 37 | } 38 | -------------------------------------------------------------------------------- /src/views/content/our-projects/our-projects.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagraphTitle } from '../../ui/titles/paragraph-title/paragraph-title'; 3 | import { ProjectItem } from '../../ui/project-item/project-item'; 4 | import { DonateBanner } from '../../ui/donate-banner/donate-banner'; 5 | 6 | import { paragraphTitles } from '../../../shared/constants/titles'; 7 | import { ourProjects } from '../../../shared/constants/our-projects/our-projects'; 8 | 9 | import './our-projects.css'; 10 | 11 | export const OurProjects = { 12 | view: ({ attrs : { pageTitle }} : { attrs: { pageTitle: string }}) => 13 | m('.our-projects', [ 14 | m('section.core', [ 15 | m(ParagraphTitle, { title: paragraphTitles[pageTitle].core }), 16 | m('dl.projects-list', 17 | ourProjects.core.map((el) => 18 | m(ProjectItem, { link: el.link, title: el.title, description: el.description })), 19 | ), 20 | ]), 21 | m('section.umbrella', [ 22 | m(ParagraphTitle, { title: paragraphTitles[pageTitle].umbrella }), 23 | m('p.umbrella__mention', ourProjects.mention.content), 24 | m('dl.projects-list', 25 | ourProjects.umbrella.map((el) => 26 | m(ProjectItem, { link: el.link, title: el.title, description: el.description })), 27 | ), 28 | ]), 29 | m(DonateBanner), 30 | ]), 31 | }; 32 | -------------------------------------------------------------------------------- /src/views/content/our-channels/our-channels.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagraphTitle } from '../../ui/titles/paragraph-title/paragraph-title'; 3 | import { ProjectItem } from '../../ui/project-item/project-item'; 4 | import { DonateBanner } from '../../ui/donate-banner/donate-banner'; 5 | import { ChatBanner } from '../../ui/chat-banner/chat-banner'; 6 | 7 | import { ourChannels } from '../../../shared/constants/our-channels/our-channels'; 8 | import {paragraphTitles} from '../../../shared/constants/titles'; 9 | 10 | import './our-channels.css'; 11 | 12 | export const OurChannels = { 13 | view: ({ attrs : { pageTitle }} : { attrs: { pageTitle: string }}) => 14 | m('.our-channels', [ 15 | m('section.channels', 16 | m('dl.projects-list', 17 | ourChannels.channels.map((el) => 18 | m(ProjectItem, { 19 | link: el.link, 20 | title: el.title, 21 | description: el.description } 22 | ) 23 | ), 24 | ), 25 | ), 26 | m('section.chats', 27 | m(ParagraphTitle, { title: paragraphTitles[pageTitle].chat }), 28 | m('.chats__banners', 29 | ourChannels.banners.map((chat) => 30 | m(ChatBanner, { 31 | title: chat.title, 32 | link: chat.link, 33 | }), 34 | ), 35 | ), 36 | ), 37 | m(DonateBanner), 38 | ]), 39 | } 40 | -------------------------------------------------------------------------------- /src/views/ui/socials/socials.css: -------------------------------------------------------------------------------- 1 | .socials { 2 | margin: 0; 3 | padding: 0; 4 | width: max-content; 5 | list-style: none; 6 | display: flex; 7 | flex-flow: row nowrap; 8 | justify-content: flex-start; 9 | align-items: center; 10 | 11 | &__item { 12 | margin: 0; 13 | padding: 0; 14 | width: 40px; 15 | height: 36px; 16 | transition: border .2s ease-in; 17 | border: 1px solid var(--grey-bg); 18 | display: flex; 19 | flex-flow: row; 20 | justify-content: center; 21 | align-items: center; 22 | 23 | &:first-child { 24 | border: 1px solid var(--grey-bg); 25 | border-radius: 4px 0 0 4px; 26 | } 27 | 28 | &:hover:first-child { 29 | border: 1px solid var(--black); 30 | border-radius: 4px 0 0 4px; 31 | } 32 | 33 | &:last-child { 34 | border: 1px solid var(--grey-bg); 35 | border-radius: 0px 4px 4px 0; 36 | } 37 | 38 | &:hover:last-child { 39 | border: 1px solid var(--black); 40 | border-radius: 0px 4px 4px 0; 41 | } 42 | 43 | &:hover { 44 | border: 1px solid var(--black); 45 | } 46 | } 47 | 48 | &__link { 49 | display: flex; 50 | justify-content: center; 51 | align-items: center; 52 | text-decoration: none; 53 | height: 37px; 54 | width: 41px; 55 | overflow: hidden; 56 | } 57 | 58 | &__link > svg { 59 | fill: black; 60 | width: 16px; 61 | height: 16px; 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const postcssConfig = require('./postcss.config.js'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | module.exports = { 6 | context: path.resolve('src'), 7 | entry: '/index.ts', 8 | output: { 9 | filename: 'app.js', 10 | }, 11 | plugins: [new HtmlWebpackPlugin()], 12 | devServer: { 13 | static: { 14 | directory: path.join(__dirname, 'public'), 15 | }, 16 | compress: true, 17 | port: 3000, 18 | historyApiFallback: true, 19 | }, 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.ts$/, 24 | use: 'ts-loader', 25 | exclude: /node_modules/, 26 | }, 27 | { 28 | test: /\.m?js$/, 29 | exclude: /node_modules/, 30 | use: { 31 | loader: "babel-loader", 32 | options: { 33 | presets: ['@babel/preset-env'], 34 | }, 35 | }, 36 | }, 37 | { 38 | test: /\.css$/i, 39 | use: [ 40 | "style-loader", 41 | "css-loader", 42 | { 43 | loader: "postcss-loader", 44 | options: { 45 | postcssOptions: postcssConfig, 46 | }, 47 | }, 48 | ], 49 | }, 50 | { 51 | test: /\.svg$/i, 52 | loader: 'svg-inline-loader', 53 | }, 54 | ], 55 | }, 56 | resolve: { 57 | extensions: ['.ts', '.js'], 58 | }, 59 | }; 60 | -------------------------------------------------------------------------------- /src/views/ui/team-card/team-card.css: -------------------------------------------------------------------------------- 1 | .team-card { 2 | display: flex; 3 | flex-flow: column nowrap; 4 | justify-content: flex-start; 5 | border: 1px solid var(--lines-grey); 6 | border-radius: 6px; 7 | width: 100%; 8 | 9 | &__img { 10 | width: 100%; 11 | border-top-left-radius: 4px; 12 | border-top-right-radius: 4px; 13 | } 14 | 15 | &__body { 16 | padding: 16px; 17 | position: relative; 18 | } 19 | 20 | &__nick { 21 | margin: 0; 22 | padding: 0 0 8px 0; 23 | font: normal normal 20px/1.2 'IBM Plex Sans', sans-serif; 24 | } 25 | 26 | &__descr { 27 | margin: 0; 28 | padding: 0 0 16px 0; 29 | font: normal normal 14px/1.2 'IBM Plex Sans', sans-serif; 30 | } 31 | 32 | &__socials { 33 | margin: 0; 34 | padding: 0; 35 | display: flex; 36 | flex-flow: row nowrap; 37 | gap: 0 2px; 38 | width: max-content; 39 | list-style: none; 40 | position: absolute; 41 | top: -14px; 42 | right: 6px; 43 | background: transparent; 44 | } 45 | 46 | &__social { 47 | margin: 0; 48 | padding: 0; 49 | } 50 | 51 | &__social-link { 52 | margin: 0; 53 | padding: 0; 54 | display: block; 55 | height: 24px; 56 | width: 24px; 57 | display: flex; 58 | justify-content: center; 59 | align-items: center; 60 | border-radius: 50%; 61 | background: var(--white); 62 | } 63 | 64 | &__social-link > svg { 65 | color: black; 66 | width: 20px; 67 | height: 20px; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/shared/constants/supporters.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | src: 'osc_mini.png', 4 | href: '', 5 | }, 6 | { 7 | src: 'skycam_mini.png', 8 | href: '', 9 | }, 10 | { 11 | src: 'gain_mini.png', 12 | href: '', 13 | }, 14 | { 15 | src: 'dvor24_mini.png', 16 | href: '', 17 | }, 18 | { 19 | src: 'goodcam_mini.png', 20 | href: '', 21 | }, 22 | { 23 | src: 'ipeye_mini.png', 24 | href: '', 25 | }, 26 | { 27 | src: 'lifecontrol_mini.png', 28 | href: '', 29 | }, 30 | { 31 | src: 'megacam_mini.png', 32 | href: '', 33 | }, 34 | { 35 | src: 'mywifi-cc_mini.png', 36 | href: '', 37 | }, 38 | { 39 | src: 'keytelecom_mini.png', 40 | href: '', 41 | }, 42 | { 43 | src: 'sputnik_mini.png', 44 | href: '', 45 | }, 46 | { 47 | src: 'techno-shield_mini.png', 48 | href: '', 49 | }, 50 | { 51 | src: 'vixand_mini.png', 52 | href: '', 53 | }, 54 | { 55 | src: 'webglazok_mini.png', 56 | href: '', 57 | }, 58 | { 59 | src: 'yucca_mini.png', 60 | href: '', 61 | }, 62 | { 63 | src: 's-video_mini.png', 64 | href: '', 65 | }, 66 | { 67 | src: 'linuxchenxing_mini.png', 68 | href: '', 69 | }, 70 | { 71 | src: 'ufanet_mini.png', 72 | href: '', 73 | }, 74 | { 75 | src: 'vtl_mini.png', 76 | href: '', 77 | }, 78 | { 79 | src: 'dozor_mini.png', 80 | href: '', 81 | }, 82 | { src: 'alarmsystem_mini.png', 83 | href: '', 84 | }, 85 | { 86 | src: 'binary-machines_mini.png', 87 | href: '', 88 | }, 89 | , 90 | ]; 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## OpenIPC Common Interface Prototype 2 | 3 | This is the source code for the proposal variant of current [OpenIPC](https://openipc.org) official web site. 4 | 5 | It reproduces the current [OpenIPC](https://openipc.org) site design and layout as long as its content. 6 | 7 | Follow the link https://openipc.org to observ its actual state. 8 | 9 | 10 | ### Technical details 11 | This site is made using [Mithril.js](mithril.js.org) framework with intent to increase development process and further maintainability. 12 | 13 | The site is suituble for all screen resolutions and provide convenient modern user interface. 14 | 15 | However yor're welcome to point out to potential or explicit bugs if you happened to find ones. 16 | 17 | 18 | ### Running the site 19 | You can obtain local copy of the site and running it on your machine. Just follow these steps: 20 | 21 | Be sure you have recent version of `yarn`, use `yarn --version`. 22 | 23 | If `yarn` is not installed on your system, install it by running `npm install --global yarn` and go on: 24 | 25 | ``` 26 | git clone https://github.com/openipc/interface 27 | cd interface 28 | yarn install 29 | yarn run dev 30 | ``` 31 | 32 | You should now have a development server running at localhost:3000 33 | 34 | 35 | ### Troubleshooting 36 | 37 | If after you have installed all dependencies you still have problems with starting the site, try to delete `node_modules` folder in project root directory and run `yarn install` again. 38 | 39 | If errors still exist feel free to inform maintainer via email puer.robustus@gmail.com or [Telegram](https://t.me/LaikaPanda). 40 | 41 | -------------------------------------------------------------------------------- /src/shared/constants/supported-hardware/socs.ts: -------------------------------------------------------------------------------- 1 | export const socs = { 2 | 'Ambarella': [{ 3 | stage: 'NEQ', 4 | socModel: 'Ambarella S2L', 5 | docs: undefined, 6 | uBoot: undefined, 7 | linux: undefined, 8 | sdk: undefined, 9 | loadAddress: undefined, 10 | buildStatus: undefined, 11 | }, 12 | { 13 | stage: 'NEQ', 14 | socModel: 'Ambarella S3L', 15 | docs: undefined, 16 | uBoot: undefined, 17 | linux: 's3l', 18 | sdk: 's3l', 19 | loadAddress: undefined, 20 | buildStatus: undefined, 21 | } 22 | ], 23 | 'Anyka': [{ 24 | stage: 'WIP', 25 | socModel: 'Anyka AK3916EV300', 26 | docs: undefined, 27 | uBoot: undefined, 28 | linux: 'ak3916ev300', 29 | sdk: 'ak3916ev300', 30 | loadAddress: undefined, 31 | buildStatus: undefined, 32 | }, 33 | { 34 | stage: 'HLP', 35 | socModel: 'Anyka AK3918EV200', 36 | docs: undefined, 37 | uBoot: undefined, 38 | linux: undefined, 39 | sdk: 'ak3918ev200', 40 | loadAddress: '0x81808000', 41 | buildStatus: undefined, 42 | } 43 | ], 44 | 'Goke': [{ 45 | stage: 'WIP', 46 | socModel: 'Goke GK7202V300', 47 | docs: 'gk7202v300', 48 | uBoot: 'gk7202v300', 49 | linux: 'gk7202v300', 50 | sdk: 'gk7202v300', 51 | loadAddress: '0x42000000', 52 | buildStatus: undefined, 53 | }, 54 | { 55 | stage: 'HLP', 56 | socModel: 'Goke GK7205V200', 57 | docs: 'gk7205v200', 58 | uBoot: 'gk7205v200', 59 | linux: 'gk7205v200', 60 | sdk: 'gk7205v200', 61 | loadAddress: '0x42000000', 62 | buildStatus: undefined, 63 | } 64 | ], 65 | }; 66 | -------------------------------------------------------------------------------- /src/views/ui/socs-mobile/soc-mobile/soc-mobile.css: -------------------------------------------------------------------------------- 1 | .soc-mobile { 2 | margin: 0; 3 | padding: 0; 4 | 5 | &__content { 6 | margin: 0; 7 | padding: 0; 8 | border: 1px solid var(--light-grey); 9 | display: grid; 10 | gap: 4px; 11 | grid-template-areas: 12 | "a b b b" 13 | "c d e f" 14 | "g g h h"; 15 | grid-template-rows: 1fr 1fr 1fr; 16 | grid-template-columns: 1fr 1fr 1fr 1fr; 17 | } 18 | 19 | &__wrapper { 20 | box-sizing: border-box; 21 | background: var(--grey-bg); 22 | padding: 4px 0 4px 0; 23 | margin: 0; 24 | width: 100%; 25 | height: 100%; 26 | display: flex; 27 | flex-flow: column; 28 | justify-content: space-between; 29 | align-items: center; 30 | } 31 | 32 | &__wrapper:nth-child(1) { 33 | grid-area: a; 34 | } 35 | 36 | &__wrapper:nth-child(2) { 37 | grid-area: b; 38 | } 39 | 40 | &__wrapper:nth-child(3) { 41 | grid-area: c; 42 | } 43 | 44 | &__wrapper:nth-child(4) { 45 | grid-area: d; 46 | } 47 | 48 | &__wrapper:nth-child(5) { 49 | grid-area: e; 50 | } 51 | 52 | &__wrapper:nth-child(6) { 53 | grid-area: f; 54 | } 55 | 56 | &__wrapper:nth-child(7) { 57 | grid-area: g; 58 | } 59 | 60 | &__wrapper:nth-child(8) { 61 | grid-area: h; 62 | } 63 | 64 | &__term { 65 | padding: 0 0 4px 0; 66 | font: normal 500 14px/1.2 'IBM Plex Sans', sans-serif; 67 | } 68 | 69 | &__descr { 70 | margin: 0; 71 | height: 100%; 72 | display: flex; 73 | flex-flow: column nowrap; 74 | justify-content: center; 75 | align-items: center; 76 | } 77 | 78 | &__descr > svg { 79 | width: 30px; 80 | height: 30px; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/views/content/support-open-source/support-open-source.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagraphTitle } from '../../ui/titles/paragraph-title/paragraph-title'; 3 | import { paragraphTitles } from '../../../shared/constants/titles'; 4 | import { ParagLink } from '../../ui/parag-link/parag-link'; 5 | import SOSTexts from '../../../shared/constants/support-open-source/texts'; 6 | 7 | import './support-open-source.css'; 8 | 9 | export const SupportOpenSource = { 10 | view: ({ attrs: { pageTitle }}) => 11 | m('section.support-open-source', [ 12 | m('div.sos-illustration', 13 | m('img.sos-illustration__picture[src=https://openipc.org/assets/ninja-sponsors.webp]') 14 | ), 15 | m('div.sos-text', [ 16 | m(ParagraphTitle, { title: paragraphTitles[pageTitle].become }), 17 | m('h3.sos-text__h3', SOSTexts.sponsor.header3), 18 | m('p.sos-text__p', SOSTexts.sponsor.p1), 19 | m('p.sos-text__p', SOSTexts.sponsor.p2), 20 | m('p.sos-text__p', SOSTexts.sponsor.p3), 21 | m('p.sos-text__p', SOSTexts.sponsor.p4), 22 | m('p.sos-text__p', SOSTexts.sponsor.p5), 23 | m('p.sos-text__p', SOSTexts.sponsor.p6), 24 | m('p.sos-text__p', SOSTexts.sponsor.p1), 25 | m(ParagLink, { text: SOSTexts.sponsor.p7, pClass: 'sos-text__p' }), 26 | m(ParagraphTitle, { title: paragraphTitles[pageTitle].donations }), 27 | m(ParagLink, { text: SOSTexts.donations.p1, pClass: 'sos-text__p' }), 28 | m('a[href=https://opencollective.com/openipc/contribute/backer-14335/checkout]', 29 | m('img[src=https://opencollective.com/webpack/donate/button.png?color=blue]'), 30 | ), 31 | m('h4.sos-text__h4', SOSTexts.donations.thanks), 32 | ]), 33 | ]), 34 | } 35 | -------------------------------------------------------------------------------- /src/views/layout/header/mobile-routes/mobile-routes.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { HeaderButton } from '../../../ui/buttons/header-button/header-button'; 3 | import { MobileDropdown } from '../mobile-dropdown/mobile-dropdown'; 4 | import { HeaderLink } from '../../../ui/links/header-link/header-link'; 5 | 6 | export const MobileRoutes = { 7 | openedDropdowns: [], 8 | toggleDropdown: (e: any) => { 9 | if (MobileRoutes.openedDropdowns.includes(e.target.name)) 10 | MobileRoutes.openedDropdowns = MobileRoutes.openedDropdowns.filter((elName: string) => 11 | elName !== e.target.name); 12 | else 13 | MobileRoutes.openedDropdowns.push(e.target.name); 14 | }, 15 | view: ({ attrs: { navElements, isOpen }}) => { 16 | if (!isOpen) MobileRoutes.openedDropdowns = []; 17 | return m('ul.header__routes.header__routes_mobile', 18 | { class: isOpen ? 'header__routes_mobile_open' : 'header__routes_mobile_close' }, 19 | navElements.map((el: {}) => { 20 | const isNestedElement = typeof el[Object.keys(el)[0]] !== 'string'; 21 | const elementName = Object.keys(el)[0]; 22 | return !isNestedElement 23 | ? m('li.header__route', 24 | m(HeaderLink, { label: elementName, href: el[elementName] }) 25 | ) 26 | : m('li.header__route.header__route_nested', [ 27 | m(HeaderButton, { 28 | label: elementName, 29 | clickHandler: MobileRoutes.toggleDropdown 30 | }), 31 | m(MobileDropdown, { 32 | navElements: el[elementName], 33 | isOpen: MobileRoutes.openedDropdowns.includes(elementName) 34 | }), 35 | ]) 36 | }) 37 | ); 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /src/views/content/introduction/introduction.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { ParagraphTitle } from '../../ui/titles/paragraph-title/paragraph-title'; 3 | import { IntroductionMainLink } from '../../ui/links/introduction-main-links/introduction-main-link'; 4 | import { Alliance } from './alliance/alliance'; 5 | import { Supporters } from './supporters/supporters'; 6 | import { paragraphTitles } from '../../../shared/constants/titles'; 7 | import { ParagLink } from '../../ui/parag-link/parag-link'; 8 | import supporters from '../../../shared/constants/supporters'; 9 | import texts from '../../../shared/constants/texts'; 10 | 11 | import './introduction.css'; 12 | 13 | export const Introduction = { 14 | view: ({ attrs: { pageTitle }}) => 15 | m('.introduction', [ 16 | m('section.introduction__main', [ 17 | m(ParagraphTitle, { title: paragraphTitles[pageTitle].open }), 18 | m('p.main-text', texts.introduction.open.p1), 19 | m(ParagLink,{ text: texts.introduction.open.p2, pClass: 'main-text'}), 20 | m('.main-links', [ 21 | m(IntroductionMainLink, { label: 'Get binary files' }), 22 | m(IntroductionMainLink, { label: 'View source code' }), 23 | ]), 24 | m(ParagLink,{ text: texts.introduction.open.p3, pClass: 'main-text' }), 25 | m(ParagraphTitle, { title: paragraphTitles[pageTitle].why }), 26 | m('p.main-text', texts.introduction.why.p1), 27 | m('p.main-text', texts.introduction.why.p2), 28 | m('p.main-text', texts.introduction.why.p3), 29 | ]), 30 | m('section.introduction__collab', [ 31 | m(Alliance, { title: paragraphTitles[pageTitle].alliance }), 32 | m(Supporters, { title: paragraphTitles[pageTitle].supporters, supporters: supporters }), 33 | ]), 34 | ]), 35 | }; 36 | -------------------------------------------------------------------------------- /src/views/ui/letters/letters.css: -------------------------------------------------------------------------------- 1 | .letters { 2 | width: min(100%, 420px); 3 | padding: 0 0 25px 0; 4 | 5 | &__list { 6 | margin: 0; 7 | padding: 0; 8 | list-style: none; 9 | display: flex; 10 | flex-flow: row nowrap; 11 | font: normal 500 20px/1.2 'IBM Plex Sans', sans-serif; 12 | border-bottom: 1px solid var(--lines-grey); 13 | } 14 | 15 | &__letter { 16 | margin: 0; 17 | padding: 0; 18 | flex: 1 1 auto; 19 | display: flex; 20 | flex-flow: row; 21 | justify-content: center; 22 | } 23 | 24 | &__link { 25 | display: block; 26 | flex: 1 1 auto; 27 | text-align: center; 28 | box-sizing: border-box; 29 | padding: 8px 0; 30 | margin: 0 0 -1px 0; 31 | text-decoration: none; 32 | color: var(--button-blue); 33 | border: 1px solid var(--white); 34 | border-bottom: 1px solid var(--lines-grey); 35 | position: relative; 36 | 37 | &::after { 38 | content: ''; 39 | border-bottom: 1px solid var(--lines-grey); 40 | position: absolute; 41 | left: -1px; 42 | right: -1px; 43 | top: 0; 44 | bottom: -1px; 45 | } 46 | 47 | &:hover { 48 | border: 1px solid var(--lines-grey); 49 | border-bottom: 1px solid var(--white); 50 | border-top-left-radius: 6px; 51 | border-top-right-radius: 6px; 52 | } 53 | 54 | &:hover { 55 | color: var(--button-blue-hover); 56 | } 57 | 58 | &_choosen { 59 | border-top-left-radius: 6px; 60 | border-top-right-radius: 6px; 61 | border: 1px solid var(--lines-grey); 62 | border-bottom: 1px solid var(--white); 63 | 64 | &::after { 65 | content: ''; 66 | border-bottom: 1px solid var(--white); 67 | position: absolute; 68 | left: 0; 69 | right: 0; 70 | top: 0; 71 | bottom: -1px; 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/shared/constants/our-team/team.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | "nick": "FlyRouter", 4 | "descr": "Project Coordination, Documentation", 5 | "img": "https://avatars.githubusercontent.com/u/88846", 6 | "githubNick": "ZigFisher", 7 | "telegramNick": "FlyRouter", 8 | }, 9 | { 10 | "nick": "widgetii", 11 | "descr": "Majestic Streamer, IPCtool", 12 | "img": "https://avatars.githubusercontent.com/u/6576495", 13 | "githubNick": "widgetii", 14 | "telegramNick": "widgetii", 15 | }, 16 | { 17 | "nick": "dimerrr", 18 | "descr": "U-Boot, Kernels, Coupler, IPCtool", 19 | "img": "https://avatars.githubusercontent.com/u/106577375", 20 | "githubNick": "dimerrr", 21 | "telegramNick": "dimerrr", 22 | }, 23 | { 24 | "nick": "John", 25 | "descr": "Linux", 26 | "img": "https://avatars.githubusercontent.com/u/21039610", 27 | "githubNick": "p0i5k", 28 | "telegramNick": "p0i5k", 29 | }, 30 | { 31 | "nick": "Hirrolot", 32 | "descr": "SmolRTSP", 33 | "img": "https://avatars.githubusercontent.com/u/40539574", 34 | "githubNick": "Hirrolot", 35 | "telegramNick": "hirrolot", 36 | }, 37 | { 38 | "nick": "cronyx", 39 | "descr": "Linux", 40 | "img": "https://avatars.githubusercontent.com/u/2557102", 41 | "githubNick": "cronyx", 42 | "telegramNick": "cronyx", 43 | }, 44 | { 45 | "nick": "chertov", 46 | "descr": "Mini Streamer", 47 | "img": "https://avatars.githubusercontent.com/u/436625", 48 | "githubNick": "chertov", 49 | "telegramNick": "mAX3773", 50 | }, 51 | { 52 | "nick": "SSharshunov", 53 | "descr": "The ex researcher", 54 | "img": "https://avatars.githubusercontent.com/u/2909755", 55 | "githubNick": "SSharshunov", 56 | "telegramNick": "USSSSSH", 57 | }, 58 | { 59 | "nick": "themactep", 60 | "descr": "Project Coordination, Documentation", 61 | "img": "https://avatars.githubusercontent.com/u/37488", 62 | "githubNick": "themactep", 63 | "telegramNick": "themactep", 64 | }, 65 | ] 66 | -------------------------------------------------------------------------------- /src/shared/constants/support-open-source/texts.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | sponsor: { 3 | header3: 'Let\'s support open-source cameras together!', 4 | p1: 'OpenIPC is asking your to support our development, to help us to attract enough funds to cover our expenses and secure long-term maintenance of what we believe is going to be a stable, flexible and most importantly, open source Open IP Network Camera Framework, for all users worldwide.', 5 | p2: 'The funds are generally intended to compensate the work of part-time and full-time maintainers. Many core team members contribute their knowledge and spend their free time to work on projects codebase, and often use personal funds to purchase new cameras in order to extend the poll of supported hardware. Your donation could help us to ease the burden on their personal finances while keeping the development supplied with the most modern hardware.', 6 | p3: 'We also need funds to organize meetings and attend events with hardware manufacturers, to monitor trends in cameras ingeneering and to get access to SDK and other supporting materials which are often expensive.', 7 | p4: 'Your contribution will help us advance development forward, and interact with the community on a regular basis.', 8 | p5: 'In recognition of your recurring donations, you will be permanently added to the Backers/Sponsors section on our GitHub page!', 9 | p6: 'We are committed to open and transparent accounting, and are grateful for any support you\'re able to provide for our efforts, so that we could advance OpenIPC and our mission towards a sustainable future.', 10 | p7: 'If you have issues getting access or download files, feel free to contact us on our [Telegram](https://t.me/openipc) channel.', 11 | }, 12 | donations: { 13 | p1: 'If you like our work, please consider supporting us on [Open Collective](https://opencollective.com/openipc/contribute/backer-14335/checkout)', 14 | thanks: 'Thanks you, it means a lot to us!', 15 | }, 16 | } 17 | -------------------------------------------------------------------------------- /src/shared/constants/our-channels/our-channels.ts: -------------------------------------------------------------------------------- 1 | export const ourChannels = { 2 | channels: [ 3 | { 4 | link: 'https://t.me/OpenIPC', 5 | title: 'OpenIPC (EN)', 6 | description: 'International channel about OpenIPC.', 7 | }, 8 | { 9 | link: 'https://t.me/openipc_modding', 10 | title: 'OpenIPC users (RU)', 11 | description: 'Channel about OpenIPC for Russian-speaking users.', 12 | }, 13 | { 14 | link: 'https://t.me/openipc_software', 15 | title: 'OpenIPC development (RU)', 16 | description: 'Channel for OpenIPC developers.', 17 | }, 18 | { 19 | link: 'https://t.me/joinchat/YgHc5Bg4NOoxOTdi', 20 | title: 'Majestic Tests (RU)', 21 | description: 'Telegram group for Majestic streamer testers.', 22 | }, 23 | { 24 | link: 'https://t.me/ExIPCam', 25 | title: 'ExIPCam users + repair', 26 | description: 'Discussion of the ExIPCam program and hardware/software repairing devices.', 27 | }, 28 | { 29 | link: 'https://t.me/openipc_demo', 30 | title: 'OpenIPC demo', 31 | description: 'Experimental Telegram Bot. (After connecting, send "/menu")', 32 | }, 33 | { 34 | link: 'https://paywall.pw/openipc', 35 | title: 'OpenIPC paywall', 36 | description: 'Paid technical support group.', 37 | }, 38 | { 39 | link: 'https://t.me/joinchat/T_GwQUBTJdfXJrFb', 40 | title: 'OpenIPC Iranian', 41 | description: 'م OpenIPC برای کاربران ایرانی (Telegram group for Iranian OpenIPC users).', 42 | }, 43 | { 44 | link: 'https://t.me/s/openipc_dev', 45 | title: 'OpenIPC dev', 46 | description: 'GitHub notifications on the latest Firmware & Software.', 47 | }, 48 | ], 49 | banners: [ 50 | { 51 | link: 'https://gitter.im/OpenIPC/english', 52 | title: 'OpenIPC English Chat', 53 | }, 54 | { 55 | link: 'https://gitter.im/OpenIPC/russian', 56 | title: 'OpenIPC Russian Chat', 57 | }, 58 | ], 59 | } 60 | -------------------------------------------------------------------------------- /src/views/ui/vendors/vendors.css: -------------------------------------------------------------------------------- 1 | .vendors { 2 | overflow-x: scroll; 3 | white-space: nowrap; 4 | padding: 0 0 5px 0; 5 | 6 | &::-webkit-scrollbar { 7 | width: 2px; 8 | height: 2px; 9 | background-color: var(--white); 10 | } 11 | 12 | &::-webkit-scrollbar-thumb { 13 | background: var(--lines-grey); 14 | } 15 | 16 | &__list { 17 | margin: 0; 18 | padding: 0; 19 | list-style: none; 20 | display: flex; 21 | flex-flow: row nowrap; 22 | justify-content: flex-start; 23 | border-bottom: 1px solid var(--lines-grey); 24 | } 25 | 26 | &__vendor { 27 | margin: 0; 28 | padding: 0; 29 | font: normal normal 16px/24px 'IBM Plex Sans', sans-serif; 30 | } 31 | 32 | &__link { 33 | display: block; 34 | box-sizing: border-box; 35 | min-width: max-content; 36 | margin: 0 0 -1px 0; 37 | padding: 8px 16px; 38 | text-decoration: none; 39 | color: var(--button-blue); 40 | border: 1px solid var(--white); 41 | border-bottom: 1px solid var(--lines-grey); 42 | position: relative; 43 | 44 | @media(max-width: $mobile) { 45 | padding: 8px 8px; 46 | } 47 | 48 | &::after { 49 | content: ''; 50 | border-bottom: 1px solid var(--lines-grey); 51 | position: absolute; 52 | left: -1px; 53 | right: -1px; 54 | top: 0; 55 | bottom: -1px; 56 | } 57 | 58 | &:hover { 59 | border: 1px solid var(--lines-grey); 60 | border-bottom: 1px solid var(--white); 61 | border-top-left-radius: 6px; 62 | border-top-right-radius: 6px; 63 | } 64 | 65 | &_choosen { 66 | border-top-left-radius: 6px; 67 | border-top-right-radius: 6px; 68 | border: 1px solid var(--lines-grey); 69 | border-bottom: 1px solid var(--white); 70 | 71 | &::after { 72 | content: ''; 73 | border-bottom: 1px solid var(--white); 74 | position: absolute; 75 | left: 0; 76 | right: 0; 77 | top: 0; 78 | bottom: -1px; 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/views/ui/socs-mobile/soc-mobile/soc-mobile.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import socsIcons from '../../../../shared/icons/socs-info/socs-icons'; 3 | 4 | import './soc-mobile.css'; 5 | 6 | export const SocMobile = { 7 | view: ({ attrs: { soc }}) => { 8 | const { 9 | stage, 10 | socModel, 11 | docs, 12 | uBoot, 13 | linux, 14 | sdk, 15 | loadAddress, 16 | buildStatus, 17 | } = soc; 18 | 19 | return m('li.soc-mobile', [ 20 | m('dl.soc-mobile__content', 21 | m('.soc-mobile__wrapper', 22 | m('dt.soc-mobile__term', 'Stage'), 23 | m('dd.soc-mobile__descr', m.trust(socsIcons[stage.toLowerCase()])), 24 | ), 25 | m('.soc-mobile__wrapper', 26 | m('dt.soc-mobile__term', 'SoC Model'), 27 | m('dd.soc-mobile__descr', socModel), 28 | ), 29 | m('.soc-mobile__wrapper', 30 | m('dt.soc-mobile__term', 'Docs'), 31 | m('dd.soc-mobile__descr', docs ? m.trust(socsIcons.infoFrame) : m.trust(socsIcons.emptyFrame)), 32 | ), 33 | m('.soc-mobile__wrapper', 34 | m('dt.soc-mobile__term', 'U-Boot'), 35 | m('dd.soc-mobile__descr', uBoot ? m.trust(socsIcons.downArrowFrame) : m.trust(socsIcons.emptyFrame)), 36 | ), 37 | m('.soc-mobile__wrapper', 38 | m('dt.soc-mobile__term', 'Linux'), 39 | m('dd.soc-mobile__descr', linux ? m.trust(socsIcons.downArrowFrame) : m.trust(socsIcons.emptyFrame)), 40 | ), 41 | m('.soc-mobile__wrapper', 42 | m('dt.soc-mobile__term', 'SDK'), 43 | m('dd.soc-mobile__descr', sdk ? m.trust(socsIcons.downArrowFrame) : m.trust(socsIcons.emptyFrame)), 44 | ), 45 | m('.soc-mobile__wrapper', 46 | m('dt.soc-mobile__term', 'Load address'), 47 | m('dd.soc-mobile__descr', loadAddress), 48 | ), 49 | m('.soc-mobile__wrapper', 50 | m('dt.soc-mobile__term', 'Build status'), 51 | m('dd.soc-mobile__descr', 'buildStatus'), 52 | ), 53 | ), 54 | ]); 55 | }, 56 | } 57 | -------------------------------------------------------------------------------- /src/views/layout/header/header.css: -------------------------------------------------------------------------------- 1 | .header { 2 | width: 100%; 3 | background: var(--blue); 4 | 5 | &__navigation { 6 | width: min(calc(100vw - 20px), 1440px); 7 | height: 58px; 8 | margin: 0 auto; 9 | display: flex; 10 | flex-flow: row nowrap; 11 | } 12 | 13 | &__home { 14 | flex: 0 0 116px; 15 | display: flex; 16 | flex-flow: column nowrap; 17 | justify-content: center; 18 | } 19 | 20 | &__routes { 21 | flex: 1 1 auto; 22 | display: flex; 23 | flex-flow: row nowrap; 24 | justify-content: flex-end; 25 | align-items: center; 26 | gap: 0 16px; 27 | list-style: none; 28 | margin: 0; 29 | padding: 0; 30 | 31 | &_mobile { 32 | width: min(calc(100vw - 20px), 1440px); 33 | margin: 0 auto; 34 | padding: 0; 35 | display: flex; 36 | flex-flow: column; 37 | justify-content: flex-start; 38 | align-items: flex-start; 39 | gap: 22px 0; 40 | background: var(--blue); 41 | box-sizing: border-box; 42 | overflow: hidden; 43 | 44 | @media (min-width: $mobile) { 45 | display: none; 46 | } 47 | 48 | &_open { 49 | max-height: 800px; 50 | transition: max-height .5s cubic-bezier(0.67, 0.05, 0.57, 1); 51 | } 52 | 53 | &_close { 54 | max-height: 0; 55 | transition: max-height .5s cubic-bezier(0, 0.7, 0.57, 1); 56 | } 57 | } 58 | 59 | &_desktop { 60 | @media (max-width: $mobile) { 61 | display: none; 62 | } 63 | } 64 | 65 | &_burger { 66 | @media (min-width: $mobile) { 67 | display: none; 68 | } 69 | } 70 | } 71 | 72 | &__route { 73 | position: relative; 74 | color: var(--black); 75 | font: normal normal 16px/1.1 'IBM Plex Sans', sans-serif; 76 | 77 | @media(max-width: $mobile) { 78 | &:first-child { 79 | padding: 10px 0 0 0; 80 | } 81 | 82 | &:last-child { 83 | padding: 0 0 20px 0; 84 | } 85 | } 86 | } 87 | &__home > svg { 88 | width: 116px; 89 | height: 32px; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/shared/constants/texts.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | introduction: { 3 | open: { 4 | p1: 'OpenIPC is a Linux operating system targeting IP cameras with processors from several manufacturers in order to replace that closed, opaque, insecure, often abandoned and unsupported firmware pre-installed by a vendor.', 5 | p2: 'OpenIPC Firmware comes as binary pre-compiled files for easy installation by end-user. Also, we provide full access to the source files for further development and improvement by any capable programmer willing to contribute to the project. OpenIPC source code is released under one of the most simple open source license agreements: [MIT License](https://opensource.org/licenses/MIT), giving users express permission to reuse code for any purpose, even as part of a proprietary software. We only ask you politely to contribute your improvements back to us. We would be grateful for any feedback and suggestions.', 6 | p3: 'OpenIPC Firmware utilizes [Buildroot](https://buildroot.org/) to build its Linux distro, and uses [Majestic streamer](https://github.com/OpenIPC/majestic) which while not yet fully open, provides unprecedented performance and capabilities for a wide range of hardware. The author of Majestic streamer is looking into possibilities to open-source the codebase after he secures enough funds to support further open development. You can [help](https://openipc.org/support-open-source) to make it happen sooner.', 7 | }, 8 | why: { 9 | p1: 'First of all, OpenIPC Firmware brings you freedom. With OpenIPC on your camera you are the master of your streams. You have full access to the system and can control what, where, and how you want your camera to behave. There are no backdoors, no botnets, no crypto-mining malware, no keyloggers, no password sniffers, nothing you could possibly expect in a closed binary system with no access to its source code.', 10 | p2: 'As for the Firmware capabilities, we strive to provide universal support for a wide range of cameras, thus we are focused on basic functionality first, allowing end-users to upgrade their cameras\' firmware and stream video and audio (where supported) without too much hassle.', 11 | p3: 'We have some interesting bits though. Our Firmware supports IPEYE cloud storage, streaming video to Youtube and Telegram, using SOCKS5 proxy, setting up a Virtual Tunnel, and more. We also have a few projects focused on premium or specialized hardware, e.g. cameras for drones.' 12 | }, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /src/views/layout/header/header.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { HeaderButton } from '../../ui/buttons/header-button/header-button'; 3 | import { BurgerButton } from '../../ui/buttons/burger-button/burger-button'; 4 | import { MobileRoutes } from './mobile-routes/mobile-routes'; 5 | import { DropDown } from './dropdown/dropdown'; 6 | import { HeaderLink } from '../../ui/links/header-link/header-link'; 7 | 8 | import navigation from '../../../shared/constants/main-nav-list'; 9 | import './header.css'; 10 | import logo from '../../../shared/images/logo.svg'; 11 | 12 | const pageClickHandler = (e) => { 13 | if ( 14 | document.querySelector('.dropdown_show') 15 | && 16 | document.querySelector('.dropdown_show') !== e.target 17 | ) { 18 | Header.clicked = null; 19 | m.redraw(); 20 | } 21 | } 22 | 23 | const toggleDropdown = () => { 24 | const pageDiv = document.querySelector('.page'); 25 | pageDiv.addEventListener('click', pageClickHandler); 26 | } 27 | 28 | export const Header = { 29 | oncreate: toggleDropdown, 30 | clicked: undefined, 31 | toggleMobileRoutes: () => Header.isMobileRoutesOpen = !Header.isMobileRoutesOpen, 32 | isMobileRoutesOpen: false, 33 | clickHandler: (e) => { 34 | e.stopPropagation(); 35 | Header.clicked === e.target.name 36 | ? Header.clicked = null 37 | : Header.clicked = e.target.name; 38 | }, 39 | view: () => 40 | m('header.header', [ 41 | m('nav.header__navigation', [ 42 | m('div.header__home', 43 | m(m.route.Link, { href: "/", class: "header__home-link" }, 44 | m.trust(logo), 45 | ), 46 | ), 47 | m('ul.header__routes.header__routes_desktop', [ 48 | navigation.map((el: {}) => { 49 | const isNestedElement = typeof el[Object.keys(el)[0]] !== 'string'; 50 | const elementName = Object.keys(el)[0]; 51 | return !isNestedElement 52 | ? m('li.header__route', 53 | m(HeaderLink, { label: elementName, href: el[elementName] }) 54 | ) 55 | : m('li.header__route.header__route_nested', [ 56 | m(HeaderButton, { label: elementName, clickHandler: Header.clickHandler, isClicked: elementName === Header.clicked }), 57 | m(DropDown, { nestedElems: el[elementName], isOpen: elementName === Header.clicked }), 58 | ]) 59 | }) 60 | ]), 61 | m('.header__routes.header__routes_burger', 62 | m(BurgerButton, { clickHandler: Header.toggleMobileRoutes }) 63 | ), 64 | ]), 65 | m(MobileRoutes, { navElements: navigation, isOpen: Header.isMobileRoutesOpen }), 66 | ]), 67 | }; 68 | -------------------------------------------------------------------------------- /src/shared/icons/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { Layout } from './views/layout/layout'; 3 | import { Introduction } from './views/content/introduction/introduction'; 4 | import { SupportedHardware } from './views/content/supported-hardware/supported-hardware'; 5 | import { SupportOpenSource } from './views/content/support-open-source/support-open-source'; 6 | import { OurTeam } from './views/content/our-team/our-team'; 7 | import { OurProjects } from './views/content/our-projects/our-projects'; 8 | import { OurChannels } from './views/content/our-channels/our-channels'; 9 | import { FirmwarePartitionCalculator } from './views/content/firmware-partition-calculator/firmware-partition-caclucator'; 10 | 11 | import './shared/styles/global.css'; 12 | import './shared/styles/palette.css'; 13 | import './shared/styles/fonts.css'; 14 | 15 | m.route.prefix = ''; 16 | 17 | m.route(document.body, '/', { 18 | '/': { 19 | render: () => 20 | m(Layout, { 21 | pageTitle: 'introduction', 22 | }, m(Introduction, { 23 | pageTitle: 'introduction' 24 | }) 25 | ), 26 | }, 27 | '/introduction': { 28 | render: () => 29 | m(Layout, { 30 | pageTitle: 'introduction' 31 | }, m(Introduction, { 32 | pageTitle: 'introduction', 33 | }) 34 | ), 35 | }, 36 | '/supported-hardware': { 37 | render: () => 38 | m(Layout, { 39 | pageTitle: 'supported-hardware', 40 | }, m(SupportedHardware, { 41 | pageTitle: 'supported-hardware', 42 | }) 43 | ), 44 | }, 45 | '/support-open-source': { 46 | render: () => 47 | m(Layout, { 48 | pageTitle: 'support-open-source', 49 | }, m(SupportOpenSource, { 50 | pageTitle: 'support-open-source', 51 | }) 52 | ), 53 | }, 54 | '/our-team': { 55 | render: () => 56 | m(Layout, { 57 | pageTitle: 'our-team', 58 | }, m(OurTeam, { 59 | pageTitle: 'our-team', 60 | }) 61 | ), 62 | }, 63 | '/our-projects': { 64 | render: () => 65 | m(Layout, { 66 | pageTitle: 'our-projects', 67 | }, m(OurProjects, { 68 | pageTitle: 'our-projects', 69 | }), 70 | ), 71 | }, 72 | '/our-channels': { 73 | render: () => 74 | m(Layout, { 75 | pageTitle: 'our-channels', 76 | }, m(OurChannels, { 77 | pageTitle: 'our-channels', 78 | }), 79 | ), 80 | }, 81 | '/firmware-partition-calculator': { 82 | render: () => 83 | m(Layout, { 84 | pageTitle: 'firmware-partition-calculator', 85 | }, m(FirmwarePartitionCalculator), 86 | ), 87 | }, 88 | '/cameras/vendors/:choosenLetter': { 89 | render: () => 90 | m(Layout, { 91 | pageTitle: 'supported-hardware', 92 | }, m(SupportedHardware, { 93 | pageTitle: 'supported-hardware', 94 | }) 95 | ), 96 | }, 97 | '/cameras/vendors/:choosenLetter/:choosenVendor': { 98 | render: () => 99 | m(Layout, { 100 | pageTitle: 'supported-hardware', 101 | }, m(SupportedHardware, { 102 | pageTitle: 'supported-hardware', 103 | }) 104 | ), 105 | }, 106 | }); 107 | -------------------------------------------------------------------------------- /src/shared/icons/socs-info/blue-info-frame.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/shared/constants/our-projects/our-projects.ts: -------------------------------------------------------------------------------- 1 | export const ourProjects = { 2 | core: [ 3 | { 4 | link: 'https://github.com/OpenIPC/firmware', 5 | title: 'Firmware:', 6 | description: 'The Holy Grail of the community. Universal firmware for IP-cameras to replace proprietary, outdated and often insecure vendor pre-installed firmware.', 7 | }, 8 | { 9 | link: 'https://github.com/OpenIPC/majestic', 10 | title: 'Majestic', 11 | description:'A universal IP-camera streamer. This project is the major part of the OpenIPC Firmware. Although it is not fully open source at this stage of development, we are considering opening up the codebase when the project matures enough and gets enough funding for open development.', 12 | }, 13 | { 14 | link: 'https://github.com/OpenIPC/ipctool', 15 | title: 'IPC tool', 16 | description: 'An IP-camera hardware inspector on steroids. This tool will not only identify your camera\'s processor, sensor, flash chip, but also help you with backing up the original firmware and more.', 17 | }, 18 | { 19 | link: 'https://github.com/OpenIPC/coupler', 20 | title: 'Coupler', 21 | description: 'A tool that allows you a smooth transition from the IP-camera manufacturer\'s pre-installed proprietary firmware to OpenIPC Firmware. No special skills are required.', 22 | }, 23 | { 24 | link: 'https://github.com/OpenIPC/smolrtsp', 25 | title: 'SmolRTSP', 26 | description: 'A simple RTSP 1.0 server library tailored for embedded devices, such as IP cameras. It supports both TCP and UDP, allows any payload format, and provides a convenient and flexible API.', 27 | }, 28 | { 29 | link: 'https://github.com/OpenIPC/mini', 30 | title: 'Mini', 31 | description: 'An open source IP-camera streamer. Think of it as Majestic\'s little brother.', 32 | }, 33 | { 34 | link: 'https://github.com/OpenIPC/microbe-web', 35 | title: 'Microbe Web', 36 | description: 'Web interface for OpenIPC Firmware. Written on Ash and tears of the developer.', 37 | }, 38 | ], 39 | 40 | mention: { 41 | content: 'The OpenIPC is also an umbrella brand for other small projects that are useful components of our ecosystem. We welcome everyone willing to contribute to the project, in any way they find useful!' 42 | }, 43 | 44 | umbrella: [ 45 | { 46 | link: 'https://github.com/OpenIPC/motors', 47 | title: 'Motors', 48 | description: 'Various code to manage motor hardware.', 49 | }, 50 | { 51 | link: 'https://github.com/OpenIPC/yaml-cli', 52 | title: 'YAML-cli', 53 | description: 'Simple YAML console tool.', 54 | }, 55 | { 56 | link: 'https://github.com/OpenIPC/hisi-trace', 57 | title: 'HiSi-trace', 58 | description: 'An utility to run Sofia from XM in a non-stock environment.', 59 | }, 60 | { 61 | link: 'https://github.com/OpenIPC/openxiongmai', 62 | title: 'OpenXiongmai', 63 | description: 'Opensource Xiongmai SoCs SDK.', 64 | }, 65 | { 66 | link: 'https://team.openipc.org/exipcam', 67 | title: 'ExIPCam', 68 | description: 'XM Device Explorer. Utility for repairing IPCam. Russian UI. Runs on Windows, Linux via Wine.', 69 | }, 70 | { 71 | link: 'https://team.openipc.org/ipcam_dms', 72 | title: 'IPCamDMS', 73 | description: 'IPCam Device Management System. Russian UI. Runs on Windows, Linux via Wine.', 74 | }, 75 | ], 76 | } 77 | -------------------------------------------------------------------------------- /src/views/content/supported-hardware/supported-hardware.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { Vendors } from '../../ui/vendors/vendors'; 3 | import { vendors } from '../../../shared/constants/supported-hardware/vendors'; 4 | import { socs } from '../../../shared/constants/supported-hardware/socs'; 5 | import { Letters } from '../../ui/letters/letters'; 6 | import { Socs } from '../../ui/socs/socs'; 7 | import { SocsMobile } from '../../ui/socs-mobile/socs-mobile'; 8 | 9 | import './supported-hardware.css'; 10 | 11 | export interface SoC { 12 | stage: string, 13 | socModel: string, 14 | docs: string, 15 | uBoot: string, 16 | linux: string, 17 | sdk: string, 18 | loadAddress: string, 19 | buildStatus: string, 20 | } 21 | 22 | export interface SoCs { 23 | [key: string]: SoC[] 24 | } 25 | 26 | const getFirstLettersOfVendors = (vendors: string[]): string[] => { 27 | return vendors.reduce((letters: string[], word: string) => { 28 | if (!letters.includes(word.slice(0, 1).toUpperCase())) 29 | letters.push(word.slice(0, 1).toUpperCase()); 30 | return letters; 31 | }, []); 32 | } 33 | 34 | const getLetterProvidedByPath = (vendors: string[]): string => { 35 | const letter: string = m.route.param('choosenLetter'); 36 | return getFirstLettersOfVendors(vendors).includes(letter) 37 | ? letter 38 | : undefined; 39 | }; 40 | 41 | const getVendorProvidedByPath = (vendors: string[]): string => { 42 | let choosenVendor: string = m.route.param('choosenVendor'); 43 | return (!choosenVendor || choosenVendor === 'full-list') 44 | ? 'Full list' 45 | : vendors.find((vendor: string) => vendor.replace(' ','-').toLowerCase() === choosenVendor); 46 | } 47 | 48 | const getVendorsByChoosenLetter = (choosenLetter: string, vendors: string[]): string[] => { 49 | return choosenLetter 50 | ? vendors.filter((vendor: String) => vendor.slice(0,1).toUpperCase() === choosenLetter) 51 | : vendors; 52 | } 53 | 54 | const getSocsFullList = (socsByVendors: Object): Object => { 55 | const socs = Object.values(socsByVendors); 56 | const fullList = socs.reduce((accumulator: {}, item: []) => { 57 | if (item) item.forEach((el: Object) => accumulator['Full list'].push(el)); 58 | return accumulator; 59 | }, {'Full list': []}); 60 | return fullList; 61 | } 62 | 63 | const getSocsByLetter = (choosenLetter: string, vendors: string[], socs: SoCs): {} => { 64 | const vendorsStartsWithChoosenLetter: String[] = vendors.filter((vendor: String) => { 65 | return vendor.slice(0,1).toUpperCase() === choosenLetter; 66 | }); 67 | const socsByLetter: Object = {}; 68 | vendorsStartsWithChoosenLetter.forEach((vendor: string) => socsByLetter[vendor] = socs[vendor]); 69 | return socsByLetter; 70 | } 71 | 72 | export const SupportedHardware = { 73 | view: () => { 74 | const letters: string[] = getFirstLettersOfVendors(vendors); 75 | const letter: string = getLetterProvidedByPath(vendors); 76 | const vendor: string = getVendorProvidedByPath(vendors); 77 | const vendorsToShow: string[] = getVendorsByChoosenLetter(letter, vendors); 78 | const socsByLetter: {} = getSocsByLetter(letter, vendors, socs); 79 | const socsFullList: Object = getSocsFullList( 80 | letter ? socsByLetter : socs 81 | ); 82 | 83 | return m('.sup-hd-wrapper', 84 | m(Letters, { letters, selectedLetter: letter } ), 85 | m(Vendors, { 86 | letter, 87 | vendors: ['Full list', ...vendorsToShow], 88 | selectedVendor: vendor, 89 | }), 90 | m('section.socs-section', 91 | m('h2.socs-section__header', vendor === 'Full list' ? 'SoC: full list' : `SoC: filtered by ${vendor}`), 92 | m(Socs, { 93 | socs: { 'Full list': socsFullList['Full list'], ...socsByLetter}[vendor], 94 | }), 95 | m(SocsMobile, { 96 | socs: { 'Full list': socsFullList['Full list'], ...socsByLetter}[vendor], 97 | }), 98 | ), 99 | ); 100 | }, 101 | }; 102 | -------------------------------------------------------------------------------- /src/views/ui/calc-table/calc-table.css: -------------------------------------------------------------------------------- 1 | .calc-table { 2 | width: 100%; 3 | box-sizing: border-box; 4 | display: grid; 5 | gap: 20px min(25px, 1.76vw); 6 | grid-template-columns: repeat(5, 1fr); 7 | grid-template-rows: repeat(6, 64px); 8 | grid-template-areas: 9 | "cell_1-1 cell_1-2 cell_1-3 . cell_1-4" 10 | "cell_2-1 cell_2-2 cell_2-3 cell_2-4 cell_2-5" 11 | "cell_3-1 cell_3-2 cell_3-3 cell_3-4 cell_3-5" 12 | "cell_4-1 cell_4-2 cell_4-3 cell_4-4 cell_4-5" 13 | "cell_5-1 cell_5-2 cell_5-3 cell_5-4 cell_5-5" 14 | "cell_6-1 cell_6-2 cell_6-3 cell_6-4 cell_6-5"; 15 | 16 | @media(max-width: $mobile) { 17 | grid-template-columns: 1fr; 18 | grid-template-areas: 19 | "cell_1-1" 20 | "cell_1-2" 21 | "cell_1-3" 22 | "cell_1-4" 23 | "cell_2-1" 24 | "cell_2-2" 25 | "cell_2-3" 26 | "cell_2-4" 27 | "cell_2-5" 28 | "cell_3-1" 29 | "cell_3-2" 30 | "cell_3-3" 31 | "cell_3-4" 32 | "cell_3-5" 33 | "cell_4-1" 34 | "cell_4-2" 35 | "cell_4-3" 36 | "cell_4-4" 37 | "cell_4-5" 38 | "cell_5-1" 39 | "cell_5-2" 40 | "cell_5-3" 41 | "cell_5-4" 42 | "cell_5-5" 43 | "cell_6-1" 44 | "cell_6-2" 45 | "cell_6-3" 46 | "cell_6-4" 47 | "cell_6-5"; 48 | } 49 | } 50 | 51 | .cell { 52 | width: 100%; 53 | box-sizing: border-box; 54 | border-radius: 6px; 55 | display: flex; 56 | flex-flow: column nowrap; 57 | justify-content: space-between; 58 | align-items: flex-start; 59 | padding: 5px; 60 | border: 1px solid var(--lines-grey); 61 | 62 | &_bg_grey { 63 | background: var(--light-grey); 64 | border: none; 65 | } 66 | 67 | &__label { 68 | color: var(--grey); 69 | font: normal normal clamp(11px, 1.14vw, 13px)/1.2 'IBM Plex Sans', sans-serif; 70 | 71 | @media(max-width: $mobile) { 72 | font: normal normal 15px/1.2 'IBM Plex Sans', sans-serif; 73 | } 74 | } 75 | 76 | &__input { 77 | border: none; 78 | outline: none; 79 | padding: 0; 80 | margin: 0 5px; 81 | font: normal normal clamp(16px, 1.8vw, 26px)/1.2 'Share Tech Mono', monospace; 82 | text-align: right; 83 | width: calc(100% - 10px); 84 | 85 | @media(max-width: $mobile) { 86 | font: normal normal 26px/1.2 'Share Tech Mono', monospace; 87 | } 88 | 89 | &_name { 90 | font: normal normal clamp(12px, 1.53vw, 22px)/1.2 'Share Tech Mono', monospace; 91 | text-align: left; 92 | 93 | @media(max-width: $mobile) { 94 | font: normal normal 22px/1.2 'Share Tech Mono', monospace; 95 | } 96 | } 97 | 98 | &_hex_black { 99 | color: var(--black); 100 | } 101 | 102 | &_hex_blue { 103 | color: var(--pure-blue); 104 | background: transparent; 105 | } 106 | } 107 | } 108 | 109 | .cell_1-1 { 110 | grid-area: cell_1-1; 111 | } 112 | 113 | .cell_1-2 { 114 | grid-area: cell_1-2; 115 | } 116 | 117 | .cell_1-3 { 118 | grid-area: cell_1-3; 119 | border: 3px solid var(--black); 120 | } 121 | 122 | .cell_1-4 { 123 | grid-area: cell_1-4; 124 | justify-content: flex-start; 125 | align-items: flex-end; 126 | outline: none; 127 | border: none; 128 | } 129 | 130 | .cell_2-1 { 131 | grid-area: cell_2-1; 132 | border: 3px solid var(--red); 133 | } 134 | 135 | .cell_2-2 { 136 | grid-area: cell_2-2; 137 | } 138 | 139 | .cell_2-3 { 140 | grid-area: cell_2-3; 141 | } 142 | 143 | .cell_2-4 { 144 | grid-area: cell_2-4; 145 | } 146 | 147 | .cell_2-5 { 148 | grid-area: cell_2-5; 149 | } 150 | 151 | .cell_3-1 { 152 | grid-area: cell_3-1; 153 | border: 3px solid var(--orange); 154 | } 155 | 156 | .cell_3-2 { 157 | grid-area: cell_3-2; 158 | } 159 | 160 | .cell_3-3 { 161 | grid-area: cell_3-3; 162 | } 163 | 164 | .cell_3-4 { 165 | grid-area: cell_3-4; 166 | } 167 | 168 | .cell_3-5 { 169 | grid-area: cell_3-5; 170 | } 171 | 172 | .cell_4-1 { 173 | grid-area: cell_4-1; 174 | border: 3px solid var(--green); 175 | } 176 | 177 | .cell_4-2 { 178 | grid-area: cell_4-2; 179 | } 180 | 181 | .cell_4-3 { 182 | grid-area: cell_4-3; 183 | } 184 | 185 | .cell_4-4 { 186 | grid-area: cell_4-4; 187 | } 188 | 189 | .cell_4-5 { 190 | grid-area: cell_4-5; 191 | } 192 | 193 | .cell_5-1 { 194 | grid-area: cell_5-1; 195 | border: 3px solid var(--pure-blue); 196 | } 197 | 198 | .cell_5-2 { 199 | grid-area: cell_5-2; 200 | } 201 | 202 | .cell_5-3 { 203 | grid-area: cell_5-3; 204 | } 205 | 206 | .cell_5-4 { 207 | grid-area: cell_5-4; 208 | } 209 | 210 | .cell_5-5 { 211 | grid-area: cell_5-5; 212 | } 213 | 214 | .cell_6-1 { 215 | grid-area: cell_6-1; 216 | border: 3px solid var(--grey); 217 | } 218 | 219 | .cell_6-2 { 220 | grid-area: cell_6-2; 221 | } 222 | 223 | .cell_6-3 { 224 | grid-area: cell_6-3; 225 | } 226 | 227 | .cell_6-4 { 228 | grid-area: cell_6-4; 229 | } 230 | 231 | .cell_6-5 { 232 | grid-area: cell_6-5; 233 | } 234 | 235 | .cell_outline { 236 | outline: 4px solid var(--blue-like-bg); 237 | } 238 | -------------------------------------------------------------------------------- /src/shared/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/shared/icons/alliance/openipc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/views/ui/calc-table/calc-table.ts: -------------------------------------------------------------------------------- 1 | import m from 'mithril'; 2 | import { SolidButton } from '../buttons/solid-button/solid-button'; 3 | 4 | import './calc-table.css'; 5 | 6 | export const CalcTable = { 7 | oncreate: () => { 8 | const inputs = Array.from(document.getElementsByClassName('cell__input')); 9 | for (const input of inputs) { 10 | console.log(input.hasAttribute('readonly') ? input.parentNode : 'put'); 11 | if (!input.hasAttribute('readonly')) { 12 | input.addEventListener('focus', (e: Event): void => { 13 | const target: HTMLElement = ((e.target as HTMLInputElement).parentElement); 14 | target.classList.add('cell_outline'); 15 | }); 16 | input.addEventListener('blur', (e: Event): void => { 17 | const target: HTMLElement = ((e.target as HTMLInputElement).parentElement); 18 | target.classList.remove('cell_outline'); 19 | }); 20 | } 21 | } 22 | }, 23 | 24 | onremove: () => { 25 | const inputs = Array.from(document.getElementsByClassName('cell__input')); 26 | for (const input of inputs) { 27 | console.log(input.hasAttribute('readonly') ? input.parentNode : 'put'); 28 | if (!input.hasAttribute('readonly')) { 29 | input.removeEventListener('focus', (e: Event): void => { 30 | const target: HTMLElement = ((e.target as HTMLInputElement).parentElement); 31 | target.classList.add('cell_outline'); 32 | }); 33 | input.removeEventListener('blur', (e: Event): void => { 34 | const target: HTMLElement = ((e.target as HTMLInputElement).parentElement); 35 | target.classList.remove('cell_outline'); 36 | }); 37 | } 38 | } 39 | }, 40 | 41 | view: () => 42 | m('.calc-table', 43 | m('.calc-table__cell.cell.cell_1-1', 44 | m('label.cell__label[for=mtd-dev-name]', 'MTD device name'), 45 | m('input.cell__input.cell__input_name[id=mtd-dev-name]'), 46 | ), 47 | m('.calc-table__cell.cell.cell_1-2', 48 | m('label.cell__label[for=flash-size]', 'Flash size, MB'), 49 | m('input.cell__input.cell__input_dec-size[id=flash-size]', { 50 | value: '8', 51 | placeholder: '8', 52 | }), 53 | ), 54 | m('.calc-table__cell.cell.cell_1-3.cell_border_black', 55 | m('label.cell__label[for=initial-offset]', 'Initial offset, dec or hex'), 56 | m('input.cell__input.cell__input_hex_black[id=initial-offset]', { 57 | value: '0x0', 58 | placeholder: '0x0', 59 | }), 60 | ), 61 | m('.calc-table__cell.cell.cell_recalc.cell_1-4', 62 | m(SolidButton, { 63 | label: 'Recalculate', 64 | bgColor: 'button-blue', 65 | labelColor: 'white', 66 | }), 67 | ), 68 | m('.calc-table__cell.cell.cell_2-1', 69 | m('label.cell__label[for=part1-name]', 'Partition 1 name'), 70 | m('input.cell__input.cell__input_name[id=part1-name]', { 71 | value: 'boot', 72 | placeholder: 'boot', 73 | }), 74 | ), 75 | m('.calc-table__cell.cell.cell_2-2', 76 | m('label.cell__label[for=part1-size]', 'Partition 1 size, KB'), 77 | m('input.cell__input.cell__input_dec-size[id=part1-size]', { 78 | value: '256', 79 | placeholder: '256', 80 | }), 81 | ), 82 | m('.calc-table__cell.cell.cell_2-3.cell_bg_grey', 83 | m('label.cell__label[for=part1-start-addr]', 'Start address'), 84 | m('input.cell__input.cell__input_hex_blue[id=part1-start-addr][readonly]', { 85 | value: '0x0', 86 | placeholder: '0x0', 87 | }), 88 | ), 89 | m('.calc-table__cell.cell.cell_2-4.cell_bg_grey', 90 | m('label.cell__label[for=part1-hex-size]', 'Hex size, bytes'), 91 | m('input.cell__input.cell__input_hex_blue[id=part1-hex-size][readonly]', { 92 | value: '0x40000', 93 | placeholder: '0x40000', 94 | }), 95 | ), 96 | m('.calc-table__cell.cell.cell_2-5.cell_bg_grey', 97 | m('label.cell__label[for=part1-end-addr]', 'End address'), 98 | m('input.cell__input.cell__input_hex_blue[id=part1-end-addr][readonly]', { 99 | value: '0x3FFFF', 100 | placeholder: '0x4FFFF', 101 | }), 102 | ), 103 | m('.calc-table__cell.cell.cell_3-1', 104 | m('label.cell__label[for=part2-name]', 'Partition 2 name'), 105 | m('input.cell__input.cell__input_name[id=part2-name]', { 106 | value: 'env', 107 | placeholder: 'env', 108 | }), 109 | ), 110 | m('.calc-table__cell.cell.cell_3-2', 111 | m('label.cell__label[for=part2-size]', 'Partition 2 size, KB'), 112 | m('input.cell__input.cell__input_dec-size[id=part2-size]', { 113 | value: '64', 114 | placeholder: '64', 115 | }), 116 | ), 117 | m('.calc-table__cell.cell.cell_3-3.cell_bg_grey', 118 | m('label.cell__label[for=part2-start-addr]', 'Start address'), 119 | m('input.cell__input.cell__input_hex_blue[id=part2-start-addr][readonly]', { 120 | value: '0x40000', 121 | placeholder: '0x40000', 122 | }), 123 | ), 124 | m('.calc-table__cell.cell.cell_3-4.cell_bg_grey', 125 | m('label.cell__label[for=part2-hex-size]', 'Hex size, bytes'), 126 | m('input.cell__input.cell__input_hex_blue[id=part2-hex-size][readonly]', { 127 | value: '0x10000', 128 | placeholder: '0x200000', 129 | }), 130 | ), 131 | m('.calc-table__cell.cell.cell_3-5.cell_bg_grey', 132 | m('label.cell__label[for=part2-end-addr]', 'End address'), 133 | m('input.cell__input.cell__input_hex_blue[id=part2-end-addr][readonly]', { 134 | value: '0x4FFFF', 135 | placeholder: '0x4FFFF', 136 | }), 137 | ), 138 | m('.calc-table__cell.cell.cell_4-1', 139 | m('label.cell__label[for=part3-name]', 'Partition 3 name'), 140 | m('input.cell__input.cell__input_name[id=part3-name]', { 141 | value: 'kernel', 142 | placeholder: 'kernel', 143 | }), 144 | ), 145 | m('.calc-table__cell.cell.cell_4-2', 146 | m('label.cell__label[for=part3-size]', 'Partition 3 size, KB'), 147 | m('input.cell__input.cell__input_dec-size[id=part3-size]', { 148 | value: '2048', 149 | placeholder: '2048', 150 | }), 151 | ), 152 | m('.calc-table__cell.cell.cell_4-3.cell_bg_grey', 153 | m('label.cell__label[for=part3-start-addr]', 'Start address'), 154 | m('input.cell__input.cell__input_hex_blue[id=part3-start-addr][readonly]', { 155 | value: '0x50000', 156 | placeholder: '0x50000', 157 | }), 158 | ), 159 | m('.calc-table__cell.cell.cell_4-4.cell_bg_grey', 160 | m('label.cell__label[for=part3-hex-size]', 'Hex size, bytes'), 161 | m('input.cell__input.cell__input_hex_blue[id=part3-hex-size][readonly]', { 162 | value: '0x200000', 163 | placeholder: '0x2000000', 164 | }), 165 | ), 166 | m('.calc-table__cell.cell.cell_4-5.cell_bg_grey', 167 | m('label.cell__label[for=part3-end-addr]', 'End address'), 168 | m('input.cell__input.cell__input_hex_blue[id=part3-end-addr][readonly]', { 169 | value: '0x24FFFF', 170 | placeholder: '0x24FFFF', 171 | }), 172 | ), 173 | m('.calc-table__cell.cell.cell_5-1', 174 | m('label.cell__label[for=part4-name]', 'Partition 4 name'), 175 | m('input.cell__input.cell__input_name[id=part4-name]', { 176 | value: 'rootfs', 177 | placeholder: 'rootfs', 178 | }), 179 | ), 180 | m('.calc-table__cell.cell.cell_5-2', 181 | m('label.cell__label[for=part4-size]', 'Partition 4 size, KB'), 182 | m('input.cell__input.cell__input_dec-size[id=part4-size]', { 183 | value: '5120', 184 | placeholder: '5120', 185 | }), 186 | ), 187 | m('.calc-table__cell.cell.cell_5-3.cell_bg_grey', 188 | m('label.cell__label[for=part4-start-addr]', 'Start address'), 189 | m('input.cell__input.cell__input_hex_blue[id=part4-start-addr][readonly]', { 190 | value: '0x250000', 191 | placeholder: '0x250000', 192 | }), 193 | ), 194 | m('.calc-table__cell.cell.cell_5-4.cell_bg_grey', 195 | m('label.cell__label[for=part4-hex-size]', 'Hex size, bytes'), 196 | m('input.cell__input.cell__input_hex_blue[id=part4-hex-size][readonly]', { 197 | value: '0x500000', 198 | placeholder: '0x5000000', 199 | }), 200 | ), 201 | m('.calc-table__cell.cell.cell_5-5.cell_bg_grey', 202 | m('label.cell__label[for=part4-end-addr]', 'End address'), 203 | m('input.cell__input.cell__input_hex_blue[id=part4-end-addr][readonly]', { 204 | value: '0x74FFFF', 205 | placeholder: '0x74FFFF', 206 | }), 207 | ), 208 | m('.calc-table__cell.cell.cell_6-1', 209 | m('label.cell__label[for=part5-name]', 'Partition 5 name'), 210 | m('input.cell__input.cell__input_name[id=part5-name]', { 211 | value: 'rootfs_data', 212 | placeholder: 'rootfs_data', 213 | }), 214 | ), 215 | m('.calc-table__cell.cell.cell_6-2', 216 | m('label.cell__label[for=part5-size]', 'Partition 5 size, KB'), 217 | m('input.cell__input.cell__input_dec-size[id=part5-size]', { 218 | value: '-', 219 | placeholder: '-', 220 | }), 221 | ), 222 | m('.calc-table__cell.cell.cell_6-3.cell_bg_grey', 223 | m('label.cell__label[for=part5-start-addr]', 'Start address'), 224 | m('input.cell__input.cell__input_hex_blue[id=part5-start-addr][readonly]', { 225 | value: '0x750000', 226 | placeholder: '0x750000', 227 | }), 228 | ), 229 | m('.calc-table__cell.cell.cell_6-4.cell_bg_grey', 230 | m('label.cell__label[for=part5-hex-size]', 'Hex size, bytes'), 231 | m('input.cell__input.cell__input_hex_blue[id=part5-hex-size][readonly]', { 232 | value: '', 233 | placeholder: '', 234 | }), 235 | ), 236 | m('.calc-table__cell.cell.cell_6-5.cell_bg_grey', 237 | m('label.cell__label[for=part5-end-addr]', 'End address'), 238 | m('input.cell__input.cell__input_hex_blue[id=part5-end-addr][readonly]', { 239 | value: '0x74FFFF', 240 | placeholder: '0x74FFFF', 241 | }), 242 | ), 243 | ), 244 | }; 245 | -------------------------------------------------------------------------------- /src/shared/icons/alliance/majestic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | --------------------------------------------------------------------------------