Compare commits
28 Commits
86207fee86
...
cursor/air
| Author | SHA1 | Date | |
|---|---|---|---|
| 7587c622c3 | |||
| 333460525a | |||
| 1db8a466a5 | |||
| ae881da02b | |||
| d83b709245 | |||
| 6c267cc6f9 | |||
| 0fc09a934c | |||
| d639415d89 | |||
| f7bab1fe70 | |||
| fc190343eb | |||
| 09bfb957e6 | |||
| 2fe7c0df76 | |||
| dd565e349a | |||
| 09082a12a5 | |||
| 1286045a21 | |||
| 23d9108436 | |||
| ddbf352b33 | |||
| 635bd4e7ba | |||
| 0560b86b87 | |||
| 205924e057 | |||
| 2bc01b5952 | |||
| ba34c80761 | |||
| f412b9f71e | |||
| 1e6653de96 | |||
| 10d73b6d31 | |||
| d56e710e28 | |||
| c4722a6c99 | |||
|
|
45b4e7a109 |
0
3d_scene_final.jsx
Normal file
@@ -1,6 +1,19 @@
|
||||
import type { NextConfig } from "next";
|
||||
import path from "path";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
async redirects() {
|
||||
return [
|
||||
{
|
||||
source: "/air-freight",
|
||||
destination: "/doormile-wings",
|
||||
permanent: true,
|
||||
},
|
||||
];
|
||||
},
|
||||
turbopack: {
|
||||
root: path.resolve(__dirname),
|
||||
},
|
||||
output: "export",
|
||||
// Required by the How It Works 3D experience. React StrictMode double-invokes
|
||||
// mount/effects in dev, which tears down and re-creates the WebGL context of
|
||||
|
||||
21
package-lock.json
generated
@@ -18,6 +18,7 @@
|
||||
"lenis": "^1.3.23",
|
||||
"maath": "^0.10.8",
|
||||
"next": "16.2.6",
|
||||
"nodemailer": "^9.0.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"react-leaflet": "^5.0.0",
|
||||
@@ -31,6 +32,7 @@
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/leaflet": "^1.9.21",
|
||||
"@types/node": "^20",
|
||||
"@types/nodemailer": "^8.0.1",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/three": "^0.184.0",
|
||||
@@ -3045,6 +3047,16 @@
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/nodemailer": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-8.0.1.tgz",
|
||||
"integrity": "sha512-PxpaInm8V1JQDd4j0ds5HfvWQk8JupS1C0Picb96QJsrrRDjBH+DlK7L4ZdNSqNULhiZRQHc40nLVShaGxXAMw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/offscreencanvas": {
|
||||
"version": "2019.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
|
||||
@@ -9018,6 +9030,15 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemailer": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-9.0.0.tgz",
|
||||
"integrity": "sha512-tbPTid7d/p9jAA8CRZ3iomvrMaST0o6NYuY7v6JQZHpPRZ61mLFSPKYd7342NtOFuej9/+L48SOIxwfu2uDvtw==",
|
||||
"license": "MIT-0",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"lenis": "^1.3.23",
|
||||
"maath": "^0.10.8",
|
||||
"next": "16.2.6",
|
||||
"nodemailer": "^9.0.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"react-leaflet": "^5.0.0",
|
||||
@@ -36,6 +37,7 @@
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/leaflet": "^1.9.21",
|
||||
"@types/node": "^20",
|
||||
"@types/nodemailer": "^8.0.1",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@types/three": "^0.184.0",
|
||||
|
||||
@@ -507,7 +507,7 @@ body:not(.rtl) .elementor-element.elementor-element-13a7637 {
|
||||
}
|
||||
|
||||
.elementor-element.elementor-element-7da6646:not(.elementor-motion-effects-element-type-background) {
|
||||
background-image: url("/images/home4-banner-4.jpg");
|
||||
background-image: url("/images/bg-header-women.webp");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -5776,12 +5776,12 @@ body:not(.block-editor-page) .content-wrapper .widget p {
|
||||
@media (max-width: 1024px) {
|
||||
.elementor-element.elementor-element-99768ba .elementor-widget-container img.wp-image-4481 {
|
||||
width: 100% !important;
|
||||
max-width: 450px !important;
|
||||
max-width: 600px !important;
|
||||
/* Prevent oversized/zoomed appearance on tablets */
|
||||
height: auto !important;
|
||||
aspect-ratio: auto !important;
|
||||
/* Maintain original proportions */
|
||||
object-fit: contain !important;
|
||||
object-fit: cover !important;
|
||||
/* Ensure no cropping of important content */
|
||||
margin: 0 auto !important;
|
||||
/* Centering */
|
||||
@@ -5799,10 +5799,10 @@ body:not(.block-editor-page) .content-wrapper .widget p {
|
||||
/* Specific scaling for small mobile phones */
|
||||
@media (max-width: 767px) {
|
||||
.elementor-element.elementor-element-99768ba .elementor-widget-container img.wp-image-4481 {
|
||||
max-width: 90% !important;
|
||||
max-width: 100% !important;
|
||||
/* Reduce scale on small screens */
|
||||
margin: 0 auto !important;
|
||||
border-radius: 18px !important;
|
||||
border-radius: 25px !important;
|
||||
/* Consistent rounded edges */
|
||||
}
|
||||
}
|
||||
@@ -8650,7 +8650,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-3264830 {
|
||||
background-image: url("/images/home2-slide-1.jpg");
|
||||
background-image: url("/images/home2-slide-1.webp");
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -8710,7 +8710,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 {
|
||||
background-image: url("/images/home2-slide-2.jpg");
|
||||
background-image: url("/images/home2-slide-2.webp");
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -8833,7 +8833,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor .elementor-element.elementor-element-ca6bc63:not(.elementor-motion-effects-element-type-background) {
|
||||
background-image: linear-gradient(to right, #00000080, #00000010), url("/images/home2-banner-1.jpg");
|
||||
background-image: linear-gradient(to right, #00000080, #00000010), url("/images/home2-banner-1.webp");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -8952,7 +8952,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor .elementor-element.elementor-element-f003242:not(.elementor-motion-effects-element-type-background) {
|
||||
background-image: url("/images/home2-banner-3.jpg");
|
||||
background-image: url("/images/home2-banner-3.webp");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -10216,7 +10216,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
#side-panel-2f31137:before {
|
||||
background-image: url("/images/bg-slide-sidebar.jpg");
|
||||
background-image: url("/images/bg-slide-sidebar.webp");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -11406,7 +11406,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-3264830 {
|
||||
background-image: url("/images/home2-slide-1.jpg");
|
||||
background-image: url("/images/home2-slide-1.webp");
|
||||
background-position: bottom center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -11458,7 +11458,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor-61 .elementor-element.elementor-element-6c7cbcb .elementor-repeater-item-6867061 {
|
||||
background-image: url("/images/home2-slide-2.jpg");
|
||||
background-image: url("/images/home2-slide-2.webp");
|
||||
background-position: bottom center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -11569,7 +11569,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor-61 .elementor-element.elementor-element-ca6bc63:not(.elementor-motion-effects-element-type-background) {
|
||||
background-image: url("/images/home2-banner-1.jpg");
|
||||
background-image: url("/images/home2-banner-1.webp");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -11684,7 +11684,7 @@ h1:where(.wp-block-heading).has-background,
|
||||
}
|
||||
|
||||
.elementor-61 .elementor-element.elementor-element-f003242:not(.elementor-motion-effects-element-type-background) {
|
||||
background-image: url("/images/home2-banner-3.jpg");
|
||||
background-image: url("/images/home2-banner-3.webp");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -14856,7 +14856,7 @@ img:is([sizes=auto i]) {
|
||||
}
|
||||
|
||||
.elementor-element.elementor-element-7da6646:not(.elementor-motion-effects-element-type-background) {
|
||||
background-image: url("/images/bg-header-5.png");
|
||||
background-image: url("/images/bg-header-5.webp");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
@@ -18143,14 +18143,97 @@ img:is([sizes=auto i]){contain-intrinsic-size:3000px 1500px}
|
||||
/* STYLE BLOCK 50 */
|
||||
.howits-hero-custom-bg.elementor-repeater-item-3264830,
|
||||
.howits-hero-custom-bg.elementor-repeater-item-6867061 {
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.1)), url('/images/home1-slide-1.png') !important;
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.1)), url('/images/home1-slide-1.webp') !important;
|
||||
background-position: center !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-size: cover !important;
|
||||
}
|
||||
.howits-hero-custom-bg.elementor-repeater-item-6867061 {
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.1)), url('/images/home1-slide-2.png') !important;
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.1)), url('/images/home1-slide-2.webp') !important;
|
||||
background-position: center !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-size: cover !important;
|
||||
}
|
||||
|
||||
/* STYLE BLOCK 51: unified mobile gutters for card/content sections */
|
||||
@media (max-width: 767px) {
|
||||
:root { --dm-mobile-gutter: 10px; }
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-89a0ca1,
|
||||
.elementor.elementor-86 .elementor-element.elementor-element-c2c601a,
|
||||
.elementor.elementor-104 .elementor-element.elementor-element-c70681e {
|
||||
--padding-left: var(--dm-mobile-gutter) !important;
|
||||
--padding-right: var(--dm-mobile-gutter) !important;
|
||||
padding-left: var(--dm-mobile-gutter) !important;
|
||||
padding-right: var(--dm-mobile-gutter) !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-3b4a7cc {
|
||||
--padding-left: 0px !important;
|
||||
--padding-right: 0px !important;
|
||||
padding-left: 0px !important;
|
||||
padding-right: 0px !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-89a0ca1 > .e-con-inner,
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-3b4a7cc > .e-con-inner,
|
||||
.elementor.elementor-86 .elementor-element.elementor-element-c2c601a > .e-con-inner,
|
||||
.elementor.elementor-104 .elementor-element.elementor-element-c70681e > .e-con-inner {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-89a0ca1 > .e-con-inner > .e-con,
|
||||
.elementor.elementor-86 .elementor-element.elementor-element-c2c601a > .e-con-inner > .e-con,
|
||||
.elementor.elementor-104 .elementor-element.elementor-element-c70681e > .e-con-inner > .e-con {
|
||||
--padding-left: 0px !important;
|
||||
--padding-right: 0px !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-6829276 {
|
||||
--e-con-grid-template-columns: minmax(0, 1fr) !important;
|
||||
--grid-justify-content: stretch !important;
|
||||
--justify-items: stretch !important;
|
||||
grid-template-columns: minmax(0, 1fr) !important;
|
||||
justify-content: stretch !important;
|
||||
justify-items: stretch !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .industry-solutions-grid,
|
||||
.elementor.elementor-61 .industry-card-link {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
.comparison-section .container {
|
||||
width: calc(100% - (var(--dm-mobile-gutter) * 2)) !important;
|
||||
max-width: calc(100% - (var(--dm-mobile-gutter) * 2)) !important;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.wcd-inner {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
}
|
||||
|
||||
33
public/draco/draco_decoder.js
Normal file
BIN
public/draco/draco_decoder.wasm
Normal file
116
public/draco/draco_wasm_wrapper.js
Normal file
@@ -0,0 +1,116 @@
|
||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(h){var n=0;return function(){return n<h.length?{done:!1,value:h[n++]}:{done:!0}}};$jscomp.arrayIterator=function(h){return{next:$jscomp.arrayIteratorImpl(h)}};$jscomp.makeIterator=function(h){var n="undefined"!=typeof Symbol&&Symbol.iterator&&h[Symbol.iterator];return n?n.call(h):$jscomp.arrayIterator(h)};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
|
||||
$jscomp.ISOLATE_POLYFILLS=!1;$jscomp.FORCE_POLYFILL_PROMISE=!1;$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION=!1;$jscomp.getGlobal=function(h){h=["object"==typeof globalThis&&globalThis,h,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var n=0;n<h.length;++n){var k=h[n];if(k&&k.Math==Math)return k}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
|
||||
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(h,n,k){if(h==Array.prototype||h==Object.prototype)return h;h[n]=k.value;return h};$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";
|
||||
var $jscomp$lookupPolyfilledValue=function(h,n){var k=$jscomp.propertyToPolyfillSymbol[n];if(null==k)return h[n];k=h[k];return void 0!==k?k:h[n]};$jscomp.polyfill=function(h,n,k,p){n&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(h,n,k,p):$jscomp.polyfillUnisolated(h,n,k,p))};
|
||||
$jscomp.polyfillUnisolated=function(h,n,k,p){k=$jscomp.global;h=h.split(".");for(p=0;p<h.length-1;p++){var l=h[p];if(!(l in k))return;k=k[l]}h=h[h.length-1];p=k[h];n=n(p);n!=p&&null!=n&&$jscomp.defineProperty(k,h,{configurable:!0,writable:!0,value:n})};
|
||||
$jscomp.polyfillIsolated=function(h,n,k,p){var l=h.split(".");h=1===l.length;p=l[0];p=!h&&p in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var y=0;y<l.length-1;y++){var f=l[y];if(!(f in p))return;p=p[f]}l=l[l.length-1];k=$jscomp.IS_SYMBOL_NATIVE&&"es6"===k?p[l]:null;n=n(k);null!=n&&(h?$jscomp.defineProperty($jscomp.polyfills,l,{configurable:!0,writable:!0,value:n}):n!==k&&(void 0===$jscomp.propertyToPolyfillSymbol[l]&&(k=1E9*Math.random()>>>0,$jscomp.propertyToPolyfillSymbol[l]=$jscomp.IS_SYMBOL_NATIVE?
|
||||
$jscomp.global.Symbol(l):$jscomp.POLYFILL_PREFIX+k+"$"+l),$jscomp.defineProperty(p,$jscomp.propertyToPolyfillSymbol[l],{configurable:!0,writable:!0,value:n})))};
|
||||
$jscomp.polyfill("Promise",function(h){function n(){this.batch_=null}function k(f){return f instanceof l?f:new l(function(q,u){q(f)})}if(h&&(!($jscomp.FORCE_POLYFILL_PROMISE||$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION&&"undefined"===typeof $jscomp.global.PromiseRejectionEvent)||!$jscomp.global.Promise||-1===$jscomp.global.Promise.toString().indexOf("[native code]")))return h;n.prototype.asyncExecute=function(f){if(null==this.batch_){this.batch_=[];var q=this;this.asyncExecuteFunction(function(){q.executeBatch_()})}this.batch_.push(f)};
|
||||
var p=$jscomp.global.setTimeout;n.prototype.asyncExecuteFunction=function(f){p(f,0)};n.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var f=this.batch_;this.batch_=[];for(var q=0;q<f.length;++q){var u=f[q];f[q]=null;try{u()}catch(A){this.asyncThrow_(A)}}}this.batch_=null};n.prototype.asyncThrow_=function(f){this.asyncExecuteFunction(function(){throw f;})};var l=function(f){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];this.isRejectionHandled_=!1;var q=this.createResolveAndReject_();
|
||||
try{f(q.resolve,q.reject)}catch(u){q.reject(u)}};l.prototype.createResolveAndReject_=function(){function f(A){return function(F){u||(u=!0,A.call(q,F))}}var q=this,u=!1;return{resolve:f(this.resolveTo_),reject:f(this.reject_)}};l.prototype.resolveTo_=function(f){if(f===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(f instanceof l)this.settleSameAsPromise_(f);else{a:switch(typeof f){case "object":var q=null!=f;break a;case "function":q=!0;break a;default:q=!1}q?this.resolveToNonPromiseObj_(f):
|
||||
this.fulfill_(f)}};l.prototype.resolveToNonPromiseObj_=function(f){var q=void 0;try{q=f.then}catch(u){this.reject_(u);return}"function"==typeof q?this.settleSameAsThenable_(q,f):this.fulfill_(f)};l.prototype.reject_=function(f){this.settle_(2,f)};l.prototype.fulfill_=function(f){this.settle_(1,f)};l.prototype.settle_=function(f,q){if(0!=this.state_)throw Error("Cannot settle("+f+", "+q+"): Promise already settled in state"+this.state_);this.state_=f;this.result_=q;2===this.state_&&this.scheduleUnhandledRejectionCheck_();
|
||||
this.executeOnSettledCallbacks_()};l.prototype.scheduleUnhandledRejectionCheck_=function(){var f=this;p(function(){if(f.notifyUnhandledRejection_()){var q=$jscomp.global.console;"undefined"!==typeof q&&q.error(f.result_)}},1)};l.prototype.notifyUnhandledRejection_=function(){if(this.isRejectionHandled_)return!1;var f=$jscomp.global.CustomEvent,q=$jscomp.global.Event,u=$jscomp.global.dispatchEvent;if("undefined"===typeof u)return!0;"function"===typeof f?f=new f("unhandledrejection",{cancelable:!0}):
|
||||
"function"===typeof q?f=new q("unhandledrejection",{cancelable:!0}):(f=$jscomp.global.document.createEvent("CustomEvent"),f.initCustomEvent("unhandledrejection",!1,!0,f));f.promise=this;f.reason=this.result_;return u(f)};l.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var f=0;f<this.onSettledCallbacks_.length;++f)y.asyncExecute(this.onSettledCallbacks_[f]);this.onSettledCallbacks_=null}};var y=new n;l.prototype.settleSameAsPromise_=function(f){var q=this.createResolveAndReject_();
|
||||
f.callWhenSettled_(q.resolve,q.reject)};l.prototype.settleSameAsThenable_=function(f,q){var u=this.createResolveAndReject_();try{f.call(q,u.resolve,u.reject)}catch(A){u.reject(A)}};l.prototype.then=function(f,q){function u(w,B){return"function"==typeof w?function(R){try{A(w(R))}catch(Z){F(Z)}}:B}var A,F,v=new l(function(w,B){A=w;F=B});this.callWhenSettled_(u(f,A),u(q,F));return v};l.prototype.catch=function(f){return this.then(void 0,f)};l.prototype.callWhenSettled_=function(f,q){function u(){switch(A.state_){case 1:f(A.result_);
|
||||
break;case 2:q(A.result_);break;default:throw Error("Unexpected state: "+A.state_);}}var A=this;null==this.onSettledCallbacks_?y.asyncExecute(u):this.onSettledCallbacks_.push(u);this.isRejectionHandled_=!0};l.resolve=k;l.reject=function(f){return new l(function(q,u){u(f)})};l.race=function(f){return new l(function(q,u){for(var A=$jscomp.makeIterator(f),F=A.next();!F.done;F=A.next())k(F.value).callWhenSettled_(q,u)})};l.all=function(f){var q=$jscomp.makeIterator(f),u=q.next();return u.done?k([]):new l(function(A,
|
||||
F){function v(R){return function(Z){w[R]=Z;B--;0==B&&A(w)}}var w=[],B=0;do w.push(void 0),B++,k(u.value).callWhenSettled_(v(w.length-1),F),u=q.next();while(!u.done)})};return l},"es6","es3");$jscomp.owns=function(h,n){return Object.prototype.hasOwnProperty.call(h,n)};$jscomp.assign=$jscomp.TRUST_ES6_POLYFILLS&&"function"==typeof Object.assign?Object.assign:function(h,n){for(var k=1;k<arguments.length;k++){var p=arguments[k];if(p)for(var l in p)$jscomp.owns(p,l)&&(h[l]=p[l])}return h};
|
||||
$jscomp.polyfill("Object.assign",function(h){return h||$jscomp.assign},"es6","es3");$jscomp.checkStringArgs=function(h,n,k){if(null==h)throw new TypeError("The 'this' value for String.prototype."+k+" must not be null or undefined");if(n instanceof RegExp)throw new TypeError("First argument to String.prototype."+k+" must not be a regular expression");return h+""};
|
||||
$jscomp.polyfill("String.prototype.startsWith",function(h){return h?h:function(n,k){var p=$jscomp.checkStringArgs(this,n,"startsWith");n+="";var l=p.length,y=n.length;k=Math.max(0,Math.min(k|0,p.length));for(var f=0;f<y&&k<l;)if(p[k++]!=n[f++])return!1;return f>=y}},"es6","es3");
|
||||
$jscomp.polyfill("Array.prototype.copyWithin",function(h){function n(k){k=Number(k);return Infinity===k||-Infinity===k?k:k|0}return h?h:function(k,p,l){var y=this.length;k=n(k);p=n(p);l=void 0===l?y:n(l);k=0>k?Math.max(y+k,0):Math.min(k,y);p=0>p?Math.max(y+p,0):Math.min(p,y);l=0>l?Math.max(y+l,0):Math.min(l,y);if(k<p)for(;p<l;)p in this?this[k++]=this[p++]:(delete this[k++],p++);else for(l=Math.min(l,y+p-k),k+=l-p;l>p;)--l in this?this[--k]=this[l]:delete this[--k];return this}},"es6","es3");
|
||||
$jscomp.typedArrayCopyWithin=function(h){return h?h:Array.prototype.copyWithin};$jscomp.polyfill("Int8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8ClampedArray.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
|
||||
$jscomp.polyfill("Uint16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float64Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
|
||||
var DracoDecoderModule=function(){var h="undefined"!==typeof document&&document.currentScript?document.currentScript.src:void 0;"undefined"!==typeof __filename&&(h=h||__filename);return function(n){function k(e){return a.locateFile?a.locateFile(e,U):U+e}function p(e,b){if(e){var c=ia;var d=e+b;for(b=e;c[b]&&!(b>=d);)++b;if(16<b-e&&c.buffer&&ra)c=ra.decode(c.subarray(e,b));else{for(d="";e<b;){var g=c[e++];if(g&128){var t=c[e++]&63;if(192==(g&224))d+=String.fromCharCode((g&31)<<6|t);else{var aa=c[e++]&
|
||||
63;g=224==(g&240)?(g&15)<<12|t<<6|aa:(g&7)<<18|t<<12|aa<<6|c[e++]&63;65536>g?d+=String.fromCharCode(g):(g-=65536,d+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else d+=String.fromCharCode(g)}c=d}}else c="";return c}function l(){var e=ja.buffer;a.HEAP8=W=new Int8Array(e);a.HEAP16=new Int16Array(e);a.HEAP32=ca=new Int32Array(e);a.HEAPU8=ia=new Uint8Array(e);a.HEAPU16=new Uint16Array(e);a.HEAPU32=Y=new Uint32Array(e);a.HEAPF32=new Float32Array(e);a.HEAPF64=new Float64Array(e)}function y(e){if(a.onAbort)a.onAbort(e);
|
||||
e="Aborted("+e+")";da(e);sa=!0;e=new WebAssembly.RuntimeError(e+". Build with -sASSERTIONS for more info.");ka(e);throw e;}function f(e){try{if(e==P&&ea)return new Uint8Array(ea);if(ma)return ma(e);throw"both async and sync fetching of the wasm failed";}catch(b){y(b)}}function q(){if(!ea&&(ta||fa)){if("function"==typeof fetch&&!P.startsWith("file://"))return fetch(P,{credentials:"same-origin"}).then(function(e){if(!e.ok)throw"failed to load wasm binary file at '"+P+"'";return e.arrayBuffer()}).catch(function(){return f(P)});
|
||||
if(na)return new Promise(function(e,b){na(P,function(c){e(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return f(P)})}function u(e){for(;0<e.length;)e.shift()(a)}function A(e){this.excPtr=e;this.ptr=e-24;this.set_type=function(b){Y[this.ptr+4>>2]=b};this.get_type=function(){return Y[this.ptr+4>>2]};this.set_destructor=function(b){Y[this.ptr+8>>2]=b};this.get_destructor=function(){return Y[this.ptr+8>>2]};this.set_refcount=function(b){ca[this.ptr>>2]=b};this.set_caught=function(b){W[this.ptr+
|
||||
12>>0]=b?1:0};this.get_caught=function(){return 0!=W[this.ptr+12>>0]};this.set_rethrown=function(b){W[this.ptr+13>>0]=b?1:0};this.get_rethrown=function(){return 0!=W[this.ptr+13>>0]};this.init=function(b,c){this.set_adjusted_ptr(0);this.set_type(b);this.set_destructor(c);this.set_refcount(0);this.set_caught(!1);this.set_rethrown(!1)};this.add_ref=function(){ca[this.ptr>>2]+=1};this.release_ref=function(){var b=ca[this.ptr>>2];ca[this.ptr>>2]=b-1;return 1===b};this.set_adjusted_ptr=function(b){Y[this.ptr+
|
||||
16>>2]=b};this.get_adjusted_ptr=function(){return Y[this.ptr+16>>2]};this.get_exception_ptr=function(){if(ua(this.get_type()))return Y[this.excPtr>>2];var b=this.get_adjusted_ptr();return 0!==b?b:this.excPtr}}function F(){function e(){if(!la&&(la=!0,a.calledRun=!0,!sa)){va=!0;u(oa);wa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)xa.unshift(a.postRun.shift());u(xa)}}if(!(0<ba)){if(a.preRun)for("function"==
|
||||
typeof a.preRun&&(a.preRun=[a.preRun]);a.preRun.length;)ya.unshift(a.preRun.shift());u(ya);0<ba||(a.setStatus?(a.setStatus("Running..."),setTimeout(function(){setTimeout(function(){a.setStatus("")},1);e()},1)):e())}}function v(){}function w(e){return(e||v).__cache__}function B(e,b){var c=w(b),d=c[e];if(d)return d;d=Object.create((b||v).prototype);d.ptr=e;return c[e]=d}function R(e){if("string"===typeof e){for(var b=0,c=0;c<e.length;++c){var d=e.charCodeAt(c);127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=
|
||||
d?(b+=4,++c):b+=3}b=Array(b+1);c=0;d=b.length;if(0<d){d=c+d-1;for(var g=0;g<e.length;++g){var t=e.charCodeAt(g);if(55296<=t&&57343>=t){var aa=e.charCodeAt(++g);t=65536+((t&1023)<<10)|aa&1023}if(127>=t){if(c>=d)break;b[c++]=t}else{if(2047>=t){if(c+1>=d)break;b[c++]=192|t>>6}else{if(65535>=t){if(c+2>=d)break;b[c++]=224|t>>12}else{if(c+3>=d)break;b[c++]=240|t>>18;b[c++]=128|t>>12&63}b[c++]=128|t>>6&63}b[c++]=128|t&63}}b[c]=0}e=r.alloc(b,W);r.copy(b,W,e);return e}return e}function Z(e){if("object"===
|
||||
typeof e){var b=r.alloc(e,W);r.copy(e,W,b);return b}return e}function X(){throw"cannot construct a VoidPtr, no constructor in IDL";}function S(){this.ptr=za();w(S)[this.ptr]=this}function Q(){this.ptr=Aa();w(Q)[this.ptr]=this}function V(){this.ptr=Ba();w(V)[this.ptr]=this}function x(){this.ptr=Ca();w(x)[this.ptr]=this}function D(){this.ptr=Da();w(D)[this.ptr]=this}function G(){this.ptr=Ea();w(G)[this.ptr]=this}function H(){this.ptr=Fa();w(H)[this.ptr]=this}function E(){this.ptr=Ga();w(E)[this.ptr]=
|
||||
this}function T(){this.ptr=Ha();w(T)[this.ptr]=this}function C(){throw"cannot construct a Status, no constructor in IDL";}function I(){this.ptr=Ia();w(I)[this.ptr]=this}function J(){this.ptr=Ja();w(J)[this.ptr]=this}function K(){this.ptr=Ka();w(K)[this.ptr]=this}function L(){this.ptr=La();w(L)[this.ptr]=this}function M(){this.ptr=Ma();w(M)[this.ptr]=this}function N(){this.ptr=Na();w(N)[this.ptr]=this}function O(){this.ptr=Oa();w(O)[this.ptr]=this}function z(){this.ptr=Pa();w(z)[this.ptr]=this}function m(){this.ptr=
|
||||
Qa();w(m)[this.ptr]=this}n=void 0===n?{}:n;var a="undefined"!=typeof n?n:{},wa,ka;a.ready=new Promise(function(e,b){wa=e;ka=b});var Ra=!1,Sa=!1;a.onRuntimeInitialized=function(){Ra=!0;if(Sa&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Sa=!0;if(Ra&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(e){if("string"!==typeof e)return!1;e=e.split(".");return 2>e.length||3<e.length?!1:1==e[0]&&0<=e[1]&&5>=e[1]?!0:0!=e[0]||10<
|
||||
e[1]?!1:!0};var Ta=Object.assign({},a),ta="object"==typeof window,fa="function"==typeof importScripts,Ua="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,U="";if(Ua){var Va=require("fs"),pa=require("path");U=fa?pa.dirname(U)+"/":__dirname+"/";var Wa=function(e,b){e=e.startsWith("file://")?new URL(e):pa.normalize(e);return Va.readFileSync(e,b?void 0:"utf8")};var ma=function(e){e=Wa(e,!0);e.buffer||(e=new Uint8Array(e));return e};var na=function(e,
|
||||
b,c){e=e.startsWith("file://")?new URL(e):pa.normalize(e);Va.readFile(e,function(d,g){d?c(d):b(g.buffer)})};1<process.argv.length&&process.argv[1].replace(/\\/g,"/");process.argv.slice(2);a.inspect=function(){return"[Emscripten Module object]"}}else if(ta||fa)fa?U=self.location.href:"undefined"!=typeof document&&document.currentScript&&(U=document.currentScript.src),h&&(U=h),U=0!==U.indexOf("blob:")?U.substr(0,U.replace(/[?#].*/,"").lastIndexOf("/")+1):"",Wa=function(e){var b=new XMLHttpRequest;b.open("GET",
|
||||
e,!1);b.send(null);return b.responseText},fa&&(ma=function(e){var b=new XMLHttpRequest;b.open("GET",e,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),na=function(e,b,c){var d=new XMLHttpRequest;d.open("GET",e,!0);d.responseType="arraybuffer";d.onload=function(){200==d.status||0==d.status&&d.response?b(d.response):c()};d.onerror=c;d.send(null)};a.print||console.log.bind(console);var da=a.printErr||console.warn.bind(console);Object.assign(a,Ta);Ta=null;var ea;a.wasmBinary&&
|
||||
(ea=a.wasmBinary);"object"!=typeof WebAssembly&&y("no native wasm support detected");var ja,sa=!1,ra="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0,W,ia,ca,Y,ya=[],oa=[],xa=[],va=!1,ba=0,qa=null,ha=null;var P="draco_decoder_gltf.wasm";P.startsWith("data:application/octet-stream;base64,")||(P=k(P));var pd=0,qd={b:function(e,b,c){(new A(e)).init(b,c);pd++;throw e;},a:function(){y("")},d:function(e,b,c){ia.copyWithin(e,b,b+c)},c:function(e){var b=ia.length;e>>>=0;if(2147483648<e)return!1;
|
||||
for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,e+100663296);var g=Math;d=Math.max(e,d);g=g.min.call(g,2147483648,d+(65536-d%65536)%65536);a:{d=ja.buffer;try{ja.grow(g-d.byteLength+65535>>>16);l();var t=1;break a}catch(aa){}t=void 0}if(t)return!0}return!1}};(function(){function e(g,t){a.asm=g.exports;ja=a.asm.e;l();oa.unshift(a.asm.f);ba--;a.monitorRunDependencies&&a.monitorRunDependencies(ba);0==ba&&(null!==qa&&(clearInterval(qa),qa=null),ha&&(g=ha,ha=null,g()))}function b(g){e(g.instance)}
|
||||
function c(g){return q().then(function(t){return WebAssembly.instantiate(t,d)}).then(function(t){return t}).then(g,function(t){da("failed to asynchronously prepare wasm: "+t);y(t)})}var d={a:qd};ba++;a.monitorRunDependencies&&a.monitorRunDependencies(ba);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(g){da("Module.instantiateWasm callback failed with error: "+g),ka(g)}(function(){return ea||"function"!=typeof WebAssembly.instantiateStreaming||P.startsWith("data:application/octet-stream;base64,")||
|
||||
P.startsWith("file://")||Ua||"function"!=typeof fetch?c(b):fetch(P,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,d).then(b,function(t){da("wasm streaming compile failed: "+t);da("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ka);return{}})();var Xa=a._emscripten_bind_VoidPtr___destroy___0=function(){return(Xa=a._emscripten_bind_VoidPtr___destroy___0=a.asm.h).apply(null,arguments)},za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=
|
||||
function(){return(za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=a.asm.i).apply(null,arguments)},Ya=a._emscripten_bind_DecoderBuffer_Init_2=function(){return(Ya=a._emscripten_bind_DecoderBuffer_Init_2=a.asm.j).apply(null,arguments)},Za=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return(Za=a._emscripten_bind_DecoderBuffer___destroy___0=a.asm.k).apply(null,arguments)},Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return(Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=
|
||||
a.asm.l).apply(null,arguments)},$a=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return($a=a._emscripten_bind_AttributeTransformData_transform_type_0=a.asm.m).apply(null,arguments)},ab=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return(ab=a._emscripten_bind_AttributeTransformData___destroy___0=a.asm.n).apply(null,arguments)},Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return(Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=
|
||||
a.asm.o).apply(null,arguments)},bb=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return(bb=a._emscripten_bind_GeometryAttribute___destroy___0=a.asm.p).apply(null,arguments)},Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return(Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=a.asm.q).apply(null,arguments)},cb=a._emscripten_bind_PointAttribute_size_0=function(){return(cb=a._emscripten_bind_PointAttribute_size_0=a.asm.r).apply(null,arguments)},db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=
|
||||
function(){return(db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=a.asm.s).apply(null,arguments)},eb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return(eb=a._emscripten_bind_PointAttribute_attribute_type_0=a.asm.t).apply(null,arguments)},fb=a._emscripten_bind_PointAttribute_data_type_0=function(){return(fb=a._emscripten_bind_PointAttribute_data_type_0=a.asm.u).apply(null,arguments)},gb=a._emscripten_bind_PointAttribute_num_components_0=function(){return(gb=a._emscripten_bind_PointAttribute_num_components_0=
|
||||
a.asm.v).apply(null,arguments)},hb=a._emscripten_bind_PointAttribute_normalized_0=function(){return(hb=a._emscripten_bind_PointAttribute_normalized_0=a.asm.w).apply(null,arguments)},ib=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return(ib=a._emscripten_bind_PointAttribute_byte_stride_0=a.asm.x).apply(null,arguments)},jb=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return(jb=a._emscripten_bind_PointAttribute_byte_offset_0=a.asm.y).apply(null,arguments)},kb=a._emscripten_bind_PointAttribute_unique_id_0=
|
||||
function(){return(kb=a._emscripten_bind_PointAttribute_unique_id_0=a.asm.z).apply(null,arguments)},lb=a._emscripten_bind_PointAttribute___destroy___0=function(){return(lb=a._emscripten_bind_PointAttribute___destroy___0=a.asm.A).apply(null,arguments)},Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return(Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=a.asm.B).apply(null,arguments)},mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=
|
||||
function(){return(mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=a.asm.C).apply(null,arguments)},nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return(nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=a.asm.D).apply(null,arguments)},ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return(ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=a.asm.E).apply(null,arguments)},pb=
|
||||
a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return(pb=a._emscripten_bind_AttributeQuantizationTransform_range_0=a.asm.F).apply(null,arguments)},qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return(qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=a.asm.G).apply(null,arguments)},Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return(Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=
|
||||
a.asm.H).apply(null,arguments)},rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return(rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=a.asm.I).apply(null,arguments)},sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return(sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=a.asm.J).apply(null,arguments)},tb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return(tb=
|
||||
a._emscripten_bind_AttributeOctahedronTransform___destroy___0=a.asm.K).apply(null,arguments)},Fa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return(Fa=a._emscripten_bind_PointCloud_PointCloud_0=a.asm.L).apply(null,arguments)},ub=a._emscripten_bind_PointCloud_num_attributes_0=function(){return(ub=a._emscripten_bind_PointCloud_num_attributes_0=a.asm.M).apply(null,arguments)},vb=a._emscripten_bind_PointCloud_num_points_0=function(){return(vb=a._emscripten_bind_PointCloud_num_points_0=a.asm.N).apply(null,
|
||||
arguments)},wb=a._emscripten_bind_PointCloud___destroy___0=function(){return(wb=a._emscripten_bind_PointCloud___destroy___0=a.asm.O).apply(null,arguments)},Ga=a._emscripten_bind_Mesh_Mesh_0=function(){return(Ga=a._emscripten_bind_Mesh_Mesh_0=a.asm.P).apply(null,arguments)},xb=a._emscripten_bind_Mesh_num_faces_0=function(){return(xb=a._emscripten_bind_Mesh_num_faces_0=a.asm.Q).apply(null,arguments)},yb=a._emscripten_bind_Mesh_num_attributes_0=function(){return(yb=a._emscripten_bind_Mesh_num_attributes_0=
|
||||
a.asm.R).apply(null,arguments)},zb=a._emscripten_bind_Mesh_num_points_0=function(){return(zb=a._emscripten_bind_Mesh_num_points_0=a.asm.S).apply(null,arguments)},Ab=a._emscripten_bind_Mesh___destroy___0=function(){return(Ab=a._emscripten_bind_Mesh___destroy___0=a.asm.T).apply(null,arguments)},Ha=a._emscripten_bind_Metadata_Metadata_0=function(){return(Ha=a._emscripten_bind_Metadata_Metadata_0=a.asm.U).apply(null,arguments)},Bb=a._emscripten_bind_Metadata___destroy___0=function(){return(Bb=a._emscripten_bind_Metadata___destroy___0=
|
||||
a.asm.V).apply(null,arguments)},Cb=a._emscripten_bind_Status_code_0=function(){return(Cb=a._emscripten_bind_Status_code_0=a.asm.W).apply(null,arguments)},Db=a._emscripten_bind_Status_ok_0=function(){return(Db=a._emscripten_bind_Status_ok_0=a.asm.X).apply(null,arguments)},Eb=a._emscripten_bind_Status_error_msg_0=function(){return(Eb=a._emscripten_bind_Status_error_msg_0=a.asm.Y).apply(null,arguments)},Fb=a._emscripten_bind_Status___destroy___0=function(){return(Fb=a._emscripten_bind_Status___destroy___0=
|
||||
a.asm.Z).apply(null,arguments)},Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return(Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=a.asm._).apply(null,arguments)},Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return(Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=a.asm.$).apply(null,arguments)},Hb=a._emscripten_bind_DracoFloat32Array_size_0=function(){return(Hb=a._emscripten_bind_DracoFloat32Array_size_0=a.asm.aa).apply(null,arguments)},Ib=
|
||||
a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return(Ib=a._emscripten_bind_DracoFloat32Array___destroy___0=a.asm.ba).apply(null,arguments)},Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return(Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=a.asm.ca).apply(null,arguments)},Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return(Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=a.asm.da).apply(null,arguments)},Kb=a._emscripten_bind_DracoInt8Array_size_0=
|
||||
function(){return(Kb=a._emscripten_bind_DracoInt8Array_size_0=a.asm.ea).apply(null,arguments)},Lb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return(Lb=a._emscripten_bind_DracoInt8Array___destroy___0=a.asm.fa).apply(null,arguments)},Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return(Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=a.asm.ga).apply(null,arguments)},Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return(Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=
|
||||
a.asm.ha).apply(null,arguments)},Nb=a._emscripten_bind_DracoUInt8Array_size_0=function(){return(Nb=a._emscripten_bind_DracoUInt8Array_size_0=a.asm.ia).apply(null,arguments)},Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return(Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=a.asm.ja).apply(null,arguments)},La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return(La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=a.asm.ka).apply(null,arguments)},Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=
|
||||
function(){return(Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=a.asm.la).apply(null,arguments)},Qb=a._emscripten_bind_DracoInt16Array_size_0=function(){return(Qb=a._emscripten_bind_DracoInt16Array_size_0=a.asm.ma).apply(null,arguments)},Rb=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return(Rb=a._emscripten_bind_DracoInt16Array___destroy___0=a.asm.na).apply(null,arguments)},Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return(Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=
|
||||
a.asm.oa).apply(null,arguments)},Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return(Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=a.asm.pa).apply(null,arguments)},Tb=a._emscripten_bind_DracoUInt16Array_size_0=function(){return(Tb=a._emscripten_bind_DracoUInt16Array_size_0=a.asm.qa).apply(null,arguments)},Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return(Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=a.asm.ra).apply(null,arguments)},Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=
|
||||
function(){return(Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=a.asm.sa).apply(null,arguments)},Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return(Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=a.asm.ta).apply(null,arguments)},Wb=a._emscripten_bind_DracoInt32Array_size_0=function(){return(Wb=a._emscripten_bind_DracoInt32Array_size_0=a.asm.ua).apply(null,arguments)},Xb=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return(Xb=a._emscripten_bind_DracoInt32Array___destroy___0=
|
||||
a.asm.va).apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return(Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=a.asm.wa).apply(null,arguments)},Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return(Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=a.asm.xa).apply(null,arguments)},Zb=a._emscripten_bind_DracoUInt32Array_size_0=function(){return(Zb=a._emscripten_bind_DracoUInt32Array_size_0=a.asm.ya).apply(null,arguments)},$b=a._emscripten_bind_DracoUInt32Array___destroy___0=
|
||||
function(){return($b=a._emscripten_bind_DracoUInt32Array___destroy___0=a.asm.za).apply(null,arguments)},Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return(Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=a.asm.Aa).apply(null,arguments)},ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return(ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=a.asm.Ba).apply(null,arguments)},bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return(bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=
|
||||
a.asm.Ca).apply(null,arguments)},cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=function(){return(cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=a.asm.Da).apply(null,arguments)},dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return(dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=a.asm.Ea).apply(null,arguments)},ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return(ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=a.asm.Fa).apply(null,
|
||||
arguments)},fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return(fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=a.asm.Ga).apply(null,arguments)},gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return(gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=a.asm.Ha).apply(null,arguments)},hc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return(hc=a._emscripten_bind_MetadataQuerier___destroy___0=a.asm.Ia).apply(null,arguments)},Qa=a._emscripten_bind_Decoder_Decoder_0=
|
||||
function(){return(Qa=a._emscripten_bind_Decoder_Decoder_0=a.asm.Ja).apply(null,arguments)},ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=function(){return(ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=a.asm.Ka).apply(null,arguments)},jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=function(){return(jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=a.asm.La).apply(null,arguments)},kc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return(kc=a._emscripten_bind_Decoder_GetAttributeId_2=
|
||||
a.asm.Ma).apply(null,arguments)},lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return(lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=a.asm.Na).apply(null,arguments)},mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return(mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=a.asm.Oa).apply(null,arguments)},nc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return(nc=a._emscripten_bind_Decoder_GetAttribute_2=a.asm.Pa).apply(null,arguments)},
|
||||
oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return(oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=a.asm.Qa).apply(null,arguments)},pc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return(pc=a._emscripten_bind_Decoder_GetMetadata_1=a.asm.Ra).apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return(qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=a.asm.Sa).apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=
|
||||
function(){return(rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=a.asm.Ta).apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return(sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=a.asm.Ua).apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return(tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=a.asm.Va).apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=function(){return(uc=
|
||||
a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=a.asm.Wa).apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return(vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=a.asm.Xa).apply(null,arguments)},wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return(wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=a.asm.Ya).apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return(xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=
|
||||
a.asm.Za).apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return(yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=a.asm._a).apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return(zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=a.asm.$a).apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return(Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=
|
||||
a.asm.ab).apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=function(){return(Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=a.asm.bb).apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return(Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=a.asm.cb).apply(null,arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return(Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=
|
||||
a.asm.db).apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return(Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=a.asm.eb).apply(null,arguments)},Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return(Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=a.asm.fb).apply(null,arguments)},Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=function(){return(Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=
|
||||
a.asm.gb).apply(null,arguments)},Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return(Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=a.asm.hb).apply(null,arguments)},Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return(Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=a.asm.ib).apply(null,arguments)},Jc=a._emscripten_bind_Decoder___destroy___0=function(){return(Jc=a._emscripten_bind_Decoder___destroy___0=a.asm.jb).apply(null,arguments)},Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=
|
||||
function(){return(Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=a.asm.kb).apply(null,arguments)},Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return(Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=a.asm.lb).apply(null,arguments)},Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return(Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=
|
||||
a.asm.mb).apply(null,arguments)},Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return(Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=a.asm.nb).apply(null,arguments)},Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return(Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=a.asm.ob).apply(null,arguments)},Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return(Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=
|
||||
a.asm.pb).apply(null,arguments)},Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return(Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=a.asm.qb).apply(null,arguments)},Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return(Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=a.asm.rb).apply(null,arguments)},Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return(Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=
|
||||
a.asm.sb).apply(null,arguments)},Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return(Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=a.asm.tb).apply(null,arguments)},Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return(Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=a.asm.ub).apply(null,arguments)},Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return(Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=
|
||||
a.asm.vb).apply(null,arguments)},Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return(Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=a.asm.wb).apply(null,arguments)},Xc=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return(Xc=a._emscripten_enum_draco_DataType_DT_INVALID=a.asm.xb).apply(null,arguments)},Yc=a._emscripten_enum_draco_DataType_DT_INT8=function(){return(Yc=a._emscripten_enum_draco_DataType_DT_INT8=a.asm.yb).apply(null,arguments)},Zc=
|
||||
a._emscripten_enum_draco_DataType_DT_UINT8=function(){return(Zc=a._emscripten_enum_draco_DataType_DT_UINT8=a.asm.zb).apply(null,arguments)},$c=a._emscripten_enum_draco_DataType_DT_INT16=function(){return($c=a._emscripten_enum_draco_DataType_DT_INT16=a.asm.Ab).apply(null,arguments)},ad=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return(ad=a._emscripten_enum_draco_DataType_DT_UINT16=a.asm.Bb).apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return(bd=a._emscripten_enum_draco_DataType_DT_INT32=
|
||||
a.asm.Cb).apply(null,arguments)},cd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return(cd=a._emscripten_enum_draco_DataType_DT_UINT32=a.asm.Db).apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_INT64=function(){return(dd=a._emscripten_enum_draco_DataType_DT_INT64=a.asm.Eb).apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return(ed=a._emscripten_enum_draco_DataType_DT_UINT64=a.asm.Fb).apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=
|
||||
function(){return(fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=a.asm.Gb).apply(null,arguments)},gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return(gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=a.asm.Hb).apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return(hd=a._emscripten_enum_draco_DataType_DT_BOOL=a.asm.Ib).apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return(id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=
|
||||
a.asm.Jb).apply(null,arguments)},jd=a._emscripten_enum_draco_StatusCode_OK=function(){return(jd=a._emscripten_enum_draco_StatusCode_OK=a.asm.Kb).apply(null,arguments)},kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return(kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=a.asm.Lb).apply(null,arguments)},ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return(ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=a.asm.Mb).apply(null,arguments)},md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=
|
||||
function(){return(md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=a.asm.Nb).apply(null,arguments)},nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return(nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=a.asm.Ob).apply(null,arguments)},od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return(od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=a.asm.Pb).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Qb).apply(null,arguments)};
|
||||
a._free=function(){return(a._free=a.asm.Rb).apply(null,arguments)};var ua=function(){return(ua=a.asm.Sb).apply(null,arguments)};a.___start_em_js=11660;a.___stop_em_js=11758;var la;ha=function b(){la||F();la||(ha=b)};if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0<a.preInit.length;)a.preInit.pop()();F();v.prototype=Object.create(v.prototype);v.prototype.constructor=v;v.prototype.__class__=v;v.__cache__={};a.WrapperObject=v;a.getCache=w;a.wrapPointer=B;a.castObject=function(b,
|
||||
c){return B(b.ptr,c)};a.NULL=B(0);a.destroy=function(b){if(!b.__destroy__)throw"Error: Cannot destroy object. (Did you create it yourself?)";b.__destroy__();delete w(b.__class__)[b.ptr]};a.compare=function(b,c){return b.ptr===c.ptr};a.getPointer=function(b){return b.ptr};a.getClass=function(b){return b.__class__};var r={buffer:0,size:0,pos:0,temps:[],needed:0,prepare:function(){if(r.needed){for(var b=0;b<r.temps.length;b++)a._free(r.temps[b]);r.temps.length=0;a._free(r.buffer);r.buffer=0;r.size+=
|
||||
r.needed;r.needed=0}r.buffer||(r.size+=128,r.buffer=a._malloc(r.size),r.buffer||y(void 0));r.pos=0},alloc:function(b,c){r.buffer||y(void 0);b=b.length*c.BYTES_PER_ELEMENT;b=b+7&-8;r.pos+b>=r.size?(0<b||y(void 0),r.needed+=b,c=a._malloc(b),r.temps.push(c)):(c=r.buffer+r.pos,r.pos+=b);return c},copy:function(b,c,d){d>>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var g=0;g<b.length;g++)c[d+g]=b[g]}};X.prototype=Object.create(v.prototype);X.prototype.constructor=
|
||||
X;X.prototype.__class__=X;X.__cache__={};a.VoidPtr=X;X.prototype.__destroy__=X.prototype.__destroy__=function(){Xa(this.ptr)};S.prototype=Object.create(v.prototype);S.prototype.constructor=S;S.prototype.__class__=S;S.__cache__={};a.DecoderBuffer=S;S.prototype.Init=S.prototype.Init=function(b,c){var d=this.ptr;r.prepare();"object"==typeof b&&(b=Z(b));c&&"object"===typeof c&&(c=c.ptr);Ya(d,b,c)};S.prototype.__destroy__=S.prototype.__destroy__=function(){Za(this.ptr)};Q.prototype=Object.create(v.prototype);
|
||||
Q.prototype.constructor=Q;Q.prototype.__class__=Q;Q.__cache__={};a.AttributeTransformData=Q;Q.prototype.transform_type=Q.prototype.transform_type=function(){return $a(this.ptr)};Q.prototype.__destroy__=Q.prototype.__destroy__=function(){ab(this.ptr)};V.prototype=Object.create(v.prototype);V.prototype.constructor=V;V.prototype.__class__=V;V.__cache__={};a.GeometryAttribute=V;V.prototype.__destroy__=V.prototype.__destroy__=function(){bb(this.ptr)};x.prototype=Object.create(v.prototype);x.prototype.constructor=
|
||||
x;x.prototype.__class__=x;x.__cache__={};a.PointAttribute=x;x.prototype.size=x.prototype.size=function(){return cb(this.ptr)};x.prototype.GetAttributeTransformData=x.prototype.GetAttributeTransformData=function(){return B(db(this.ptr),Q)};x.prototype.attribute_type=x.prototype.attribute_type=function(){return eb(this.ptr)};x.prototype.data_type=x.prototype.data_type=function(){return fb(this.ptr)};x.prototype.num_components=x.prototype.num_components=function(){return gb(this.ptr)};x.prototype.normalized=
|
||||
x.prototype.normalized=function(){return!!hb(this.ptr)};x.prototype.byte_stride=x.prototype.byte_stride=function(){return ib(this.ptr)};x.prototype.byte_offset=x.prototype.byte_offset=function(){return jb(this.ptr)};x.prototype.unique_id=x.prototype.unique_id=function(){return kb(this.ptr)};x.prototype.__destroy__=x.prototype.__destroy__=function(){lb(this.ptr)};D.prototype=Object.create(v.prototype);D.prototype.constructor=D;D.prototype.__class__=D;D.__cache__={};a.AttributeQuantizationTransform=
|
||||
D;D.prototype.InitFromAttribute=D.prototype.InitFromAttribute=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return!!mb(c,b)};D.prototype.quantization_bits=D.prototype.quantization_bits=function(){return nb(this.ptr)};D.prototype.min_value=D.prototype.min_value=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return ob(c,b)};D.prototype.range=D.prototype.range=function(){return pb(this.ptr)};D.prototype.__destroy__=D.prototype.__destroy__=function(){qb(this.ptr)};G.prototype=
|
||||
Object.create(v.prototype);G.prototype.constructor=G;G.prototype.__class__=G;G.__cache__={};a.AttributeOctahedronTransform=G;G.prototype.InitFromAttribute=G.prototype.InitFromAttribute=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return!!rb(c,b)};G.prototype.quantization_bits=G.prototype.quantization_bits=function(){return sb(this.ptr)};G.prototype.__destroy__=G.prototype.__destroy__=function(){tb(this.ptr)};H.prototype=Object.create(v.prototype);H.prototype.constructor=H;H.prototype.__class__=
|
||||
H;H.__cache__={};a.PointCloud=H;H.prototype.num_attributes=H.prototype.num_attributes=function(){return ub(this.ptr)};H.prototype.num_points=H.prototype.num_points=function(){return vb(this.ptr)};H.prototype.__destroy__=H.prototype.__destroy__=function(){wb(this.ptr)};E.prototype=Object.create(v.prototype);E.prototype.constructor=E;E.prototype.__class__=E;E.__cache__={};a.Mesh=E;E.prototype.num_faces=E.prototype.num_faces=function(){return xb(this.ptr)};E.prototype.num_attributes=E.prototype.num_attributes=
|
||||
function(){return yb(this.ptr)};E.prototype.num_points=E.prototype.num_points=function(){return zb(this.ptr)};E.prototype.__destroy__=E.prototype.__destroy__=function(){Ab(this.ptr)};T.prototype=Object.create(v.prototype);T.prototype.constructor=T;T.prototype.__class__=T;T.__cache__={};a.Metadata=T;T.prototype.__destroy__=T.prototype.__destroy__=function(){Bb(this.ptr)};C.prototype=Object.create(v.prototype);C.prototype.constructor=C;C.prototype.__class__=C;C.__cache__={};a.Status=C;C.prototype.code=
|
||||
C.prototype.code=function(){return Cb(this.ptr)};C.prototype.ok=C.prototype.ok=function(){return!!Db(this.ptr)};C.prototype.error_msg=C.prototype.error_msg=function(){return p(Eb(this.ptr))};C.prototype.__destroy__=C.prototype.__destroy__=function(){Fb(this.ptr)};I.prototype=Object.create(v.prototype);I.prototype.constructor=I;I.prototype.__class__=I;I.__cache__={};a.DracoFloat32Array=I;I.prototype.GetValue=I.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Gb(c,
|
||||
b)};I.prototype.size=I.prototype.size=function(){return Hb(this.ptr)};I.prototype.__destroy__=I.prototype.__destroy__=function(){Ib(this.ptr)};J.prototype=Object.create(v.prototype);J.prototype.constructor=J;J.prototype.__class__=J;J.__cache__={};a.DracoInt8Array=J;J.prototype.GetValue=J.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Jb(c,b)};J.prototype.size=J.prototype.size=function(){return Kb(this.ptr)};J.prototype.__destroy__=J.prototype.__destroy__=function(){Lb(this.ptr)};
|
||||
K.prototype=Object.create(v.prototype);K.prototype.constructor=K;K.prototype.__class__=K;K.__cache__={};a.DracoUInt8Array=K;K.prototype.GetValue=K.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Mb(c,b)};K.prototype.size=K.prototype.size=function(){return Nb(this.ptr)};K.prototype.__destroy__=K.prototype.__destroy__=function(){Ob(this.ptr)};L.prototype=Object.create(v.prototype);L.prototype.constructor=L;L.prototype.__class__=L;L.__cache__={};a.DracoInt16Array=
|
||||
L;L.prototype.GetValue=L.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Pb(c,b)};L.prototype.size=L.prototype.size=function(){return Qb(this.ptr)};L.prototype.__destroy__=L.prototype.__destroy__=function(){Rb(this.ptr)};M.prototype=Object.create(v.prototype);M.prototype.constructor=M;M.prototype.__class__=M;M.__cache__={};a.DracoUInt16Array=M;M.prototype.GetValue=M.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Sb(c,b)};
|
||||
M.prototype.size=M.prototype.size=function(){return Tb(this.ptr)};M.prototype.__destroy__=M.prototype.__destroy__=function(){Ub(this.ptr)};N.prototype=Object.create(v.prototype);N.prototype.constructor=N;N.prototype.__class__=N;N.__cache__={};a.DracoInt32Array=N;N.prototype.GetValue=N.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Vb(c,b)};N.prototype.size=N.prototype.size=function(){return Wb(this.ptr)};N.prototype.__destroy__=N.prototype.__destroy__=function(){Xb(this.ptr)};
|
||||
O.prototype=Object.create(v.prototype);O.prototype.constructor=O;O.prototype.__class__=O;O.__cache__={};a.DracoUInt32Array=O;O.prototype.GetValue=O.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Yb(c,b)};O.prototype.size=O.prototype.size=function(){return Zb(this.ptr)};O.prototype.__destroy__=O.prototype.__destroy__=function(){$b(this.ptr)};z.prototype=Object.create(v.prototype);z.prototype.constructor=z;z.prototype.__class__=z;z.__cache__={};a.MetadataQuerier=
|
||||
z;z.prototype.HasEntry=z.prototype.HasEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return!!ac(d,b,c)};z.prototype.GetIntEntry=z.prototype.GetIntEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return bc(d,b,c)};z.prototype.GetIntEntryArray=z.prototype.GetIntEntryArray=function(b,c,d){var g=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===
|
||||
typeof c?c.ptr:R(c);d&&"object"===typeof d&&(d=d.ptr);cc(g,b,c,d)};z.prototype.GetDoubleEntry=z.prototype.GetDoubleEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return dc(d,b,c)};z.prototype.GetStringEntry=z.prototype.GetStringEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return p(ec(d,b,c))};z.prototype.NumEntries=z.prototype.NumEntries=function(b){var c=this.ptr;
|
||||
b&&"object"===typeof b&&(b=b.ptr);return fc(c,b)};z.prototype.GetEntryName=z.prototype.GetEntryName=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return p(gc(d,b,c))};z.prototype.__destroy__=z.prototype.__destroy__=function(){hc(this.ptr)};m.prototype=Object.create(v.prototype);m.prototype.constructor=m;m.prototype.__class__=m;m.__cache__={};a.Decoder=m;m.prototype.DecodeArrayToPointCloud=m.prototype.DecodeArrayToPointCloud=function(b,c,d){var g=
|
||||
this.ptr;r.prepare();"object"==typeof b&&(b=Z(b));c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return B(ic(g,b,c,d),C)};m.prototype.DecodeArrayToMesh=m.prototype.DecodeArrayToMesh=function(b,c,d){var g=this.ptr;r.prepare();"object"==typeof b&&(b=Z(b));c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return B(jc(g,b,c,d),C)};m.prototype.GetAttributeId=m.prototype.GetAttributeId=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&
|
||||
(c=c.ptr);return kc(d,b,c)};m.prototype.GetAttributeIdByName=m.prototype.GetAttributeIdByName=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return lc(d,b,c)};m.prototype.GetAttributeIdByMetadataEntry=m.prototype.GetAttributeIdByMetadataEntry=function(b,c,d){var g=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);d=d&&"object"===typeof d?d.ptr:R(d);return mc(g,b,c,d)};m.prototype.GetAttribute=
|
||||
m.prototype.GetAttribute=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(nc(d,b,c),x)};m.prototype.GetAttributeByUniqueId=m.prototype.GetAttributeByUniqueId=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(oc(d,b,c),x)};m.prototype.GetMetadata=m.prototype.GetMetadata=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return B(pc(c,b),T)};m.prototype.GetAttributeMetadata=m.prototype.GetAttributeMetadata=
|
||||
function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(qc(d,b,c),T)};m.prototype.GetFaceFromMesh=m.prototype.GetFaceFromMesh=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!rc(g,b,c,d)};m.prototype.GetTriangleStripsFromMesh=m.prototype.GetTriangleStripsFromMesh=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);
|
||||
return sc(d,b,c)};m.prototype.GetTrianglesUInt16Array=m.prototype.GetTrianglesUInt16Array=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!tc(g,b,c,d)};m.prototype.GetTrianglesUInt32Array=m.prototype.GetTrianglesUInt32Array=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!uc(g,b,c,d)};m.prototype.GetAttributeFloat=m.prototype.GetAttributeFloat=
|
||||
function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!vc(g,b,c,d)};m.prototype.GetAttributeFloatForAllPoints=m.prototype.GetAttributeFloatForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!wc(g,b,c,d)};m.prototype.GetAttributeIntForAllPoints=m.prototype.GetAttributeIntForAllPoints=function(b,c,d){var g=this.ptr;
|
||||
b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!xc(g,b,c,d)};m.prototype.GetAttributeInt8ForAllPoints=m.prototype.GetAttributeInt8ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!yc(g,b,c,d)};m.prototype.GetAttributeUInt8ForAllPoints=m.prototype.GetAttributeUInt8ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=
|
||||
b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!zc(g,b,c,d)};m.prototype.GetAttributeInt16ForAllPoints=m.prototype.GetAttributeInt16ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Ac(g,b,c,d)};m.prototype.GetAttributeUInt16ForAllPoints=m.prototype.GetAttributeUInt16ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&
|
||||
(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Bc(g,b,c,d)};m.prototype.GetAttributeInt32ForAllPoints=m.prototype.GetAttributeInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Cc(g,b,c,d)};m.prototype.GetAttributeUInt32ForAllPoints=m.prototype.GetAttributeUInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===
|
||||
typeof d&&(d=d.ptr);return!!Dc(g,b,c,d)};m.prototype.GetAttributeDataArrayForAllPoints=m.prototype.GetAttributeDataArrayForAllPoints=function(b,c,d,g,t){var aa=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);g&&"object"===typeof g&&(g=g.ptr);t&&"object"===typeof t&&(t=t.ptr);return!!Ec(aa,b,c,d,g,t)};m.prototype.SkipAttributeTransform=m.prototype.SkipAttributeTransform=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);Fc(c,
|
||||
b)};m.prototype.GetEncodedGeometryType_Deprecated=m.prototype.GetEncodedGeometryType_Deprecated=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Gc(c,b)};m.prototype.DecodeBufferToPointCloud=m.prototype.DecodeBufferToPointCloud=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(Hc(d,b,c),C)};m.prototype.DecodeBufferToMesh=m.prototype.DecodeBufferToMesh=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===
|
||||
typeof c&&(c=c.ptr);return B(Ic(d,b,c),C)};m.prototype.__destroy__=m.prototype.__destroy__=function(){Jc(this.ptr)};(function(){function b(){a.ATTRIBUTE_INVALID_TRANSFORM=Kc();a.ATTRIBUTE_NO_TRANSFORM=Lc();a.ATTRIBUTE_QUANTIZATION_TRANSFORM=Mc();a.ATTRIBUTE_OCTAHEDRON_TRANSFORM=Nc();a.INVALID=Oc();a.POSITION=Pc();a.NORMAL=Qc();a.COLOR=Rc();a.TEX_COORD=Sc();a.GENERIC=Tc();a.INVALID_GEOMETRY_TYPE=Uc();a.POINT_CLOUD=Vc();a.TRIANGULAR_MESH=Wc();a.DT_INVALID=Xc();a.DT_INT8=Yc();a.DT_UINT8=Zc();a.DT_INT16=
|
||||
$c();a.DT_UINT16=ad();a.DT_INT32=bd();a.DT_UINT32=cd();a.DT_INT64=dd();a.DT_UINT64=ed();a.DT_FLOAT32=fd();a.DT_FLOAT64=gd();a.DT_BOOL=hd();a.DT_TYPES_COUNT=id();a.OK=jd();a.DRACO_ERROR=kd();a.IO_ERROR=ld();a.INVALID_PARAMETER=md();a.UNSUPPORTED_VERSION=nd();a.UNKNOWN_VERSION=od()}va?b():oa.unshift(b)})();if("function"===typeof a.onModuleParsed)a.onModuleParsed();a.Decoder.prototype.GetEncodedGeometryType=function(b){if(b.__class__&&b.__class__===a.DecoderBuffer)return a.Decoder.prototype.GetEncodedGeometryType_Deprecated(b);
|
||||
if(8>b.byteLength)return a.INVALID_GEOMETRY_TYPE;switch(b[7]){case 0:return a.POINT_CLOUD;case 1:return a.TRIANGULAR_MESH;default:return a.INVALID_GEOMETRY_TYPE}};return n.ready}}();"object"===typeof exports&&"object"===typeof module?module.exports=DracoDecoderModule:"function"===typeof define&&define.amd?define([],function(){return DracoDecoderModule}):"object"===typeof exports&&(exports.DracoDecoderModule=DracoDecoderModule);
|
||||
BIN
public/images/Aravinth.webp
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
public/images/Fazul.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/images/Investor.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/images/Parthi.webp
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
public/images/Suriya.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
public/images/about-bg.webp
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
public/images/air-freight-pic-1.jpg
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
public/images/air-freight-slide-1.jpg
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
public/images/air-freight-slide-2.jpg
Normal file
|
After Width: | Height: | Size: 143 KiB |
BIN
public/images/b5b560fe-aab0-4fe6-9f8c-4b187c2f0e99.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
public/images/b5b560fe-aab0-4fe6-9f8c-4b187c2f0e99.webp
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
public/images/bg-header-5.webp
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/images/bg-header-women.webp
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
public/images/bg-map-women.webp
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
public/images/bg-slide-sidebar.webp
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
public/images/blog-post-pic-14.webp
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
public/images/blog-post-pic-15.webp
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
public/images/blog-post-pic-17.webp
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
public/images/blog-post-pic-3.webp
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
public/images/blog-post-pic-31.webp
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
public/images/blog-post-pic-6.webp
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
public/images/blog-post-pic-8.webp
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
public/images/card 1.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/images/card 2.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/images/card 3.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/images/card4.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
public/images/card5.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
public/images/card6.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
public/images/ev-paradox.webp
Normal file
|
After Width: | Height: | Size: 176 KiB |
BIN
public/images/ev.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
public/images/first-mile-approach.webp
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
public/images/home-bg-1.webp
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
public/images/home1-slide-1.webp
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
public/images/home1-slide-2.webp
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
public/images/home2-banner-1.webp
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
public/images/home2-banner-3.webp
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
public/images/home2-pic-3.webp
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
public/images/home2-slide-1.webp
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
public/images/home2-slide-2.webp
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
public/images/last-mile-approach.webp
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
public/images/mid-mile-approach.webp
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
public/images/mile-1.webp
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
public/images/miletruth-bg.webp
Normal file
|
After Width: | Height: | Size: 187 KiB |
BIN
public/images/pahse1.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
public/images/premium-ev-van.webp
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
public/images/tab-pic-1-solution.webp
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
public/images/tab-pic-1.webp
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
public/images/tab-pic-2-solution.webp
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/images/tab-pic-2.webp
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
public/images/tab-pic-3-solution.webp
Normal file
|
After Width: | Height: | Size: 157 KiB |
BIN
public/images/tab-pic-3.webp
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
public/images/wings-heroslide2.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
public/images/wings-heroslider3.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/images/wings-heroslider4.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
public/images/women-hero-silder-1.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/images/women-hero-slider-2.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/images/women-hero-slider-3.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/videos/Doormile-quantum-video3.mp4
Normal file
BIN
public/videos/fleet.mp4
Normal file
BIN
public/videos/workflow-2-routing.mp4
Normal file
53
src/actions/sendEmail.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
"use server";
|
||||
|
||||
import nodemailer from "nodemailer";
|
||||
|
||||
export async function sendContactEmail(data: {
|
||||
fullName: string;
|
||||
email: string;
|
||||
subject: string;
|
||||
message: string;
|
||||
}) {
|
||||
const { fullName, email, subject, message } = data;
|
||||
|
||||
if (!fullName || !email || !subject || !message) {
|
||||
return { success: false, error: "All fields are required." };
|
||||
}
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: Number(process.env.SMTP_PORT) || 465,
|
||||
secure: true,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASSWORD,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
await transporter.sendMail({
|
||||
from: `"${fullName}" <${process.env.SMTP_USER}>`,
|
||||
to: process.env.CONTACT_RECEIVER,
|
||||
replyTo: email,
|
||||
subject: `New Contact Form Submission: ${subject}`,
|
||||
html: `
|
||||
<div style="font-family: sans-serif; color: #333; max-width: 600px; margin: 0 auto; border: 1px solid #eee; padding: 20px; border-radius: 8px;">
|
||||
<h2 style="color: #c01227; border-bottom: 2px solid #c01227; padding-bottom: 10px; margin-top: 0;">New Contact Form Submission</h2>
|
||||
<p><strong>Name:</strong> ${fullName}</p>
|
||||
<p><strong>Email:</strong> ${email}</p>
|
||||
<p><strong>Subject:</strong> ${subject}</p>
|
||||
<p><strong>Message:</strong></p>
|
||||
<blockquote style="background: #f9f9f9; padding: 15px; border-left: 4px solid #c01227; margin: 0; font-style: italic;">
|
||||
${message.replace(/\n/g, "<br />")}
|
||||
</blockquote>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error("Email send error:", error);
|
||||
const errorMessage = error instanceof Error ? error.message : "Failed to send the email. Please try again later.";
|
||||
return { success: false, error: errorMessage };
|
||||
}
|
||||
}
|
||||
@@ -15,14 +15,14 @@ export const metadata = {
|
||||
|
||||
export default function AboutUsPage() {
|
||||
return (
|
||||
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div id="about" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="86" className="elementor elementor-86 elementor-59">
|
||||
<AboutHero />
|
||||
<TheDoormileWay />
|
||||
<EVLogisticSection />
|
||||
<WomenSection />
|
||||
{/* <WomenSection /> */}
|
||||
<CompetitiveEdge />
|
||||
<IntelligenceGrid />
|
||||
<OurTeam />
|
||||
|
||||
15
src/app/air-freight/page.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { permanentRedirect } from "next/navigation";
|
||||
|
||||
export const metadata = {
|
||||
alternates: {
|
||||
canonical: "https://doormile.com/doormile-wings",
|
||||
},
|
||||
robots: {
|
||||
index: false,
|
||||
follow: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default function AirFreightRedirectPage() {
|
||||
permanentRedirect("/doormile-wings");
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import { getPostBySlug, getAllSlugs, SITE_URL } from "@/data/blog";
|
||||
|
||||
type Params = { slug: string };
|
||||
|
||||
// Required for `output: "export"` — prerender every post at build time.
|
||||
// Required for `output: "export"`: prerender every post at build time.
|
||||
export function generateStaticParams(): Params[] {
|
||||
return getAllSlugs().map((slug) => ({ slug }));
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ import BlogGrid from "@/components/sections/BlogGrid";
|
||||
|
||||
export const metadata = {
|
||||
title: "Blog – Doormile",
|
||||
description: "Insights and logistics intelligence from the team behind Doormile. Learn how AI is transforming EV planning and last-mile operations.",
|
||||
description: "Practical notes on delivery planning, EV fleet operations, route optimisation, charging, and last-mile performance from the Doormile team.",
|
||||
};
|
||||
|
||||
export default function BlogPage() {
|
||||
return (
|
||||
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div id="blogs" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="104" className="elementor elementor-104">
|
||||
|
||||
62
src/app/doormile-wings/page.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import WingsHero from "@/components/sections/WingsHero";
|
||||
import WingsWhyGrid from "@/components/sections/WingsWhyGrid";
|
||||
import WingsSpeedAdvantage from "@/components/sections/WingsSpeedAdvantage";
|
||||
import WingsFeatureGrid from "@/components/sections/WingsFeatureGrid";
|
||||
import WingsIndustries from "@/components/sections/WingsIndustries";
|
||||
import WingsHowItWorks from "@/components/sections/WingsHowItWorks";
|
||||
import WingsFleetStrategy from "@/components/sections/WingsFleetStrategy";
|
||||
import WingsInfrastructure from "@/components/sections/WingsInfrastructure";
|
||||
import WingsMileTruth from "@/components/sections/WingsMileTruth";
|
||||
import WingsRoadmap from "@/components/sections/WingsRoadmap";
|
||||
|
||||
export const metadata = {
|
||||
title: "Doormile Wings – Redefining Domestic Air Logistics Through AI",
|
||||
description: "Doormile Wings links India's major regional capitals with AI-powered, same-day air logistics and zero-emission EV last-mile delivery — where quick commerce meets quick logistics.",
|
||||
alternates: {
|
||||
canonical: "https://doormile.com/doormile-wings",
|
||||
},
|
||||
openGraph: {
|
||||
title: "Doormile Wings – Redefining Domestic Air Logistics Through AI",
|
||||
description: "Same-day air logistics linking India's major regional capitals, powered by MileTruth™ AI and zero-emission EV last-mile delivery.",
|
||||
url: "https://doormile.com/doormile-wings",
|
||||
siteName: "Doormile",
|
||||
type: "website",
|
||||
images: [
|
||||
{
|
||||
url: "https://doormile.com/images/wings-logo.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "Doormile Wings",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Doormile Wings – Redefining Domestic Air Logistics Through AI",
|
||||
description: "Same-day air logistics linking India's major regional capitals, powered by MileTruth™ AI and zero-emission EV last-mile delivery.",
|
||||
images: ["https://doormile.com/images/wings-logo.png"],
|
||||
},
|
||||
};
|
||||
|
||||
export default function DoormileWingsPage() {
|
||||
return (
|
||||
<div id="doormile-wings" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="95" className="elementor elementor-95 elementor-59">
|
||||
<WingsHero />
|
||||
<WingsWhyGrid />
|
||||
<WingsSpeedAdvantage />
|
||||
<WingsFeatureGrid />
|
||||
<WingsIndustries />
|
||||
<WingsHowItWorks />
|
||||
<WingsFleetStrategy />
|
||||
<WingsInfrastructure />
|
||||
<WingsMileTruth />
|
||||
<WingsRoadmap />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
123
src/app/empowerment/page.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import EmpowermentHero from "@/components/sections/EmpowermentHero";
|
||||
import EmpowermentVision from "@/components/sections/EmpowermentVision";
|
||||
import EmpowermentStory from "@/components/sections/EmpowermentStory";
|
||||
import WomenSection from "@/components/sections/WomenSection";
|
||||
import EmpowermentPrograms from "@/components/sections/EmpowermentPrograms";
|
||||
import EmpowermentImpact from "@/components/sections/EmpowermentImpact";
|
||||
import EmpowermentHowItWorks from "@/components/sections/EmpowermentHowItWorks";
|
||||
import EmpowermentStories from "@/components/sections/EmpowermentStories";
|
||||
import EmpowermentPartners from "@/components/sections/EmpowermentPartners";
|
||||
import EmpowermentCTA from "@/components/sections/EmpowermentCTA";
|
||||
|
||||
const WINGS_WOMEN_STATS = [
|
||||
{ value: "500", plus: "+", label: "Women Founders" },
|
||||
{ value: "35", plus: "+", label: "Cities Active" },
|
||||
{ value: "100", plus: "+", label: "Enterprises Launched" },
|
||||
];
|
||||
|
||||
const WINGS_WOMEN_CARDS = [
|
||||
{
|
||||
title: "Venture Building",
|
||||
desc: "End-to-end support for women launching logistics enterprises — from ideation to market entry.",
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M4 19V5" />
|
||||
<path d="M4 7h12l-2 4 2 4H4" />
|
||||
<path d="M18 19h2" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Entrepreneurship",
|
||||
desc: "Women building, owning, and scaling sustainable businesses within the logistics ecosystem.",
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect x="3" y="7" width="18" height="13" rx="2" />
|
||||
<path d="M8 7V5a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M3 12h18" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Founder Networks",
|
||||
desc: "Peer communities and strategic connections that accelerate growth and open new markets.",
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="8" cy="8" r="3" />
|
||||
<circle cx="16" cy="8" r="3" />
|
||||
<path d="M2.5 20c.7-3.1 2.8-5 5.5-5s4.8 1.9 5.5 5" />
|
||||
<path d="M10.5 20c.7-3.1 2.8-5 5.5-5s4.8 1.9 5.5 5" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Enterprise Leadership",
|
||||
desc: "Strategic decision-making, operational excellence, and vision-driven leadership for women founders.",
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="9" r="5" />
|
||||
<path d="M9 13.5 7.5 21 12 18l4.5 3-1.5-7.5" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export const metadata = {
|
||||
title: "Doormile Wings — Women Entrepreneurship Initiative",
|
||||
description: "Doormile Wings empowers women to build, own, and lead enterprises within the logistics ecosystem through strategic partnerships, founder networks, and entrepreneurial infrastructure.",
|
||||
alternates: {
|
||||
canonical: "https://doormile.com/empowerment",
|
||||
},
|
||||
openGraph: {
|
||||
title: "Doormile Wings — Women Entrepreneurship Initiative",
|
||||
description: "An entrepreneurial ecosystem empowering women to launch, grow, and lead logistics enterprises with strategic partnerships and industry collaboration.",
|
||||
url: "https://doormile.com/empowerment",
|
||||
siteName: "Doormile",
|
||||
type: "website",
|
||||
images: [
|
||||
{
|
||||
url: "https://doormile.com/images/wings-logo.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "Doormile Wings — Women Entrepreneurship Initiative",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Doormile Wings — Women Entrepreneurship Initiative",
|
||||
description: "An entrepreneurial ecosystem empowering women to launch, grow, and lead logistics enterprises with strategic partnerships and industry collaboration.",
|
||||
images: ["https://doormile.com/images/wings-logo.png"],
|
||||
},
|
||||
};
|
||||
|
||||
export default function EmpowermentPage() {
|
||||
return (
|
||||
<div id="empowerment" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="86" className="elementor elementor-86 elementor-59 elementor-empowerment">
|
||||
<EmpowermentHero />
|
||||
<EmpowermentVision />
|
||||
<EmpowermentStory />
|
||||
<WomenSection
|
||||
eyebrow="/ Doormile Wings /"
|
||||
bannerLabel="Women Entrepreneurship"
|
||||
bannerCopy="An ecosystem where women build, own, and scale enterprises across logistics."
|
||||
ctaLabel="Explore the ecosystem"
|
||||
ctaHref="#wings-empowerment-programs"
|
||||
heading="Women Building The Next Mile"
|
||||
stats={WINGS_WOMEN_STATS}
|
||||
cards={WINGS_WOMEN_CARDS}
|
||||
/>
|
||||
<EmpowermentPrograms />
|
||||
<EmpowermentImpact />
|
||||
<EmpowermentHowItWorks />
|
||||
<EmpowermentStories />
|
||||
<EmpowermentPartners />
|
||||
<EmpowermentCTA />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
133
src/app/express/page.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Express – Doormile",
|
||||
description: "Doormile Express — a fast-lane logistics service for time-critical shipments. Coming soon.",
|
||||
alternates: {
|
||||
canonical: "https://doormile.com/express",
|
||||
},
|
||||
robots: {
|
||||
index: false,
|
||||
follow: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default function ExpressPage() {
|
||||
return (
|
||||
<div id="express" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<section className="express-coming-soon">
|
||||
<div className="express-coming-soon-inner">
|
||||
<span className="express-coming-soon-eyebrow">Solutions / Express</span>
|
||||
<h1 className="express-coming-soon-heading">
|
||||
Doormile Express is <span className="express-coming-soon-accent">on its way</span>
|
||||
</h1>
|
||||
<p className="express-coming-soon-text">
|
||||
We're building a fast-lane logistics service for time-critical shipments.
|
||||
Check back soon, or explore what Doormile already delivers today.
|
||||
</p>
|
||||
<div className="express-coming-soon-actions">
|
||||
<Link href="/doormile-wings" prefetch className="logico-alter-button">
|
||||
Explore Doormile Wings
|
||||
</Link>
|
||||
<Link href="/contact" className="express-coming-soon-link">
|
||||
Get notified when we launch →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Self-contained placeholder styling, scoped to .express-coming-soon.
|
||||
Re-declares --logico-dark-text-color/--logico-light-text-color/
|
||||
--logico-accent-color locally: the sitewide :root fallback is the
|
||||
light-theme value (dark text on white), which would render near-
|
||||
black text on this dark section without the override. */}
|
||||
<style
|
||||
suppressHydrationWarning
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
.express-coming-soon {
|
||||
--logico-dark-text-color: #ffffff;
|
||||
--logico-light-text-color: #bebebe;
|
||||
--logico-accent-color: #C01227;
|
||||
min-height: calc(100vh - 160px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: clamp(48px, 8vw, 120px) 24px;
|
||||
background: radial-gradient(120% 120% at 50% 0%, rgba(192, 18, 39, 0.18) 0%, rgba(26, 26, 26, 0.98) 55%, #111111 100%);
|
||||
}
|
||||
.express-coming-soon-inner {
|
||||
max-width: 720px;
|
||||
text-align: center;
|
||||
}
|
||||
.express-coming-soon-eyebrow {
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: var(--logico-accent-color);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.express-coming-soon-heading {
|
||||
font-family: 'Manrope', sans-serif;
|
||||
font-size: clamp(32px, 5vw, 56px);
|
||||
line-height: 1.15em;
|
||||
font-weight: 700;
|
||||
color: var(--logico-dark-text-color);
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
.express-coming-soon-accent {
|
||||
color: var(--logico-accent-color);
|
||||
}
|
||||
.express-coming-soon-text {
|
||||
font-size: 16px;
|
||||
line-height: 1.75em;
|
||||
color: var(--logico-light-text-color);
|
||||
margin: 0 auto 36px;
|
||||
max-width: 520px;
|
||||
}
|
||||
.express-coming-soon-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
}
|
||||
.express-coming-soon .logico-alter-button {
|
||||
color: #ffffff !important;
|
||||
border-color: rgba(255, 255, 255, 0.45) !important;
|
||||
background: transparent !important;
|
||||
}
|
||||
.express-coming-soon .logico-alter-button:hover {
|
||||
background: #ffffff !important;
|
||||
color: #1a1a1a !important;
|
||||
border-color: #ffffff !important;
|
||||
}
|
||||
.express-coming-soon-link {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--logico-light-text-color);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 4px;
|
||||
}
|
||||
.express-coming-soon-link:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.express-coming-soon-actions {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -10,6 +10,27 @@ html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
SITE-WIDE STICKY FIX
|
||||
The legacy Elementor build sets `.body-container { overflow: hidden }`
|
||||
(public/css/site.css, generated — do not edit there). Any ancestor
|
||||
with non-visible overflow becomes the containing block for
|
||||
`position: sticky` descendants; since `.body-container` itself never
|
||||
actually scrolls (the real scrollbar lives on <body>), that made every
|
||||
`position: sticky` element on the site inert — it just scrolled away
|
||||
in normal flow instead of pinning.
|
||||
Note: setting overflow-x:hidden paired with overflow-y:visible gets
|
||||
silently coerced to overflow-y:auto by the CSS spec (an "auto" value on
|
||||
one axis when the other is non-visible) — which ALSO still counts as a
|
||||
scroll container and breaks sticky the same way. So this must be fully
|
||||
visible on both axes. <body> already has overflow-x: hidden site-wide
|
||||
(from the same legacy stylesheet), so horizontal bleed is still safely
|
||||
clipped there — this rule doesn't need to repeat it.
|
||||
============================================================ */
|
||||
.body-container {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
GLOBAL SPACING SYSTEM
|
||||
A single shared vertical-rhythm scale so every section uses
|
||||
@@ -25,6 +46,7 @@ html {
|
||||
--space-section: clamp(40px, 5vw, 64px);
|
||||
--space-section-lg: clamp(52px, 6vw, 80px);
|
||||
--space-hero-gap: clamp(36px, 4.5vw, 64px);
|
||||
--dm-mobile-gutter: 10px;
|
||||
}
|
||||
|
||||
.dm-section {
|
||||
@@ -152,16 +174,21 @@ body {
|
||||
#masthead .elementor-element.elementor-element-0b7bf6f > .elementor-widget-container {
|
||||
padding: 0 42px !important;
|
||||
border-radius: 22px !important;
|
||||
height: 58px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
#masthead .elementor-element.elementor-element-0b7bf6f .header-menu-container .main-menu > li > a {
|
||||
padding-top: 15px !important;
|
||||
padding-bottom: 16px !important;
|
||||
padding-top: 6px !important;
|
||||
padding-bottom: 6px !important;
|
||||
padding-left: 14px !important;
|
||||
padding-right: 14px !important;
|
||||
font-size: 15px !important;
|
||||
line-height: 1.2 !important;
|
||||
white-space: nowrap !important;
|
||||
min-height: auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu {
|
||||
@@ -178,7 +205,11 @@ body {
|
||||
}
|
||||
|
||||
#masthead .elementor-element.elementor-element-466de1b.dm-header-scrolled {
|
||||
top: 0 !important;
|
||||
top: 15px !important;
|
||||
left: 20px !important;
|
||||
right: 20px !important;
|
||||
border-radius: 24px !important;
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +491,7 @@ body {
|
||||
@media (max-width: 720px) {
|
||||
.dm-contact-left {
|
||||
min-height: auto;
|
||||
padding: 42px 22px 58px;
|
||||
padding: 42px 20px 58px;
|
||||
}
|
||||
|
||||
.dm-contact-title {
|
||||
@@ -478,43 +509,43 @@ body {
|
||||
}
|
||||
|
||||
.dm-contact-card {
|
||||
margin: 0 16px 32px;
|
||||
padding: 44px 22px 34px;
|
||||
border-radius: 24px;
|
||||
margin: 0 20px 28px;
|
||||
padding: 28px 20px 24px;
|
||||
border-radius: 28px;
|
||||
}
|
||||
|
||||
.dm-contact-card h3 {
|
||||
margin-bottom: 34px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.dm-contact-form {
|
||||
gap: 20px;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
.dm-contact-form input {
|
||||
height: 60px;
|
||||
padding: 0 20px;
|
||||
height: 56px;
|
||||
padding: 0 18px;
|
||||
}
|
||||
|
||||
.dm-contact-form textarea {
|
||||
min-height: 190px;
|
||||
padding: 20px;
|
||||
min-height: 170px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.dm-contact-submit {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.dm-contact-submit span:first-child {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
padding: 0 22px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.dm-contact-submit-icon {
|
||||
width: 64px;
|
||||
min-width: 64px;
|
||||
width: 60px;
|
||||
min-width: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,7 +568,139 @@ body {
|
||||
.industry-solutions-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}.industry-card-link {
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-3b4a7cc {
|
||||
--padding-left: 0px !important;
|
||||
--padding-right: 0px !important;
|
||||
padding-left: 0px !important;
|
||||
padding-right: 0px !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-3b4a7cc > .e-con-inner {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-3b4a7cc > .e-con-inner {
|
||||
max-width: 100% !important;
|
||||
width: 100% !important;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-d602f7f {
|
||||
--padding-left: 20px !important;
|
||||
--padding-right: 20px !important;
|
||||
padding-left: 20px !important;
|
||||
padding-right: 20px !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-f64bd88,
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-5ed2dbb,
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-6829276 {
|
||||
--padding-left: 0px !important;
|
||||
--padding-right: 0px !important;
|
||||
--margin-left: 0px !important;
|
||||
--margin-right: 0px !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-6829276 {
|
||||
--e-con-grid-template-columns: minmax(0, 1fr) !important;
|
||||
--grid-justify-content: stretch !important;
|
||||
--justify-items: stretch !important;
|
||||
grid-template-columns: minmax(0, 1fr) !important;
|
||||
justify-content: stretch !important;
|
||||
justify-items: stretch !important;
|
||||
min-width: 0 !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .industry-solutions-grid,
|
||||
.elementor.elementor-61 .industry-card-link {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .industry-solutions-grid {
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-89a0ca1,
|
||||
.elementor.elementor-86 .elementor-element.elementor-element-c2c601a,
|
||||
.elementor.elementor-104 .elementor-element.elementor-element-c70681e {
|
||||
--padding-left: var(--dm-mobile-gutter) !important;
|
||||
--padding-right: var(--dm-mobile-gutter) !important;
|
||||
padding-left: var(--dm-mobile-gutter) !important;
|
||||
padding-right: var(--dm-mobile-gutter) !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-89a0ca1 > .e-con-inner,
|
||||
.elementor.elementor-86 .elementor-element.elementor-element-c2c601a > .e-con-inner,
|
||||
.elementor.elementor-104 .elementor-element.elementor-element-c70681e > .e-con-inner {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.elementor.elementor-61 .elementor-element.elementor-element-89a0ca1 > .e-con-inner > .e-con,
|
||||
.elementor.elementor-86 .elementor-element.elementor-element-c2c601a > .e-con-inner > .e-con,
|
||||
.elementor.elementor-104 .elementor-element.elementor-element-c70681e > .e-con-inner > .e-con {
|
||||
--padding-left: 0px !important;
|
||||
--padding-right: 0px !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.comparison-section .container {
|
||||
width: calc(100% - (var(--dm-mobile-gutter) * 2)) !important;
|
||||
max-width: calc(100% - (var(--dm-mobile-gutter) * 2)) !important;
|
||||
margin-left: auto !important;
|
||||
margin-right: auto !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.wcd-inner {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
}
|
||||
|
||||
.industry-card-link {
|
||||
position: relative;
|
||||
height: 600px;
|
||||
border-radius: 30px;
|
||||
@@ -831,6 +994,49 @@ body {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
SHARED PAGE CONTENT CONTAINER
|
||||
Matches the Hero/Header/Footer's real rendered OUTER edge, not the
|
||||
Footer's narrower inner text column. The Hero card
|
||||
(.owl-stage-outer, via .wings-hero-page.elementor-element-741f56c)
|
||||
and the Footer's outer band (.elementor-element-b29b8fc) both sit a
|
||||
fixed, uncapped 20px in from the viewport edge at every desktop
|
||||
width (verified 1280px-2400px — no max-width ever kicks in). Apply
|
||||
this class to any Wings-page section's content wrapper to guarantee
|
||||
its cards/timeline/grid hug those same edges instead of sitting
|
||||
narrower and more centered.
|
||||
============================================================ */
|
||||
.dm-section-container {
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
box-sizing: border-box;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.dm-section-container {
|
||||
padding-left: var(--dm-mobile-gutter, 10px);
|
||||
padding-right: var(--dm-mobile-gutter, 10px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Doormile Wings hero frame: the generic vendor CSS assigns 32px padding to
|
||||
.elementor-element-741f56c on all pages; Home's frame is 20px (scoped
|
||||
to .elementor-61). Scope the same 20px frame to the Doormile Wings hero so
|
||||
the card alignment matches Home and Solutions exactly. */
|
||||
@media (min-width: 1025px) {
|
||||
.wings-hero-page.elementor-element-741f56c,
|
||||
.af-hero-page.elementor-element-741f56c {
|
||||
--padding-top: 20px;
|
||||
--padding-right: 20px;
|
||||
--padding-bottom: 20px;
|
||||
--padding-left: 20px;
|
||||
padding: 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom premium animations keyframes */
|
||||
@keyframes shimmer-sweep {
|
||||
0% {
|
||||
@@ -899,12 +1105,14 @@ body {
|
||||
to 600px at <= 840px. Earlier this card shrank at <= 1536px, which is why the
|
||||
About hero looked smaller than Home on MacBook M1/Pro (their ~1440-1512px logical
|
||||
width falls below 1536px). Match the home breakpoint instead. */
|
||||
@media (max-width: 840px) {
|
||||
@media (max-width: 1024px) {
|
||||
.custom-standard-hero-container {
|
||||
/* No top gap on mobile: the hero card sits flush to the top so the floating
|
||||
/* No top gap on mobile/tablet: the hero card sits flush to the top so the floating
|
||||
navbar rests directly on the hero instead of leaving a band above it. */
|
||||
padding: 0 10px 10px 10px !important;
|
||||
}
|
||||
}
|
||||
@media (max-width: 840px) {
|
||||
.custom-standard-hero-card {
|
||||
height: 600px !important;
|
||||
min-height: 600px !important;
|
||||
@@ -912,6 +1120,81 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile hero/header normalization
|
||||
Home is the reference: at phone width the hero wrapper is full-width with
|
||||
10px side gutters, the visible hero card is 370px wide, starts 7px from the
|
||||
viewport top, and the first section begins immediately after the hero wrapper.
|
||||
Apply those same computed values to every hero template instead of carrying
|
||||
separate page-level mobile overrides. */
|
||||
@media (max-width: 840px) {
|
||||
body .elementor .elementor-element.elementor-element-741f56c,
|
||||
body .custom-standard-hero-container,
|
||||
body .miletruth-hero .elementor-element.elementor-element-86f3204 {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
padding: 0 var(--dm-mobile-gutter) var(--dm-mobile-gutter) var(--dm-mobile-gutter) !important;
|
||||
--padding-top: 0px !important;
|
||||
--padding-right: var(--dm-mobile-gutter) !important;
|
||||
--padding-bottom: var(--dm-mobile-gutter) !important;
|
||||
--padding-left: var(--dm-mobile-gutter) !important;
|
||||
--padding-block-start: 0px !important;
|
||||
box-sizing: border-box !important;
|
||||
border-radius: 0 !important;
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
body .elementor .elementor-element.elementor-element-6c7cbcb .owl-stage-outer,
|
||||
body .custom-standard-hero-card,
|
||||
body .miletruth-hero .miletruth-hero-container {
|
||||
width: 100% !important;
|
||||
height: 600px !important;
|
||||
min-height: 600px !important;
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
border-radius: 25px !important;
|
||||
overflow: hidden !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
body .elementor .elementor-element.elementor-element-6c7cbcb .owl-carousel.owl-theme .content-item,
|
||||
body .elementor .elementor-element.elementor-element-6c7cbcb .content-item,
|
||||
body .miletruth-hero .slide-content {
|
||||
height: 600px !important;
|
||||
min-height: 600px !important;
|
||||
}
|
||||
|
||||
body .elementor .elementor-element.elementor-element-741f56c + *,
|
||||
body .custom-standard-hero-container + *,
|
||||
body .elementor-63.miletruth-hero + * {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
body .elementor .elementor-element.elementor-element-6c7cbcb .owl-stage-outer,
|
||||
body .custom-standard-hero-card,
|
||||
body .miletruth-hero .miletruth-hero-container {
|
||||
height: 520px !important;
|
||||
min-height: 520px !important;
|
||||
margin-top: 7px !important;
|
||||
border-radius: 25px !important;
|
||||
}
|
||||
|
||||
body .elementor .elementor-element.elementor-element-6c7cbcb .owl-carousel.owl-theme .content-item,
|
||||
body .elementor .elementor-element.elementor-element-6c7cbcb .content-item,
|
||||
body .miletruth-hero .slide-content {
|
||||
height: 520px !important;
|
||||
min-height: 520px !important;
|
||||
}
|
||||
|
||||
body .miletruth-hero .miletruth-hero-container {
|
||||
padding-top: 60px !important;
|
||||
padding-bottom: 60px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Consistent flush hero across every page on mobile/tablet — the floating navbar
|
||||
(position:absolute; top:5px) should rest directly on the hero with no band
|
||||
above it. Home / How It Works / Solutions share .elementor-element-741f56c;
|
||||
@@ -929,5 +1212,31 @@ body {
|
||||
.miletruth-hero-container {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
/* Audit & align section rhythm on mobile/tablet across all content pages */
|
||||
.elementor-86 #women-entrepreneurship.elementor-element-bbc6760,
|
||||
.elementor-86 .comparison-section,
|
||||
.elementor-86 .elementor-element.elementor-element-bbc6760:not(#women-entrepreneurship),
|
||||
.elementor-86 .elementor-element.elementor-element-c2c601a,
|
||||
.elementor-59 .elementor-element.elementor-element-bbc6760,
|
||||
.elementor-104 .elementor-element.elementor-element-c70681e {
|
||||
margin-top: var(--space-section) !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* Solutions page: First section under Solutions Hero gets the hero gap */
|
||||
.elementor-59 .elementor-element.elementor-element-3b4a7cc {
|
||||
margin-top: var(--space-hero-gap) !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* About page: First section under About Hero gets the hero gap */
|
||||
.elementor-86 .elementor-element.elementor-element-88745f4:first-of-type {
|
||||
margin-top: var(--space-hero-gap) !important;
|
||||
}
|
||||
/* About page: Subsequent sections get standard section spacing */
|
||||
.elementor-86 .elementor-element.elementor-element-88745f4 ~ .elementor-element.elementor-element-88745f4 {
|
||||
margin-top: var(--space-section) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export const metadata = {
|
||||
|
||||
export default function HowItWorksPage() {
|
||||
return (
|
||||
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div id="how-it-works" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="59" className="elementor elementor-59">
|
||||
|
||||
@@ -90,7 +90,7 @@ export default function RootLayout({
|
||||
│ └─ footer
|
||||
SSR ships body with shared WP/Elementor classes; BodyClasses (client) refines per route.
|
||||
*/}
|
||||
<body className={SHARED_BODY_CLASSES}>
|
||||
<body className={SHARED_BODY_CLASSES} suppressHydrationWarning>
|
||||
<BodyClasses />
|
||||
<LoadingScreen />
|
||||
<AnimationProvider>
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from "react";
|
||||
import MileTruthHero from "../../components/sections/MileTruthHero";
|
||||
import Workflow1 from "../../components/sections/Workflow1";
|
||||
import Workflow2 from "../../components/sections/Workflow2";
|
||||
import Workflow4 from "../../components/sections/Workflow4";
|
||||
import Workflow3Lazy from "../../components/sections/Workflow3Lazy";
|
||||
|
||||
export const metadata = {
|
||||
@@ -11,13 +12,14 @@ export const metadata = {
|
||||
|
||||
export default function MileTruthPage() {
|
||||
return (
|
||||
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div id="miletruth" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="59" className="elementor elementor-59">
|
||||
<MileTruthHero />
|
||||
<Workflow1 />
|
||||
<Workflow2 />
|
||||
<Workflow4 />
|
||||
<Workflow3Lazy />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@ export const metadata: Metadata = {
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div id="home" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="61" className="elementor elementor-61">
|
||||
|
||||
80
src/app/sitemap.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { MetadataRoute } from "next";
|
||||
|
||||
export const dynamic = "force-static";
|
||||
|
||||
const BASE_URL = "https://doormile.com";
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const now = new Date();
|
||||
|
||||
const staticRoutes: MetadataRoute.Sitemap = [
|
||||
{
|
||||
url: `${BASE_URL}/`,
|
||||
lastModified: now,
|
||||
changeFrequency: "weekly",
|
||||
priority: 1.0,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/how-it-works`,
|
||||
lastModified: now,
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/miletruth`,
|
||||
lastModified: now,
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/solutions`,
|
||||
lastModified: now,
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/doormile-wings`,
|
||||
lastModified: now,
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.8,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/about-us`,
|
||||
lastModified: now,
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.7,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/blog`,
|
||||
lastModified: now,
|
||||
changeFrequency: "weekly",
|
||||
priority: 0.7,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/contact`,
|
||||
lastModified: now,
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.6,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/privacy-policy`,
|
||||
lastModified: now,
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.3,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/terms-of-service`,
|
||||
lastModified: now,
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.3,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/cookie-policy`,
|
||||
lastModified: now,
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.3,
|
||||
},
|
||||
];
|
||||
|
||||
return staticRoutes;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export default function SolutionsPage() {
|
||||
}
|
||||
`}} />
|
||||
|
||||
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div id="solutions" className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
|
||||
<div className="content">
|
||||
<div className="content-inner">
|
||||
<div data-elementor-type="wp-page" data-elementor-id="59" className="elementor elementor-59">
|
||||
|
||||
@@ -6,7 +6,7 @@ import { blogPosts } from "@/data/blog";
|
||||
|
||||
/**
|
||||
* Client-side blog search. The site is a static export, so there is no search
|
||||
* server — we filter the known posts in the browser and link straight to the
|
||||
* server. We filter the known posts in the browser and link straight to the
|
||||
* matching /blog/[slug] routes.
|
||||
*/
|
||||
export default function BlogSearch() {
|
||||
|
||||
@@ -72,10 +72,10 @@ export default function BlogSidebar({ current }: { current?: BlogPost }) {
|
||||
|
||||
{/* CTA Card */}
|
||||
<section className="dm-blog-widget dm-blog-cta-card">
|
||||
<h2 className="dm-blog-cta-title">Ready to optimise your fleet?</h2>
|
||||
<h2 className="dm-blog-cta-title">Planning delivery routes?</h2>
|
||||
<p className="dm-blog-cta-text">
|
||||
See how MileTruth™ AI cuts distance, vehicles and emissions — without
|
||||
missing an SLA.
|
||||
Talk to us about reducing wasted distance, missed windows, and avoidable
|
||||
vehicle time.
|
||||
</p>
|
||||
<Link href="/contact" className="dm-blog-cta-btn">
|
||||
Contact Us
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import emailjs from "@emailjs/browser";
|
||||
import { submitContactForm } from "@/lib/contactForm";
|
||||
import { ScrollReveal } from "@/animations/Reveal";
|
||||
|
||||
export default function Footer() {
|
||||
@@ -53,40 +53,44 @@ export default function Footer() {
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
// EmailJS is fully client-side — only the public-safe credentials are used
|
||||
// (Service ID, Template ID, Public Key). No private/secret key, no backend route.
|
||||
const serviceId = process.env.NEXT_PUBLIC_EMAILJS_SERVICE_ID;
|
||||
const templateId = process.env.NEXT_PUBLIC_EMAILJS_TEMPLATE_ID;
|
||||
const publicKey = process.env.NEXT_PUBLIC_EMAILJS_PUBLIC_KEY;
|
||||
if (!serviceId || !templateId || !publicKey) {
|
||||
console.error("EmailJS env vars are missing — set NEXT_PUBLIC_EMAILJS_* in .env.local");
|
||||
setFormStatus("error");
|
||||
return;
|
||||
}
|
||||
|
||||
setFormStatus("submitting");
|
||||
try {
|
||||
await emailjs.send(
|
||||
serviceId,
|
||||
templateId,
|
||||
{
|
||||
name: formData.fullName,
|
||||
email: formData.email,
|
||||
subject: formData.subject,
|
||||
message: formData.message,
|
||||
},
|
||||
publicKey,
|
||||
);
|
||||
setFormStatus("success");
|
||||
setFormData({ fullName: "", email: "", subject: "", message: "" });
|
||||
const res = await submitContactForm(formData);
|
||||
|
||||
if (res.success) {
|
||||
setFormStatus("success");
|
||||
setFormData({ fullName: "", email: "", subject: "", message: "" });
|
||||
} else {
|
||||
console.error("Failed to submit contact form");
|
||||
setFormStatus("error");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
console.error("Error submitting contact form:", err);
|
||||
setFormStatus("error");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Floating-label fix: the theme only lifts the label on :focus-within, so a
|
||||
filled-but-blurred field drops its label back onto the typed value and the
|
||||
two overlap. Keep the label lifted (and the notch in the top border open)
|
||||
whenever the field carries a value, via the .dm-field-filled class below. */}
|
||||
<style dangerouslySetInnerHTML={{ __html: `
|
||||
.logico-form-field.dm-field-filled .logico-label-wrapper>label {
|
||||
font-size: 14px;
|
||||
top: -14px;
|
||||
color: var(--logico-dark-text-color);
|
||||
}
|
||||
.logico-form-field.dm-field-filled .logico-label-placeholder .logico-label-placeholder-text:before {
|
||||
right: 100%;
|
||||
left: initial;
|
||||
}
|
||||
.logico-form-field.dm-field-filled .logico-label-placeholder .logico-label-placeholder-text:after {
|
||||
left: 100%;
|
||||
right: initial;
|
||||
}
|
||||
` }} />
|
||||
<footer
|
||||
data-rocket-location-hash="1eeca93394c4fc14089e9d12a2a92e22"
|
||||
itemScope
|
||||
@@ -197,14 +201,14 @@ export default function Footer() {
|
||||
<line x1="8.59" y1="13.51" x2="15.42" y2="17.49" />
|
||||
<line x1="15.41" y1="6.51" x2="8.59" y2="10.49" />
|
||||
</svg>
|
||||
<span>Social network</span>
|
||||
<span>Social</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="elementor-element elementor-element-a6bccba elementor-shape-square elementor-grid-0 elementor-widget elementor-widget-social-icons" data-id="a6bccba" data-element_type="widget" data-e-type="widget" data-widget_type="social-icons.default">
|
||||
<div className="elementor-widget-container">
|
||||
<div className="elementor-social-icons-wrapper elementor-grid" role="list" style={socialIconSpacing}>
|
||||
<span className="elementor-grid-item" role="listitem" style={{padding:"0 15px"}}>
|
||||
{/* <span className="elementor-grid-item" role="listitem" style={{padding:"0 15px"}}>
|
||||
<a className="elementor-icon elementor-social-icon elementor-social-icon-facebook-f elementor-repeater-item-3fbe893" href="https://www.facebook.com" target="_blank" rel="noopener noreferrer">
|
||||
<span className="elementor-screen-only">Facebook</span>
|
||||
<svg aria-hidden="true" className="e-font-icon-svg e-fab-facebook-f" viewBox="0 0 320 512" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -219,7 +223,7 @@ export default function Footer() {
|
||||
<path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</span> */}
|
||||
<span className="elementor-grid-item" role="listitem"style={{padding:"0 15px"}}>
|
||||
<a className="elementor-icon elementor-social-icon elementor-social-icon-linkedin-in elementor-repeater-item-38e1bcc" href="https://www.linkedin.com" target="_blank" rel="noopener noreferrer">
|
||||
<span className="elementor-screen-only">LinkedIn</span>
|
||||
@@ -255,7 +259,7 @@ export default function Footer() {
|
||||
<div className="wpforms-container wpforms-render-modern" id="wpforms-369">
|
||||
<form id="wpforms-form-369" className="wpforms-validate wpforms-form" onSubmit={handleSubmit}>
|
||||
<div className="wpforms-field-container">
|
||||
<div className="wpforms-field-wrapper logico-form-field">
|
||||
<div className={`wpforms-field-wrapper logico-form-field${formData.fullName ? " dm-field-filled" : ""}`}>
|
||||
<div className="logico-label-wrapper" style={{marginBottom:"12px"}}>
|
||||
<div className="logico-label-placeholder">
|
||||
<div className="logico-label-placeholder-text">Full name</div>
|
||||
@@ -272,7 +276,7 @@ export default function Footer() {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="wpforms-field-wrapper logico-form-field">
|
||||
<div className={`wpforms-field-wrapper logico-form-field${formData.email ? " dm-field-filled" : ""}`}>
|
||||
<div className="logico-label-wrapper" style={{marginBottom:"12px"}}>
|
||||
<div className="logico-label-placeholder">
|
||||
<div className="logico-label-placeholder-text">Email</div>
|
||||
@@ -289,7 +293,7 @@ export default function Footer() {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="wpforms-field-wrapper logico-form-field">
|
||||
<div className={`wpforms-field-wrapper logico-form-field${formData.subject ? " dm-field-filled" : ""}`}>
|
||||
<div className="logico-label-wrapper" style={{marginBottom:"12px"}}>
|
||||
<div className="logico-label-placeholder">
|
||||
<div className="logico-label-placeholder-text">Subject</div>
|
||||
@@ -306,7 +310,7 @@ export default function Footer() {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div className="wpforms-field-wrapper logico-form-field">
|
||||
<div className={`wpforms-field-wrapper logico-form-field${formData.message ? " dm-field-filled" : ""}`}>
|
||||
<div className="logico-label-wrapper" style={{marginBottom:"12px"}}>
|
||||
<div className="logico-label-placeholder">
|
||||
<div className="logico-label-placeholder-text">Message</div>
|
||||
@@ -384,7 +388,7 @@ export default function Footer() {
|
||||
<div className="elementor-element elementor-element-e4e6486 elementor-shape-square elementor-grid-0 elementor-widget elementor-widget-social-icons" data-id="e4e6486" data-element_type="widget" data-e-type="widget" data-widget_type="social-icons.default">
|
||||
<div className="elementor-widget-container">
|
||||
<div className="elementor-social-icons-wrapper elementor-grid" role="list" style={socialIconSpacing}>
|
||||
<span className="elementor-grid-item" role="listitem" style={{padding:"0 15px"}}>
|
||||
{/* <span className="elementor-grid-item" role="listitem" style={{padding:"0 15px"}}>
|
||||
<a className="elementor-icon elementor-social-icon elementor-social-icon-facebook-f" href="https://www.facebook.com" target="_blank" rel="noopener noreferrer">
|
||||
<span className="elementor-screen-only">Facebook</span>
|
||||
<svg aria-hidden="true" className="e-font-icon-svg e-fab-facebook-f" viewBox="0 0 320 512" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -399,7 +403,7 @@ export default function Footer() {
|
||||
<path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</span>
|
||||
</span> */}
|
||||
<span className="elementor-grid-item" role="listitem" style={{padding:"0 15px"}}>
|
||||
<a className="elementor-icon elementor-social-icon elementor-social-icon-linkedin-in" href="https://www.linkedin.com" target="_blank" rel="noopener noreferrer">
|
||||
<span className="elementor-screen-only">LinkedIn</span>
|
||||
@@ -454,6 +458,9 @@ export default function Footer() {
|
||||
<div className="elementor-element elementor-element-a219b7d elementor-widget elementor-widget-logico_custom_navigation_menu" data-id="a219b7d" data-element_type="widget" data-e-type="widget" data-widget_type="logico_custom_navigation_menu.default">
|
||||
<div className="elementor-widget-container">
|
||||
<ul className="logico-custom-menu-widget">
|
||||
<li>
|
||||
<Link href="/doormile-wings">Doormile Wings</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/about-us">About Us</Link>
|
||||
</li>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Menu open/close + sidebar state is read from HeaderUIProvider so BodyOverlay (sibling at body level) can react.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { KeyboardEvent, FocusEvent, MouseEvent, useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { usePathname } from "next/navigation";
|
||||
@@ -19,6 +19,9 @@ const CURRENT_PAGE_MAP: Record<string, string> = {
|
||||
"/how-it-works": "how-it-works",
|
||||
"/miletruth": "miletruth",
|
||||
"/solutions": "solutions",
|
||||
"/doormile-wings": "doormile-wings",
|
||||
"/empowerment": "entarpreneurship",
|
||||
"/express": "express",
|
||||
"/about-us": "about",
|
||||
"/blog": "blogs",
|
||||
};
|
||||
@@ -28,9 +31,13 @@ const CURRENT_PAGE_ALIASES: Record<string, string[]> = {
|
||||
home: ["home"],
|
||||
"how-it-works": ["how-it-works", "how-its-works"],
|
||||
miletruth: ["miletruth"],
|
||||
// Solutions is now a plain top-level link — no child pages own its active state.
|
||||
solutions: ["solutions"],
|
||||
about: ["about", "about-us", "women"],
|
||||
"doormile-wings": ["doormile-wings"],
|
||||
entarpreneurship: ["entarpreneurship"],
|
||||
blogs: ["blogs"],
|
||||
// Company is the dropdown parent for About + Blogs + How It Works — active if any is.
|
||||
company: ["blogs", "how-it-works", "about"],
|
||||
};
|
||||
|
||||
export default function Header() {
|
||||
@@ -44,12 +51,57 @@ export default function Header() {
|
||||
const dmHeaderActive = (key: string) =>
|
||||
(CURRENT_PAGE_ALIASES[key] ?? []).includes(currentPage) ? " active" : "";
|
||||
|
||||
const scrollToNavTarget = (targetId: string) => {
|
||||
const target = document.getElementById(targetId);
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
return;
|
||||
}
|
||||
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
};
|
||||
|
||||
const handleNavClick = (
|
||||
event: MouseEvent<HTMLAnchorElement>,
|
||||
targetPath: string,
|
||||
targetId: string,
|
||||
shouldCloseMenu = false,
|
||||
) => {
|
||||
if (shouldCloseMenu) closeMobileMenu();
|
||||
|
||||
if (pathname !== targetPath) return;
|
||||
|
||||
event.preventDefault();
|
||||
const targetUrl = `${targetPath}#${targetId}`;
|
||||
if (`${window.location.pathname}${window.location.hash}` !== targetUrl) {
|
||||
window.history.pushState(null, "", targetUrl);
|
||||
}
|
||||
requestAnimationFrame(() => scrollToNavTarget(targetId));
|
||||
};
|
||||
|
||||
// Mirror of header.php <script> block (lines 628-660):
|
||||
// - on doc.ready: $('.header-hide-until-scroll').addClass('header-visible-scrolled')
|
||||
// - on scroll: toggleClass('dm-header-scrolled', scrollTop > 50)
|
||||
const [visibleScrolled, setVisibleScrolled] = useState(false);
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
|
||||
// Company dropdown (desktop) / accordion (mobile). Local to Header —
|
||||
// unlike isMenuOpen/isSidebarOpen (HeaderUIProvider), no sibling component
|
||||
// needs to read this.
|
||||
const [isDesktopCompanyOpen, setDesktopCompanyOpen] = useState(false);
|
||||
const [isMobileCompanyOpen, setMobileCompanyOpen] = useState(false);
|
||||
|
||||
// Collapse the accordion whenever the off-canvas menu closes, so it isn't
|
||||
// left expanded the next time the menu opens.
|
||||
const closeMobileMenu = () => {
|
||||
setMobileCompanyOpen(false);
|
||||
closeAll();
|
||||
};
|
||||
const toggleMobileMenu = () => {
|
||||
setMobileCompanyOpen(false);
|
||||
toggleMenu();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handle = requestAnimationFrame(() => {
|
||||
setVisibleScrolled(true);
|
||||
@@ -406,27 +458,88 @@ export default function Header() {
|
||||
<nav>
|
||||
<ul id="menu-main-menu" className="main-menu">
|
||||
<li id="menu-item-10508" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10508${dmHeaderActive("home")}`}>
|
||||
<Link href="/">Home</Link>
|
||||
<Link href="/#home" onClick={(event) => handleNavClick(event, "/", "home")}>Home</Link>
|
||||
</li>
|
||||
<li id="menu-item-10509" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("how-it-works")}`}>
|
||||
<Link href="/how-it-works">How It Works</Link>
|
||||
<li id="menu-item-10509" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("doormile-wings")}`}>
|
||||
<Link href="/doormile-wings" prefetch>Wings</Link>
|
||||
</li>
|
||||
<li id="menu-item-10510" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10510${dmHeaderActive("miletruth")}`}>
|
||||
<Link href="/miletruth">MileTruth™ AI</Link>
|
||||
<Link href="/miletruth#miletruth" onClick={(event) => handleNavClick(event, "/miletruth", "miletruth")}>MileTruth™ AI</Link>
|
||||
</li>
|
||||
<li id="menu-item-10511" className={`menu-item menu-item-type-custom menu-item-10511${dmHeaderActive("solutions")}`}>
|
||||
<Link href="/solutions">Solutions</Link>
|
||||
<li id="menu-item-10511" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10511${dmHeaderActive("solutions")}`}>
|
||||
<Link href="/solutions" prefetch>Solutions</Link>
|
||||
</li>
|
||||
<li id="menu-item-10512" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10512${dmHeaderActive("about")}`}>
|
||||
<Link href="/about-us">About</Link>
|
||||
<li id="menu-item-10513" className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10513${dmHeaderActive("entarpreneurship")}`}>
|
||||
<Link href="/empowerment" prefetch>Entrepreneurship</Link>
|
||||
</li>
|
||||
<li id="menu-item-10535" className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-10535${dmHeaderActive("blogs")}`}>
|
||||
<Link href="/blog">Blogs</Link>
|
||||
<li
|
||||
id="menu-item-10535"
|
||||
className={`menu-item menu-item-type-custom menu-item-has-children menu-item-10535${dmHeaderActive("company")}`}
|
||||
onMouseEnter={() => setDesktopCompanyOpen(true)}
|
||||
onMouseLeave={() => setDesktopCompanyOpen(false)}
|
||||
onKeyDown={(event: KeyboardEvent<HTMLLIElement>) => {
|
||||
if (event.key !== "Escape") return;
|
||||
setDesktopCompanyOpen(false);
|
||||
event.currentTarget.querySelector<HTMLAnchorElement>(":scope > a")?.focus();
|
||||
}}
|
||||
onBlur={(event: FocusEvent<HTMLLIElement>) => {
|
||||
if (!event.currentTarget.contains(event.relatedTarget as Node)) {
|
||||
setDesktopCompanyOpen(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<a
|
||||
href="#"
|
||||
aria-haspopup="true"
|
||||
aria-expanded={isDesktopCompanyOpen}
|
||||
onFocus={() => setDesktopCompanyOpen(true)}
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
setDesktopCompanyOpen((open) => !open);
|
||||
}}
|
||||
>
|
||||
Company
|
||||
</a>
|
||||
<ul className="dm-solutions-dropdown">
|
||||
<li className={currentPage === "about" ? "dm-child-active" : ""}>
|
||||
<Link
|
||||
href="/about-us#about"
|
||||
onClick={(event) => {
|
||||
setDesktopCompanyOpen(false);
|
||||
handleNavClick(event, "/about-us", "about");
|
||||
}}
|
||||
>
|
||||
About
|
||||
</Link>
|
||||
</li>
|
||||
<li className={currentPage === "blogs" ? "dm-child-active" : ""}>
|
||||
<Link
|
||||
href="/blog#blogs"
|
||||
onClick={(event) => {
|
||||
setDesktopCompanyOpen(false);
|
||||
handleNavClick(event, "/blog", "blogs");
|
||||
}}
|
||||
>
|
||||
Blogs
|
||||
</Link>
|
||||
</li>
|
||||
<li className={currentPage === "how-it-works" ? "dm-child-active" : ""}>
|
||||
<Link
|
||||
href="/how-it-works#how-it-works"
|
||||
onClick={(event) => {
|
||||
setDesktopCompanyOpen(false);
|
||||
handleNavClick(event, "/how-it-works", "how-it-works");
|
||||
}}
|
||||
>
|
||||
How It Works
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div className="menu-trigger" data-id="0b7bf6f" onClick={toggleMenu}>
|
||||
<div className="menu-trigger" data-id="0b7bf6f" onClick={toggleMobileMenu}>
|
||||
<span className="menu-trigger-icon">
|
||||
<span className="hamburger">
|
||||
<span></span>
|
||||
@@ -446,7 +559,7 @@ export default function Header() {
|
||||
<div className="header-icon login-logout">
|
||||
<a href="#" title="Login/Register" className="link-login"></a>
|
||||
</div>
|
||||
<div className="header-icon menu-close" onClick={closeAll}>
|
||||
<div className="header-icon menu-close" onClick={closeMobileMenu}>
|
||||
<span className="menu-close-icon"></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -454,22 +567,55 @@ export default function Header() {
|
||||
<nav>
|
||||
<ul id="menu-main-menu-1" className="main-menu">
|
||||
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10508${dmHeaderActive("home")}`}>
|
||||
<Link href="/" onClick={closeAll}>Home</Link>
|
||||
<Link href="/#home" onClick={(event) => handleNavClick(event, "/", "home", true)}>Home</Link>
|
||||
</li>
|
||||
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("how-it-works")}`}>
|
||||
<Link href="/how-it-works" onClick={closeAll}>How It Works</Link>
|
||||
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10509${dmHeaderActive("doormile-wings")}`}>
|
||||
<Link href="/doormile-wings" prefetch onClick={closeMobileMenu}>Wings</Link>
|
||||
</li>
|
||||
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10510${dmHeaderActive("miletruth")}`}>
|
||||
<Link href="/miletruth" onClick={closeAll}>MileTruth™ AI</Link>
|
||||
<Link href="/miletruth#miletruth" onClick={(event) => handleNavClick(event, "/miletruth", "miletruth", true)}>MileTruth™ AI</Link>
|
||||
</li>
|
||||
<li className={`menu-item menu-item-type-custom menu-item-10511${dmHeaderActive("solutions")}`}>
|
||||
<Link href="/solutions" onClick={closeAll}>Solutions</Link>
|
||||
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10511${dmHeaderActive("solutions")}`}>
|
||||
<Link href="/solutions" prefetch onClick={closeMobileMenu}>Solutions</Link>
|
||||
</li>
|
||||
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-10512${dmHeaderActive("about")}`}>
|
||||
<Link href="/about-us" onClick={closeAll}>About</Link>
|
||||
<li className={`menu-item menu-item-type-custom menu-item-object-custom menu-item-10513${dmHeaderActive("entarpreneurship")}`}>
|
||||
<Link href="/empowerment" prefetch onClick={closeMobileMenu}>Entrepreneurship</Link>
|
||||
</li>
|
||||
<li className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-10535${dmHeaderActive("blogs")}`}>
|
||||
<Link href="/blog" onClick={closeAll}>Blogs</Link>
|
||||
<li
|
||||
className={`menu-item menu-item-type-custom menu-item-10535 dm-mobile-solutions${dmHeaderActive("company")}${isMobileCompanyOpen ? " dm-accordion-open" : ""}`}
|
||||
>
|
||||
<div className="dm-mobile-solutions-row">
|
||||
<a
|
||||
href="#"
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
setMobileCompanyOpen((open) => !open);
|
||||
}}
|
||||
>
|
||||
Company
|
||||
</a>
|
||||
<button
|
||||
type="button"
|
||||
className="dm-mobile-solutions-toggle"
|
||||
aria-label={isMobileCompanyOpen ? "Close Company menu" : "Open Company menu"}
|
||||
aria-haspopup="true"
|
||||
aria-expanded={isMobileCompanyOpen}
|
||||
onClick={() => setMobileCompanyOpen((open) => !open)}
|
||||
>
|
||||
<span className="dm-accordion-chevron" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<ul className="dm-mobile-solutions-panel">
|
||||
<li className={currentPage === "about" ? "dm-child-active" : ""}>
|
||||
<Link href="/about-us#about" onClick={(event) => handleNavClick(event, "/about-us", "about", true)}>About</Link>
|
||||
</li>
|
||||
<li className={currentPage === "blogs" ? "dm-child-active" : ""}>
|
||||
<Link href="/blog#blogs" onClick={(event) => handleNavClick(event, "/blog", "blogs", true)}>Blogs</Link>
|
||||
</li>
|
||||
<li className={currentPage === "how-it-works" ? "dm-child-active" : ""}>
|
||||
<Link href="/how-it-works#how-it-works" onClick={(event) => handleNavClick(event, "/how-it-works", "how-it-works", true)}>How It Works</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -747,6 +893,9 @@ export default function Header() {
|
||||
|
||||
/* Responsive logo adjustment on mobile/tablet */
|
||||
@media (max-width: 1024px) {
|
||||
#masthead .elementor-element.elementor-element-466de1b {
|
||||
top: 18px !important;
|
||||
}
|
||||
#masthead .elementor-element.elementor-element-846e53d .hfe-site-logo .hfe-site-logo-container img {
|
||||
width: 150px !important;
|
||||
height: auto !important;
|
||||
@@ -765,16 +914,22 @@ export default function Header() {
|
||||
to the top once scrolled past 50px, matching desktop behaviour. */
|
||||
#masthead .elementor-element.elementor-element-466de1b.dm-header-scrolled {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
top: 18px !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
}
|
||||
|
||||
#masthead .elementor-element.elementor-element-e052838 {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 0px !important;
|
||||
border-radius: 16px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
#masthead .elementor-element.elementor-element-846e53d .hfe-site-logo .hfe-site-logo-container img {
|
||||
width: 130px !important;
|
||||
margin-left: 10px !important;
|
||||
width: 150px !important;
|
||||
margin-left: 8px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,6 +973,281 @@ export default function Header() {
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cline x1='5' y1='5' x2='19' y2='19'/%3E%3Cline x1='19' y1='5' x2='5' y2='19'/%3E%3C/svg%3E");
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cline x1='5' y1='5' x2='19' y2='19'/%3E%3Cline x1='19' y1='5' x2='5' y2='19'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ── Company dropdown (desktop) / accordion (mobile) ──
|
||||
Company (Blogs + How It Works) is a non-navigating parent —
|
||||
its trigger is a plain anchor with no href target, only a
|
||||
dropdown toggle. Class names below (.dm-solutions-dropdown,
|
||||
.dm-mobile-solutions*) are unchanged from when this same
|
||||
component/markup belonged to Solutions, reusing site.css's dead
|
||||
.menu-item-has-children chevron (fontello glyph, already
|
||||
coloured white for this exact header widget) instead of
|
||||
inventing a new arrow. Desktop opens on hover/focus; mobile is a
|
||||
height-collapsing accordion controlled by the chevron button. */
|
||||
@media (min-width: 1025px) {
|
||||
#masthead .header-menu-container nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
gap: 16px !important;
|
||||
margin: 0 !important;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li > a {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
min-height: 48px;
|
||||
line-height: 1.2 !important;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
min-width: 360px;
|
||||
height: 24px;
|
||||
transform: translateX(-50%);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 34px);
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
margin: 0;
|
||||
padding: 12px;
|
||||
list-style: none;
|
||||
background: linear-gradient(180deg, rgba(31, 31, 31, 0.98) 0%, rgba(18, 18, 18, 0.98) 100%);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
backdrop-filter: blur(20px);
|
||||
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
border: 1px solid rgba(255, 255, 255, 0.09);
|
||||
border-radius: 18px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
/* .main-menu li:not(:last-of-type) (site.css) is a descendant
|
||||
selector that also matches these nested <li>s, pushing every
|
||||
row but the last 12px to the right. Cancel it here. */
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li + li {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li > a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 10px;
|
||||
height: 48px;
|
||||
padding: 0 16px;
|
||||
border-radius: 10px;
|
||||
/* Hardcoded rather than var(--logico-dark-text-color): that
|
||||
variable is only overridden to white inside a few unrelated
|
||||
scoped contexts (e.g. #side-panel-2f31137) and otherwise
|
||||
falls back to the sitewide light-theme value (#111111),
|
||||
which would be invisible on this dark glass panel. */
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-family: var(--font-manrope), "Manrope", sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
letter-spacing: normal;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.25s ease, color 0.25s ease, padding-left 0.25s ease;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li > a:before {
|
||||
content: "";
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
margin-left: -16px;
|
||||
flex: 0 0 11px;
|
||||
background-color: #c01227;
|
||||
opacity: 0;
|
||||
transform: translateX(-10px);
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12 12 4'/%3E%3Cpath d='M5 4h7v7'/%3E%3C/svg%3E");
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12 12 4'/%3E%3Cpath d='M5 4h7v7'/%3E%3C/svg%3E");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
transition: opacity 0.25s ease-in-out, transform 0.25s ease-in-out, background-color 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li > a:hover,
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li > a:focus-visible {
|
||||
background-color: rgba(255, 255, 255, 0.08);
|
||||
color: #ffffff;
|
||||
padding-left: 22px;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li > a:hover:before,
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li > a:focus-visible:before {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
background-color: #c01227;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children .dm-solutions-dropdown li.dm-child-active > a {
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children > a[aria-expanded="true"] ~ .dm-solutions-dropdown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
transform: translate(-50%, 24px);
|
||||
}
|
||||
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children > a[aria-expanded="true"]:after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* Outlines are globally suppressed for .main-menu>li>a above;
|
||||
restore a visible focus ring scoped only to this trigger. */
|
||||
#masthead .header-menu-container .main-menu > li.menu-item-has-children > a:focus-visible {
|
||||
outline: 2px solid var(--logico-dark-text-color, #ffffff);
|
||||
outline-offset: 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-row {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-row > a {
|
||||
display: block;
|
||||
flex: 1 1 auto;
|
||||
padding: 0.75em 0;
|
||||
color: var(--logico-default-text-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
flex: 0 0 44px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--logico-default-text-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-toggle:focus-visible {
|
||||
outline: 2px solid currentColor;
|
||||
outline-offset: 2px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-accordion-chevron {
|
||||
display: inline-block;
|
||||
width: 0.7em;
|
||||
height: 0.7em;
|
||||
flex: 0 0 auto;
|
||||
background-color: currentColor;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
-webkit-mask-position: center;
|
||||
mask-position: center;
|
||||
-webkit-mask-size: contain;
|
||||
mask-size: contain;
|
||||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions.dm-accordion-open .dm-accordion-chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-panel {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-left: 18px;
|
||||
transition: max-height 0.3s ease;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions.dm-accordion-open .dm-mobile-solutions-panel {
|
||||
max-height: 160px;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-panel > li {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* .mobile-header-menu-container ul.main-menu>li>a (site.css) only
|
||||
matches direct children of .main-menu, so these nested links
|
||||
fall through to the sitewide generic underlined-anchor default.
|
||||
Restore the plain sibling-item look explicitly. */
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-panel > li > a {
|
||||
display: block;
|
||||
padding: 0.35em 0;
|
||||
color: var(--logico-default-text-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* A vendor li:before rule (checkmark bullet, likely intended for a
|
||||
feature-list style elsewhere) leaks through here since the reset
|
||||
at .mobile-header-menu-container ul.main-menu>li:before only
|
||||
matches direct children of .main-menu, not this nested li.
|
||||
Suppress it on both the <li> and <a> — these child rows aren't
|
||||
top-level nav items and shouldn't carry any bullet/indicator. */
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-panel > li:before,
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-panel > li > a:before {
|
||||
content: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#masthead .mobile-header-menu-container .dm-mobile-solutions-panel > li.dm-child-active > a {
|
||||
color: var(--logico-light-text-color);
|
||||
text-decoration: underline;
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,69 +1,170 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useEffect, useRef, useState, type MutableRefObject } from "react";
|
||||
import Image from "next/image";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
/**
|
||||
* LoadingScreen
|
||||
* ---------------------------------------------------------------------------
|
||||
* Native reimplementation of the legacy WordPress page-loader: a black
|
||||
* full-screen overlay with a centered, pulsing Doormile logo that fades out.
|
||||
* Route-transition loader only: a black full-screen overlay with a centered,
|
||||
* pulsing Doormile logo. It intentionally does not run on initial page render,
|
||||
* image loading, lazy component loading, API requests, or scroll.
|
||||
*
|
||||
* Shows on initial load (until the window finishes loading, min ~450ms to avoid
|
||||
* a flash, capped at 2.5s so it never blocks) and again briefly on each route
|
||||
* navigation. CWV-safe: fixed/out-of-flow (no layout shift), logo is priority,
|
||||
* and it never delays hydration.
|
||||
* The App Router does not expose the old `next/router` routeChangeStart /
|
||||
* routeChangeComplete event API. This component provides the same behavior by
|
||||
* detecting internal route-link starts and completing when `usePathname()`
|
||||
* reports the committed route.
|
||||
*/
|
||||
type Phase = "visible" | "hiding" | "gone";
|
||||
type Phase = "hidden" | "visible" | "hiding";
|
||||
|
||||
const MIN_SHOW_MS = 450;
|
||||
const MAX_SHOW_MS = 2500;
|
||||
const NAV_SHOW_MS = 520;
|
||||
const MIN_VISIBLE_MS = 420;
|
||||
const MAX_VISIBLE_MS = 800;
|
||||
|
||||
function getRoutePath(url: URL) {
|
||||
return `${url.pathname}${url.search}`;
|
||||
}
|
||||
|
||||
export default function LoadingScreen() {
|
||||
const pathname = usePathname();
|
||||
const [phase, setPhase] = useState<Phase>("visible");
|
||||
const isFirstRender = useRef(true);
|
||||
const [phase, setPhase] = useState<Phase>("hidden");
|
||||
const phaseRef = useRef<Phase>("hidden");
|
||||
const visibleSince = useRef(0);
|
||||
const pendingPath = useRef<string | null>(null);
|
||||
const currentRoutePath = useRef<string | null>(null);
|
||||
const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
const safetyTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
const setLoaderPhase = (nextPhase: Phase) => {
|
||||
phaseRef.current = nextPhase;
|
||||
setPhase(nextPhase);
|
||||
};
|
||||
|
||||
const clearTimer = (timer: MutableRefObject<ReturnType<typeof setTimeout> | null>) => {
|
||||
if (!timer.current) return;
|
||||
clearTimeout(timer.current);
|
||||
timer.current = null;
|
||||
};
|
||||
|
||||
const completeTransition = () => {
|
||||
pendingPath.current = null;
|
||||
clearTimer(safetyTimer);
|
||||
|
||||
if (phaseRef.current === "hidden" || phaseRef.current === "hiding") return;
|
||||
|
||||
const elapsed = performance.now() - visibleSince.current;
|
||||
const wait = Math.max(0, MIN_VISIBLE_MS - elapsed);
|
||||
clearTimer(hideTimer);
|
||||
hideTimer.current = setTimeout(() => {
|
||||
setLoaderPhase("hiding");
|
||||
hideTimer.current = setTimeout(() => setLoaderPhase("hidden"), 360);
|
||||
}, wait);
|
||||
};
|
||||
|
||||
// Initial load: hide once the page is ready.
|
||||
useEffect(() => {
|
||||
const start = performance.now();
|
||||
let began = false;
|
||||
let fadeTimer: ReturnType<typeof setTimeout>;
|
||||
|
||||
const begin = () => {
|
||||
if (began) return;
|
||||
began = true;
|
||||
const wait = Math.max(0, MIN_SHOW_MS - (performance.now() - start));
|
||||
fadeTimer = setTimeout(() => setPhase("hiding"), wait);
|
||||
};
|
||||
|
||||
const cap = setTimeout(begin, MAX_SHOW_MS);
|
||||
const onReady = () => begin();
|
||||
|
||||
if (document.readyState === "complete") begin();
|
||||
else window.addEventListener("load", onReady, { once: true });
|
||||
|
||||
return () => {
|
||||
clearTimeout(cap);
|
||||
clearTimeout(fadeTimer);
|
||||
window.removeEventListener("load", onReady);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Route navigations: flash the loader briefly for an app-like transition.
|
||||
useEffect(() => {
|
||||
if (isFirstRender.current) {
|
||||
isFirstRender.current = false;
|
||||
return;
|
||||
}
|
||||
setPhase("visible");
|
||||
const t = setTimeout(() => setPhase("hiding"), NAV_SHOW_MS);
|
||||
return () => clearTimeout(t);
|
||||
currentRoutePath.current = `${pathname}${window.location.search}`;
|
||||
completeTransition();
|
||||
// `phase` intentionally stays out of this dependency list. The route commit
|
||||
// is the completion signal; phase changes should not repeatedly restart hide.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [pathname]);
|
||||
|
||||
if (phase === "gone") return null;
|
||||
useEffect(() => {
|
||||
const startTransition = (targetPath: string, force = false) => {
|
||||
if (!force && targetPath === getRoutePath(new URL(window.location.href))) return;
|
||||
if (pendingPath.current === targetPath && phaseRef.current === "visible") return;
|
||||
|
||||
pendingPath.current = targetPath;
|
||||
clearTimer(hideTimer);
|
||||
clearTimer(safetyTimer);
|
||||
|
||||
visibleSince.current = performance.now();
|
||||
setLoaderPhase("visible");
|
||||
|
||||
safetyTimer.current = setTimeout(() => {
|
||||
completeTransition();
|
||||
}, MAX_VISIBLE_MS);
|
||||
};
|
||||
|
||||
const getInternalRouteTarget = (anchor: HTMLAnchorElement) => {
|
||||
const rawHref = anchor.getAttribute("href");
|
||||
if (!rawHref || rawHref.startsWith("#")) return null;
|
||||
if (anchor.target && anchor.target !== "_self") return null;
|
||||
if (anchor.hasAttribute("download")) return null;
|
||||
if (/^(mailto:|tel:|sms:|javascript:)/i.test(rawHref)) return null;
|
||||
|
||||
const url = new URL(rawHref, window.location.href);
|
||||
if (url.origin !== window.location.origin) return null;
|
||||
|
||||
const current = new URL(window.location.href);
|
||||
const sameRoute = url.pathname === current.pathname && url.search === current.search;
|
||||
if (sameRoute) return null;
|
||||
|
||||
return getRoutePath(url);
|
||||
};
|
||||
|
||||
const handleDocumentClick = (event: MouseEvent) => {
|
||||
if (event.defaultPrevented) return;
|
||||
if (event.button !== 0) return;
|
||||
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
||||
|
||||
const anchor = (event.target as Element | null)?.closest("a[href]");
|
||||
if (!anchor || !(anchor instanceof HTMLAnchorElement)) return;
|
||||
|
||||
const targetPath = getInternalRouteTarget(anchor);
|
||||
if (targetPath) startTransition(targetPath);
|
||||
};
|
||||
|
||||
const originalPushState = window.history.pushState;
|
||||
const originalReplaceState = window.history.replaceState;
|
||||
|
||||
const scheduleHistoryTransition = (targetPath: string) => {
|
||||
const currentPath = getRoutePath(new URL(window.location.href));
|
||||
if (targetPath === currentPath) return;
|
||||
|
||||
window.setTimeout(() => {
|
||||
startTransition(targetPath, true);
|
||||
}, 0);
|
||||
};
|
||||
|
||||
window.history.pushState = function patchedPushState(...args) {
|
||||
const urlArg = args[2];
|
||||
if (typeof urlArg === "string" || urlArg instanceof URL) {
|
||||
const url = new URL(urlArg, window.location.href);
|
||||
if (url.origin === window.location.origin) scheduleHistoryTransition(getRoutePath(url));
|
||||
}
|
||||
return originalPushState.apply(this, args);
|
||||
};
|
||||
|
||||
window.history.replaceState = function patchedReplaceState(...args) {
|
||||
const urlArg = args[2];
|
||||
if (typeof urlArg === "string" || urlArg instanceof URL) {
|
||||
const url = new URL(urlArg, window.location.href);
|
||||
if (url.origin === window.location.origin) scheduleHistoryTransition(getRoutePath(url));
|
||||
}
|
||||
return originalReplaceState.apply(this, args);
|
||||
};
|
||||
|
||||
const handlePopState = () => {
|
||||
const targetPath = getRoutePath(new URL(window.location.href));
|
||||
if (targetPath !== currentRoutePath.current) startTransition(targetPath, true);
|
||||
};
|
||||
|
||||
document.addEventListener("click", handleDocumentClick, true);
|
||||
window.addEventListener("popstate", handlePopState);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener("click", handleDocumentClick, true);
|
||||
window.removeEventListener("popstate", handlePopState);
|
||||
window.history.pushState = originalPushState;
|
||||
window.history.replaceState = originalReplaceState;
|
||||
clearTimer(hideTimer);
|
||||
clearTimer(safetyTimer);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
if (phase === "hidden") return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -72,7 +173,10 @@ export default function LoadingScreen() {
|
||||
aria-live="polite"
|
||||
aria-label="Loading"
|
||||
onTransitionEnd={(e) => {
|
||||
if (e.propertyName === "opacity" && phase === "hiding") setPhase("gone");
|
||||
if (e.propertyName === "opacity" && phase === "hiding") {
|
||||
setPhase("hidden");
|
||||
phaseRef.current = "hidden";
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="dm-loader__pulse">
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* ContactMapEmbed
|
||||
* ---------------------------------------------------------------------------
|
||||
* Client boundary that lazy-loads the Leaflet map. `ssr: false` keeps Leaflet
|
||||
* out of the server bundle and off the critical render path; the skeleton fills
|
||||
* the host container's fixed height so there is zero layout shift (CLS) while
|
||||
* the map chunk loads.
|
||||
* out of the server bundle and off the critical render path. The host container
|
||||
* already owns the fixed height, so the loading state stays invisible before
|
||||
* the interactive map is ready.
|
||||
*/
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
@@ -14,7 +14,7 @@ import styles from "./OfficeMap.module.css";
|
||||
|
||||
const OfficeMap = dynamic(() => import("./OfficeMap"), {
|
||||
ssr: false,
|
||||
loading: () => <div className={styles.skeleton} role="presentation" aria-hidden="true" />,
|
||||
loading: () => <div className={styles.mapMountReserve} role="presentation" aria-hidden="true" />,
|
||||
});
|
||||
|
||||
export default function ContactMapEmbed() {
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
/* ===========================================================================
|
||||
Office satellite map — scoped styles.
|
||||
All Leaflet global classes are namespaced under `.root` via :global() so this
|
||||
module cannot leak into the rest of the app and vice-versa.
|
||||
Colours/radii reference the app's theme (dark surface, #C01227 brand red).
|
||||
The map fills its container 100% — no hard-coded layout values live here.
|
||||
=========================================================================== */
|
||||
|
||||
.root {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* inherit the host container's rounded corners so tiles/controls clip cleanly */
|
||||
border-radius: inherit;
|
||||
overflow: hidden;
|
||||
background: #0b0b0b;
|
||||
@@ -34,10 +29,6 @@
|
||||
.controls {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
/* Span the full width (with side insets) instead of left:50%+auto-width:
|
||||
an absolutely-positioned auto-width box anchored at left:50% can only grow
|
||||
to 50% of the map, which on a narrow phone forced the city buttons to stack
|
||||
vertically. With left/right insets the row uses the full width and centres. */
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
z-index: 600; /* above tiles + markers; popups open lower so they never collide */
|
||||
@@ -47,6 +38,7 @@
|
||||
gap: 8px;
|
||||
pointer-events: none; /* let the row be transparent to drags; buttons re-enable */
|
||||
}
|
||||
|
||||
.controlBtn {
|
||||
pointer-events: auto;
|
||||
appearance: none;
|
||||
@@ -68,15 +60,18 @@
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease,
|
||||
transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.controlBtn:hover {
|
||||
background: rgba(192, 18, 39, 0.9);
|
||||
border-color: #c01227;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.controlBtn:focus-visible {
|
||||
outline: 2px solid #ffffff;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.controlBtnActive,
|
||||
.controlBtnActive:hover {
|
||||
background: #c01227;
|
||||
@@ -90,6 +85,7 @@
|
||||
border-color: rgba(192, 18, 39, 0.55);
|
||||
box-shadow: 0 0 0 1px rgba(192, 18, 39, 0.25), 0 4px 14px rgba(192, 18, 39, 0.2);
|
||||
}
|
||||
|
||||
.controlBtnHq.controlBtnActive {
|
||||
box-shadow: 0 6px 20px rgba(192, 18, 39, 0.55);
|
||||
}
|
||||
@@ -98,8 +94,6 @@
|
||||
.controls {
|
||||
top: 12px;
|
||||
gap: 5px;
|
||||
/* Keep all three city buttons on a single line — shrink them (below) so the
|
||||
row fits instead of wrapping to two lines on narrow phones. */
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.controlBtn {
|
||||
@@ -110,12 +104,12 @@
|
||||
|
||||
/* ---- Branded marker pin ---- */
|
||||
.markerIcon {
|
||||
/* divIcon resets — keep only the pin's own drop shadow */
|
||||
background: transparent;
|
||||
border: 0;
|
||||
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.55));
|
||||
transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.markerIcon:hover,
|
||||
.markerIcon:focus-visible {
|
||||
transform: translateY(-3px) scale(1.06);
|
||||
@@ -125,15 +119,16 @@
|
||||
.markerIconHq {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
/* red glow + grounding shadow */
|
||||
filter: drop-shadow(0 0 9px rgba(192, 18, 39, 0.85))
|
||||
drop-shadow(0 5px 7px rgba(0, 0, 0, 0.55));
|
||||
transition: transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
.markerIconHq svg {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.markerIconHq:hover,
|
||||
.markerIconHq:focus-visible {
|
||||
transform: translateY(-3px) scale(1.05);
|
||||
@@ -153,6 +148,7 @@
|
||||
pointer-events: none;
|
||||
animation: hqPulse 2.2s ease-out infinite;
|
||||
}
|
||||
|
||||
@keyframes hqPulse {
|
||||
0% {
|
||||
transform: scale(0.6);
|
||||
@@ -168,26 +164,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Themed Leaflet internals (scoped to this map only) ---- */
|
||||
/* ---- Leaflet Branded Elements ---- */
|
||||
.root :global(.leaflet-container) {
|
||||
background: #0b0b0b;
|
||||
}
|
||||
|
||||
/* Zoom + attribution controls — dark, on-theme */
|
||||
.root :global(.leaflet-bar) {
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.root :global(.leaflet-bar a) {
|
||||
background: rgba(15, 15, 17, 0.92);
|
||||
color: #f5f5f5;
|
||||
border-bottom-color: rgba(255, 255, 255, 0.12);
|
||||
transition: background-color 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
.root :global(.leaflet-bar a:hover) {
|
||||
background: #c01227;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.root :global(.leaflet-bar a:focus-visible) {
|
||||
outline: 2px solid #c01227;
|
||||
outline-offset: 2px;
|
||||
@@ -202,72 +200,129 @@
|
||||
border-radius: 6px 0 0 0;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
.root :global(.leaflet-control-attribution a) {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
/* Popup — dark card matching the app surfaces */
|
||||
.root :global(.leaflet-popup-content-wrapper) {
|
||||
background: #141416;
|
||||
color: #ffffff;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
.root :global(.leaflet-popup-content-wrapper) {
|
||||
border-radius: 10px;
|
||||
}
|
||||
.root :global(.leaflet-popup-content) {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.root :global(.leaflet-popup-tip) {
|
||||
background: #141416;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
/* ---- Floating Popup overlays ---- */
|
||||
.root :global(.leaflet-popup) {
|
||||
animation: popupFade 0.2s ease-out forwards;
|
||||
}
|
||||
|
||||
/* ---- Compact, Google-Maps-style tooltip content ---- */
|
||||
.tip {
|
||||
.root :global(.leaflet-popup-content-wrapper) {
|
||||
background: #0f0f11;
|
||||
color: #ffffff;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 8px; /* Clean business card rounded corners */
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
animation: popupScale 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
transform-origin: bottom center;
|
||||
}
|
||||
|
||||
.root :global(.leaflet-popup-content) {
|
||||
margin: 0 !important;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.root :global(.leaflet-popup-tip) {
|
||||
background: #0f0f11;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
@keyframes popupFade {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes popupScale {
|
||||
from { transform: scale(0.92); }
|
||||
to { transform: scale(1); }
|
||||
}
|
||||
|
||||
/* Compact Details Card inside Popup */
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
padding: 8px 12px;
|
||||
min-width: 120px;
|
||||
max-width: 200px;
|
||||
text-align: left;
|
||||
padding: 12px 16px;
|
||||
min-width: 230px;
|
||||
max-width: 280px;
|
||||
box-sizing: border-box;
|
||||
font-family: var(--font-manrope), system-ui, -apple-system, sans-serif;
|
||||
}
|
||||
.tipTitle {
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.01em;
|
||||
color: #ffffff;
|
||||
white-space: nowrap;
|
||||
border-top: 2px solid #c01227; /* Thinner brand accent line */
|
||||
background: #0f0f11;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* ---- Loading skeleton (prevents CLS — fills the fixed-height host) ---- */
|
||||
.skeleton {
|
||||
.cardHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.cardIcon {
|
||||
font-size: 15px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 17px !important;
|
||||
font-weight: 800 !important;
|
||||
color: #ffffff !important; /* Force white header text */
|
||||
margin: 0 !important;
|
||||
letter-spacing: -0.01em !important;
|
||||
}
|
||||
|
||||
.cardBody {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.addressLine {
|
||||
font-size: 14px !important;
|
||||
line-height: 1.5 !important;
|
||||
color: rgba(255, 255, 255, 0.75) !important;
|
||||
margin: 0 0 6px 0 !important;
|
||||
padding: 0 !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.addressLine:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.card {
|
||||
padding: 9px 12px;
|
||||
min-width: 200px;
|
||||
max-width: 230px;
|
||||
}
|
||||
.cardTitle {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.addressLine {
|
||||
font-size: 12px !important;
|
||||
margin-bottom: 3px !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Invisible lazy mount reserve ---- */
|
||||
.mapMountReserve {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
background:
|
||||
linear-gradient(
|
||||
100deg,
|
||||
rgba(255, 255, 255, 0) 30%,
|
||||
rgba(255, 255, 255, 0.05) 50%,
|
||||
rgba(255, 255, 255, 0) 70%
|
||||
),
|
||||
#101012;
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.4s ease-in-out infinite;
|
||||
}
|
||||
@keyframes shimmer {
|
||||
from { background-position: 200% 0; }
|
||||
to { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.skeleton { animation: none; }
|
||||
.markerIcon,
|
||||
.markerIconHq { transition: none; }
|
||||
.pinPulse { animation: none; opacity: 0.45; }
|
||||
@@ -289,12 +344,14 @@
|
||||
color: rgba(255, 255, 255, 0.82);
|
||||
font-family: var(--font-manrope), system-ui, sans-serif;
|
||||
}
|
||||
|
||||
.errorTitle {
|
||||
font-size: clamp(15px, 2.4vw, 18px);
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.errorText {
|
||||
font-size: 13px;
|
||||
max-width: 38ch;
|
||||
@@ -302,6 +359,7 @@
|
||||
line-height: 1.55;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.errorList {
|
||||
list-style: none;
|
||||
margin: 4px 0 0;
|
||||
@@ -311,6 +369,7 @@
|
||||
gap: 8px 12px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.errorList li {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -319,6 +378,7 @@
|
||||
font-weight: 700;
|
||||
color: #f1f1f1;
|
||||
}
|
||||
|
||||
.errorList li::before {
|
||||
content: "";
|
||||
width: 7px;
|
||||
@@ -327,7 +387,7 @@
|
||||
background: #c01227;
|
||||
}
|
||||
|
||||
/* ---- Screen-reader-only office list (semantic fallback) ---- */
|
||||
/* ---- Screen-reader-only office list ---- */
|
||||
.srOnly {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
|
||||
@@ -7,14 +7,9 @@
|
||||
* Doormile office markers, plus a row of "jump to office" buttons that fly the
|
||||
* map to a selected office's coordinates and open its popup.
|
||||
*
|
||||
* The experience opens focused on the Hyderabad headquarters — the largest,
|
||||
* glowing, pulsing marker — with its popup open by default, so the command
|
||||
* centre of the network is immediately legible. Hovering any marker opens its
|
||||
* popup; leaving closes it. Clicking a marker or a nav button flies to it.
|
||||
*
|
||||
* Loaded via a `ssr:false` dynamic import so Leaflet (which touches `window`)
|
||||
* never runs on the server and cannot cause hydration mismatches. Layout/spacing
|
||||
* is owned by the host container (see ContactMap).
|
||||
* The map centers with a North latitude offset to keep markers lower in the viewport,
|
||||
* avoiding collisions with the navigation tabs. Popups are compact and styled like
|
||||
* clean business cards.
|
||||
*/
|
||||
|
||||
import "leaflet/dist/leaflet.css";
|
||||
@@ -25,6 +20,7 @@ import L from "leaflet";
|
||||
import { MapContainer, Marker, Popup, TileLayer, ZoomControl, useMap } from "react-leaflet";
|
||||
|
||||
import {
|
||||
LatLng,
|
||||
ESRI_WORLD_IMAGERY,
|
||||
HQ_OFFICE,
|
||||
MAP_FOCUS_ZOOM,
|
||||
@@ -41,7 +37,6 @@ type FocusTarget = { id: string; nonce: number };
|
||||
/**
|
||||
* Build a branded SVG pin. The headquarters pin is larger, carries a red glow
|
||||
* and a soft pulse ring, and sits above every other marker.
|
||||
* (Module-scope-safe construction — this file is client-only.)
|
||||
*/
|
||||
function createMarkerIcon(isHeadquarters: boolean): L.DivIcon {
|
||||
if (isHeadquarters) {
|
||||
@@ -57,7 +52,7 @@ function createMarkerIcon(isHeadquarters: boolean): L.DivIcon {
|
||||
`,
|
||||
iconSize: [40, 52],
|
||||
iconAnchor: [20, 52],
|
||||
popupAnchor: [0, -46],
|
||||
popupAnchor: [0, -52], // Anchored to top tip of pin
|
||||
});
|
||||
}
|
||||
|
||||
@@ -72,15 +67,14 @@ function createMarkerIcon(isHeadquarters: boolean): L.DivIcon {
|
||||
`,
|
||||
iconSize: [30, 40],
|
||||
iconAnchor: [15, 40],
|
||||
popupAnchor: [0, -36],
|
||||
popupAnchor: [0, -40], // Anchored to top tip of pin
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Imperative map effects that need the Leaflet instance:
|
||||
* - keep the viewport sized correctly across resizes / lazy reveals
|
||||
* - on first paint, snap to the HQ and open its popup (no jarring long fly)
|
||||
* - fly to a single office when one is selected via the buttons
|
||||
* - snap to the offset HQ on first paint, fly thereafter and open popups.
|
||||
*/
|
||||
function MapController({
|
||||
focus,
|
||||
@@ -92,8 +86,7 @@ function MapController({
|
||||
const map = useMap();
|
||||
const didInit = useRef(false);
|
||||
|
||||
// Keep the map correctly sized on container resize / lazy reveal. We never
|
||||
// re-frame the view here, so resizing keeps whatever office is in focus.
|
||||
// Keep the map correctly sized on container resize / lazy reveal.
|
||||
useEffect(() => {
|
||||
const container = map.getContainer();
|
||||
let raf = 0;
|
||||
@@ -116,16 +109,20 @@ function MapController({
|
||||
|
||||
const openPopup = () => markerRefs.current[office.id]?.openPopup();
|
||||
|
||||
// Offset the center slightly North so the marker sits lower in the viewport,
|
||||
// preventing the popup card from colliding with the top controls.
|
||||
const offsetLatitude = 0.022;
|
||||
const centeredPosition: LatLng = [office.position[0] + offsetLatitude, office.position[1]];
|
||||
|
||||
if (!didInit.current) {
|
||||
didInit.current = true;
|
||||
map.invalidateSize();
|
||||
map.setView(office.position, MAP_FOCUS_ZOOM, { animate: false });
|
||||
// Open the HQ popup once the marker has mounted on this frame.
|
||||
map.setView(centeredPosition, MAP_FOCUS_ZOOM, { animate: false });
|
||||
const raf = requestAnimationFrame(openPopup);
|
||||
return () => cancelAnimationFrame(raf);
|
||||
}
|
||||
|
||||
map.flyTo(office.position, MAP_FOCUS_ZOOM, { duration: 1.1 });
|
||||
map.flyTo(centeredPosition, MAP_FOCUS_ZOOM, { duration: 1.1 });
|
||||
map.once("moveend", openPopup);
|
||||
return () => {
|
||||
map.off("moveend", openPopup);
|
||||
@@ -140,12 +137,21 @@ export default function OfficeMap() {
|
||||
const hqIcon = useMemo(() => createMarkerIcon(true), []);
|
||||
const markerRefs = useRef<Record<string, L.Marker>>({});
|
||||
|
||||
// Default to the headquarters so its button reads active and its popup opens.
|
||||
// Default to the headquarters.
|
||||
const [focus, setFocus] = useState<FocusTarget | null>({ id: HQ_OFFICE.id, nonce: 0 });
|
||||
const focusOffice = useCallback((id: string) => {
|
||||
setFocus((prev) => ({ id, nonce: (prev?.nonce ?? 0) + 1 }));
|
||||
}, []);
|
||||
|
||||
const [hoveredOfficeId, setHoveredOfficeId] = useState<string | null>(null);
|
||||
|
||||
// Restore the focused office popup when mouse leaves other markers.
|
||||
useEffect(() => {
|
||||
if (hoveredOfficeId === null && focus?.id) {
|
||||
markerRefs.current[focus.id]?.openPopup();
|
||||
}
|
||||
}, [hoveredOfficeId, focus]);
|
||||
|
||||
const [status, setStatus] = useState<MapStatus>("loading");
|
||||
const loadedRef = useRef(false);
|
||||
const errorCountRef = useRef(0);
|
||||
@@ -155,8 +161,6 @@ export default function OfficeMap() {
|
||||
setStatus("ready");
|
||||
}, []);
|
||||
|
||||
// Only surface an error if tiles never render (network/CORS/down). Once any
|
||||
// tile load succeeds the map is considered healthy and stays that way.
|
||||
const handleTileError = useCallback(() => {
|
||||
errorCountRef.current += 1;
|
||||
if (!loadedRef.current && errorCountRef.current >= 6) setStatus("error");
|
||||
@@ -223,8 +227,9 @@ export default function OfficeMap() {
|
||||
/>
|
||||
|
||||
{OFFICE_LOCATIONS.map((office) => {
|
||||
// Google-Maps-style tooltip: hovering shows just the location name;
|
||||
// clicking focuses the office.
|
||||
const isFocused = focus?.id === office.id;
|
||||
const isHovered = hoveredOfficeId === office.id;
|
||||
|
||||
return (
|
||||
<Marker
|
||||
key={office.id}
|
||||
@@ -236,9 +241,16 @@ export default function OfficeMap() {
|
||||
alt={office.name}
|
||||
eventHandlers={{
|
||||
click: () => focusOffice(office.id),
|
||||
// Hover opens the compact popup without moving the map.
|
||||
mouseover: (event) => event.target.openPopup(),
|
||||
mouseout: (event) => event.target.closePopup(),
|
||||
mouseover: (event) => {
|
||||
setHoveredOfficeId(office.id);
|
||||
event.target.openPopup();
|
||||
},
|
||||
mouseout: (event) => {
|
||||
setHoveredOfficeId(null);
|
||||
if (focus?.id !== office.id) {
|
||||
event.target.closePopup();
|
||||
}
|
||||
},
|
||||
}}
|
||||
ref={(instance) => {
|
||||
if (instance) markerRefs.current[office.id] = instance;
|
||||
@@ -246,16 +258,25 @@ export default function OfficeMap() {
|
||||
>
|
||||
<Popup
|
||||
className={styles.popup}
|
||||
autoPan={false}
|
||||
autoPan={isFocused}
|
||||
autoPanPadding={[25, 25]}
|
||||
closeButton={false}
|
||||
minWidth={120}
|
||||
maxWidth={200}
|
||||
minWidth={240}
|
||||
maxWidth={290}
|
||||
>
|
||||
<span className={styles.tip}>
|
||||
<span className={styles.tipTitle}>
|
||||
<span aria-hidden="true">📍</span> {office.shortLabel}
|
||||
</span>
|
||||
</span>
|
||||
<div className={styles.card}>
|
||||
<div className={styles.cardHeader}>
|
||||
<span className={styles.cardIcon} aria-hidden="true">📍</span>
|
||||
<h4 className={styles.cardTitle}>{office.city} Office</h4>
|
||||
</div>
|
||||
<div className={styles.cardBody}>
|
||||
{office.address.map((line, idx) => (
|
||||
<p key={idx} className={styles.addressLine}>
|
||||
{line}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Popup>
|
||||
</Marker>
|
||||
);
|
||||
|
||||
@@ -25,6 +25,8 @@ export interface OfficeLocation {
|
||||
readonly position: LatLng;
|
||||
/** Headquarters gets the largest, glowing, default-active marker. */
|
||||
readonly isHeadquarters?: boolean;
|
||||
/** Full office address lines. */
|
||||
readonly address: readonly string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,6 +44,12 @@ export const OFFICE_LOCATIONS: readonly OfficeLocation[] = [
|
||||
// Vision Ultima, Jayabheri Enclave, Gachibowli — verified on satellite.
|
||||
position: [17.4484, 78.3573],
|
||||
isHeadquarters: true,
|
||||
address: [
|
||||
"5th Floor, Vision Ultima,",
|
||||
"Street No.3, Jayabheri Enclave,",
|
||||
"Gachibowli, Hyderabad,",
|
||||
"Telangana 500032"
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "bengaluru",
|
||||
@@ -50,6 +58,13 @@ export const OFFICE_LOCATIONS: readonly OfficeLocation[] = [
|
||||
shortLabel: "Bengaluru Hub",
|
||||
// Resolved from the supplied Google Maps share link — verified on satellite.
|
||||
position: [12.9929351, 77.6988599],
|
||||
address: [
|
||||
"C612, 6th Floor,",
|
||||
"Trifecta Starlight, ITPL Road,",
|
||||
"Garudacharapalya, Mahadevapura,",
|
||||
"Bangalore 560048,",
|
||||
"Karnataka, India"
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "coimbatore",
|
||||
@@ -58,6 +73,12 @@ export const OFFICE_LOCATIONS: readonly OfficeLocation[] = [
|
||||
shortLabel: "Coimbatore Hub",
|
||||
// Mayflower Valencia, Coimbatore — verified against satellite view.
|
||||
position: [11.0191, 76.9883],
|
||||
address: [
|
||||
"Mayflower Valencia,",
|
||||
"Near Nava India Bus Stop,",
|
||||
"Avinashi Road, Udayampalayam,",
|
||||
"Tamil Nadu 641003"
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -3,7 +3,31 @@ import Link from "next/link";
|
||||
|
||||
export default function AboutCTA() {
|
||||
return (
|
||||
<div className="we-container">
|
||||
<>
|
||||
<style dangerouslySetInnerHTML={{ __html: `
|
||||
@media (max-width: 768px) {
|
||||
.we-container {
|
||||
margin-top: 40px !important;
|
||||
margin-bottom: 40px !important;
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
.we-cta {
|
||||
padding: 48px 20px !important;
|
||||
border-radius: 22px !important;
|
||||
}
|
||||
.we-cta-title {
|
||||
font-size: clamp(28px, 6vw, 38px) !important;
|
||||
line-height: 1.25 !important;
|
||||
margin-bottom: 16px !important;
|
||||
}
|
||||
.we-cta-sub {
|
||||
font-size: 15px !important;
|
||||
line-height: 1.5 !important;
|
||||
margin-bottom: 24px !important;
|
||||
}
|
||||
}
|
||||
`}} />
|
||||
<div className="we-container">
|
||||
<div className="we-cta reveal">
|
||||
<div className="we-cta-inner">
|
||||
<h2 className="we-cta-title">
|
||||
@@ -26,5 +50,6 @@ export default function AboutCTA() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ import React from "react";
|
||||
export default function AboutHero() {
|
||||
return (
|
||||
<>
|
||||
<link rel="preload" as="image" href="/images/about-bg.webp" />
|
||||
<style dangerouslySetInnerHTML={{ __html: `
|
||||
.about-us-hero-content {
|
||||
width: 100% !important;
|
||||
text-align: center !important;
|
||||
color: #fff !important;
|
||||
padding: 40px !important;
|
||||
padding: 0 15px !important;
|
||||
z-index: 2;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
@@ -33,7 +34,7 @@ export default function AboutHero() {
|
||||
<div className="custom-standard-hero-container">
|
||||
<div
|
||||
style={{
|
||||
backgroundImage: "url('/images/about-bg.png')",
|
||||
backgroundImage: "url('/images/about-bg.webp')",
|
||||
"--hero-overlay": "linear-gradient(to bottom, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.92) 60%, rgba(0, 0, 0, 0.98) 100%)"
|
||||
} as React.CSSProperties}
|
||||
className="custom-standard-hero-card"
|
||||
@@ -48,4 +49,3 @@ export default function AboutHero() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,40 @@ export default function BlogGrid() {
|
||||
}
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.elementor-104 .elementor-element.elementor-element-c70681e {
|
||||
margin-top: var(--space-section) !important;
|
||||
margin-bottom: 16px !important;
|
||||
}
|
||||
.custom-blog-grid {
|
||||
grid-template-columns: 1fr !important;
|
||||
gap: 48px !important;
|
||||
gap: 28px !important;
|
||||
padding: 24px 20px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.elementor-104 .elementor-element.elementor-element-c70681e {
|
||||
--padding-left: 10px !important;
|
||||
--padding-right: 10px !important;
|
||||
padding-left: 10px !important;
|
||||
padding-right: 10px !important;
|
||||
}
|
||||
.elementor-104 .elementor-element.elementor-element-3dec5cf {
|
||||
--padding-left: 0px !important;
|
||||
--padding-right: 0px !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
.elementor-104 .elementor-element.elementor-element-aa12479,
|
||||
.elementor-104 .elementor-element.elementor-element-aa12479 > .elementor-widget-container,
|
||||
.elementor-104 .archive-listing,
|
||||
.elementor-104 .custom-blog-grid {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
.elementor-104 .custom-blog-grid {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +113,7 @@ export default function BlogGrid() {
|
||||
font-family: var(--font-manrope), sans-serif !important;
|
||||
}
|
||||
|
||||
/* Bottom block pinned to the card base — keeps Read More + image at the
|
||||
/* Bottom block pinned to the card base. Keeps Read More + image at the
|
||||
same vertical position across cards with different text lengths. */
|
||||
.custom-blog-bottom {
|
||||
display: flex !important;
|
||||
|
||||
@@ -147,6 +147,12 @@ const STYLES = `
|
||||
padding: clamp(24px, 3vw, 32px) clamp(20px, 4vw, 40px) clamp(8px, 1.5vw, 16px);
|
||||
display: flex; flex-direction: column; gap: clamp(32px, 4vw, 48px);
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.dm-blog-footer-inner {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prev / Next */
|
||||
.dm-prevnext {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function BlogsHero() {
|
||||
return (
|
||||
<>
|
||||
<link rel="preload" as="image" href="/images/home2-banner-1.webp" />
|
||||
<style dangerouslySetInnerHTML={{ __html: `
|
||||
.blogs-hero-title {
|
||||
color: #ffffff !important;
|
||||
@@ -15,18 +15,31 @@ export default function BlogsHero() {
|
||||
letter-spacing: -1.5px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.blogs-hero-content {
|
||||
position: relative !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
flex-direction: column !important;
|
||||
max-width: 1000px !important;
|
||||
margin: 0 auto !important;
|
||||
padding: 0 15px !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
`}} />
|
||||
<div className="custom-standard-hero-container">
|
||||
<div
|
||||
style={{
|
||||
backgroundImage: "url(/images/home2-banner-1.jpg)",
|
||||
backgroundImage: "url(/images/home2-banner-1.webp)",
|
||||
backgroundPosition: "center center",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundSize: "cover"
|
||||
}}
|
||||
className="custom-standard-hero-card"
|
||||
>
|
||||
<div className="e-con-inner" style={{ position: "relative", width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column" }}>
|
||||
<div className="blogs-hero-content">
|
||||
|
||||
{/* Title / Heading for Blogs */}
|
||||
<div style={{ textAlign: "center", color: "#fff", zIndex: 5 }}>
|
||||
@@ -43,4 +56,3 @@ export default function BlogsHero() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -492,7 +492,11 @@ export default function CompetitiveEdge() {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.comparison-section {
|
||||
padding: 80px 0;
|
||||
padding: 56px 0;
|
||||
}
|
||||
|
||||
.comparison-section .container {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.moat-heading {
|
||||
|
||||
@@ -33,6 +33,25 @@ export default function ConnectedLogistics() {
|
||||
max-width: min(526px, 100%) !important;
|
||||
}
|
||||
|
||||
/* Sizing and identical padding on all 4 sides for Connected Logistics Image container */
|
||||
.elementor-element-99768ba .elementor-widget-container {
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
padding: 40px !important; /* Identical gap on left, right, top, and bottom */
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
|
||||
.elementor-element-99768ba img.wp-image-4481 {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important; /* Allow natural responsive scaling on desktop */
|
||||
height: auto !important;
|
||||
object-fit: cover !important;
|
||||
border-radius: 25px !important; /* Preserve 25px border radius */
|
||||
margin: 0 auto !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* Desktop/Laptop (min-width: 1025px) column width and flex rules */
|
||||
@media (min-width: 1025px) {
|
||||
.elementor-element-9ffed33 {
|
||||
@@ -67,9 +86,20 @@ export default function ConnectedLogistics() {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
/* Force ScrollReveal wrapper div to span full width */
|
||||
.elementor-element-96343ba > div {
|
||||
width: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
/* Show image at the bottom or top depending on order */
|
||||
.elementor-element-96343ba {
|
||||
margin-top: 30px !important;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* Reduce padding bottom of the content section on tablet */
|
||||
.elementor-element-71c3e1d {
|
||||
padding-bottom: 24px !important;
|
||||
}
|
||||
|
||||
/* Override desktop fixed widths on mobile/tablet */
|
||||
@@ -78,6 +108,52 @@ export default function ConnectedLogistics() {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
/* Allow widget container to take 100% width on mobile/tablet */
|
||||
.elementor-element-99768ba {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
/* Tablet overrides */
|
||||
.elementor-element-99768ba .elementor-widget-container {
|
||||
padding: 10px !important;
|
||||
display: block !important; /* Disable flex centering layout on mobile/tablet */
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.elementor-element.elementor-element-99768ba .elementor-widget-container img.wp-image-4481 {
|
||||
width: 100% !important;
|
||||
max-width: 600px !important; /* allow up to 600px on tablet */
|
||||
border-radius: 25px !important; /* Explicitly keep 25px */
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
/* Mobile overrides: let container take 100% width and image fill it */
|
||||
.elementor-element-99768ba {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
/* Eliminate extra gap under the content column on mobile */
|
||||
.elementor-element-71c3e1d {
|
||||
padding-bottom: 12px !important;
|
||||
}
|
||||
|
||||
.elementor-element-99768ba .elementor-widget-container {
|
||||
padding: 0px !important; /* Eliminate padding to maximize image width/height */
|
||||
display: block !important; /* Disable flex centering layout on mobile/tablet */
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.elementor-element.elementor-element-99768ba .elementor-widget-container img.wp-image-4481 {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
height: auto !important;
|
||||
object-fit: cover !important;
|
||||
border-radius: 25px !important; /* Explicitly keep 25px */
|
||||
}
|
||||
}
|
||||
`}} />
|
||||
<div className="elementor-element elementor-element-9ffed33 e-con-full e-flex cut-corner-no sticky-container-off e-con e-child" data-id="9ffed33" data-element_type="container" data-e-type="container" data-settings="{"background_background":"classic"}">
|
||||
@@ -92,7 +168,7 @@ export default function ConnectedLogistics() {
|
||||
priority
|
||||
width={578}
|
||||
height={790}
|
||||
src="/images/home2-pic-3.png"
|
||||
src="/images/home2-pic-3.webp"
|
||||
className="attachment-full size-full wp-image-4481"
|
||||
alt="Connected Logistics"
|
||||
style={{
|
||||
|
||||