\n \n );\n};\n\nexport { CjsEvent };\n","import { ICjsEventProp } from \"./CjsEvent\";\n\nconst events: ICjsEventProp[] = [\n {\n eventType: \"none\",\n header: \"CJ Shaughnessy Crane Service is founded.\",\n subHeader: \"\",\n description: \"\",\n date: \"June 2012\",\n },\n {\n eventType: \"crane\",\n header: \"New Crane\",\n subHeader: \"Manitex 35124C Boom Truck Purchased\",\n description:\n \"CJ Shaughnessy purchases its first crane to start servicing the local area\",\n date: \"June 2012\",\n },\n {\n eventType: \"crane\",\n header: \"New Crane\",\n subHeader: \"Liebherr LTM 1060-3.1\",\n description:\n \"With a growing number of projects CJS Crane purchases their first Liebherr crane for use\",\n date: \"April 2015\",\n },\n {\n eventType: \"location\",\n header: \"New Location\",\n subHeader: \"CJ Shaughnessy Crane moves its shop to Braintree\",\n description:\n \"With quick access to the highway and a short commute to Boston we found a great location to grow\",\n date: \"Oct 2015\",\n },\n {\n eventType: \"crane\",\n header: \"New Crane\",\n subHeader: \"Liebherr LTM 1100-4.2\",\n description:\n \"To be able to bid higher tonnage jobs this four axle Liebherr was put into service\",\n date: \"2016\",\n },\n {\n eventType: \"truck\",\n header: \"New Truck\",\n subHeader: \"Peterbilt\",\n description:\n \"CJS Crane starts offering hauling services to help its customers\",\n date: \"2016\",\n },\n {\n eventType: \"location\",\n header: \"New Location\",\n subHeader: \"CJ Shaughnessy moves to Bodwell St Avon\",\n description:\n \"CJS Crane purchases its new shop in Avon MA - the expanded shop allows for warehousing customer products and increases capacity for more equipment \",\n date: \"July 2018\",\n },\n {\n eventType: \"crane\",\n header: \"New Crane\",\n subHeader: \"Liebherr LTM 1450-8.1\",\n description:\n \"CJS expands its fleet and lifting capabilities with this 8 axle, 550 ton crane\",\n date: \"Sept 2019\",\n },\n {\n eventType: \"location\",\n header: \"New Location\",\n subHeader: \"Bodwell Expansion\",\n description:\n \"CJS purchases the property adjacent to its existing Bodwell Street yard, adding 25,000 square feet of state of the art warehouse space and additional office space\",\n date: \"June 2021\",\n },\n {\n eventType: \"crane\",\n header: \"New Crane\",\n subHeader: \"Liebherr LTM 1120-4.1\",\n description: \"CJS puts into service its 9th crane\",\n date: \"July 2021\",\n },\n {\n eventType: \"crane\",\n header: \"New Crane\",\n subHeader: \"Liebherr LTM 1060-3.1\",\n description: \"CJS puts into service its 10th crane\",\n date: \"July 2021\",\n },\n {\n eventType: \"telehandler\",\n header: \"New Telehandler\",\n subHeader: \"Manitou MHT 10180\",\n description:\n \"CJS purchases this 40K telelhandler with 30 feet of reach, complementing its existing fleet of telescopic forklifts, now ranging from 10K to 40K\",\n date: \"Jan 2022\",\n },\n {\n eventType: \"crane\",\n header: \"New Crane\",\n subHeader: \"Liebherr LTM 1650-8.1\",\n description:\n \"CJS purchases its biggest crane to date. The 1650 is now the biggest mobile crane operating in Boston.\",\n date: \"November 2022\",\n },\n];\n\nexport { events };\n","import React from \"react\";\nimport {\n VerticalTimeline,\n VerticalTimelineElement,\n} from \"react-vertical-timeline-component\";\nimport StarIcon from \"@material-ui/icons/Star\";\n\nimport { CjsEvent, ICjsEventProp } from \"./CjsEvent\";\nimport { events } from \"./events\";\n\nimport \"react-vertical-timeline-component/style.min.css\";\nimport \"./CjsTimeline.scss\";\n\nconst CjsTimeline = () => {\n const newEvents = events.slice(0).reverse();\n return (\n
\n \n \n \n \n \n \n {show && }\n \n );\n};\n\nexport { JobSummaryCard };\n","import { useRef } from \"react\";\nimport { useIntersectionObserver } from \"hooks\";\n\nconst addBg = (navBar: HTMLDivElement | null, bgClass: string) => {\n if (navBar === null) {\n return;\n }\n navBar.classList.add(bgClass);\n};\n\nconst removeBg = (navBar: HTMLDivElement | null, bgClass: string) => {\n if (navBar === null) {\n return;\n }\n navBar.classList.remove(bgClass);\n};\n\nconst useDynamicNavbar = () => {\n const navBarEl = useRef(null);\n\n const handleJumboAppearing = () => {\n removeBg(navBarEl.current, \"dark-background\");\n };\n\n const handleJumboDisappearing = () => {\n addBg(navBarEl.current, \"dark-background\");\n };\n\n const handleOnToggle = (expanded: boolean) => {\n if (navBarEl.current === null) {\n return;\n }\n\n if (expanded) {\n addBg(navBarEl.current, \"open-background\");\n return;\n }\n\n removeBg(navBarEl.current, \"open-background\");\n };\n\n useIntersectionObserver(\n \".cjs-jumbotron\",\n handleJumboAppearing,\n handleJumboDisappearing\n );\n\n return { handleOnToggle, navBarEl };\n};\n\nexport { useDynamicNavbar };\n","import { useEffect, useRef } from \"react\";\n\nconst useIntersectionObserver = (\n watchClass: string,\n onAppear: () => void,\n onDisappear: () => void\n) => {\n const watchRef = useRef(null);\n\n useEffect(() => {\n watchRef.current = document.querySelector(watchClass);\n if (watchRef.current === null) {\n return;\n }\n\n const handler: IntersectionObserverCallback = (entries) => {\n if (entries[0].isIntersecting) {\n onAppear();\n } else {\n onDisappear();\n }\n };\n\n const intersectionObserver = new IntersectionObserver(handler, {\n rootMargin: \"-115px 0px 0px 0px\",\n });\n intersectionObserver.observe(watchRef.current);\n\n return () => {\n if (watchRef.current === null) {\n return;\n }\n intersectionObserver.unobserve(watchRef.current);\n };\n }, [watchClass, onAppear, onDisappear]);\n};\n\nexport { useIntersectionObserver };\n","import React from \"react\";\nimport { useEffect } from \"react\";\nimport { NavLink } from \"react-router-dom\";\nimport { useLocation, useHistory } from \"react-router\";\nimport { ImPhone } from \"react-icons/im\";\nimport { Container, Navbar, Nav, Button } from \"react-bootstrap\";\n\nimport { gaTracking } from \"services\";\nimport { Stack, QuoteButton } from \"components\";\n\nimport { useDynamicNavbar } from \"./useDynamicNavbar\";\n\nimport logo from \"images/cjs-logo-trim-small.png\";\n\nimport \"./navbar.scss\";\n\nconst NavBar = () => {\n const location = useLocation();\n const history = useHistory();\n\n useEffect(() => {\n return history.listen(() => {\n gaTracking.pageView();\n });\n }, [history]);\n\n const { navBarEl, handleOnToggle } = useDynamicNavbar();\n\n return (\n \n \n \n \n \n \n \n \n \n {/* */}\n Get A Quote\n \n \n \n \n \n \n \n \n \n \n \n \n );\n};\n\nexport { NavBar };\n","import React from \"react\";\nimport { Helmet } from \"react-helmet\";\n\ntype PageHelmetProps = {\n title: string;\n description: string;\n};\n\nconst PageHelmet = ({ title, description }: PageHelmetProps) => {\n return (\n \n {title}\n \n \n \n \n );\n};\n\nexport { PageHelmet };\n","import { useEffect } from \"react\";\nimport { useLocation } from \"react-router-dom\";\n\nconst ScrollToTop = () => {\n const { pathname } = useLocation();\n\n useEffect(() => {\n window.scrollTo(0, 0);\n }, [pathname]);\n\n return null;\n};\n\nexport { ScrollToTop };\n","import React from \"react\";\nimport { Row, Col } from \"react-bootstrap\";\nimport { ServiceCard, Stack } from \"../../components\";\n\nimport bose from \"../../images/BosePick.jpg\";\nimport hauling from \"../../images/hauling-2.jpg\";\nimport rigging from \"../../images/rigging-1-small.jpg\";\n\nimport \"./ServicesSection.scss\";\n\ninterface ServiceCardInfo {\n title: string;\n description: string;\n photoUrl: string;\n altText: string;\n}\n\nconst services: ServiceCardInfo[] = [\n {\n title: \"HOISTING\",\n description: `We are experts at properly planning your lift, ensuring a\n safe and successful placement of your equipment. We leave\n nothing to chance and carefully plan your lift before it\n takes place.`,\n photoUrl: bose,\n altText: \"CJS Crane Bose Hositing Lift\",\n },\n {\n title: \"RIGGING\",\n description: `At CJS Crane, we are routinely entrusted with moving\n equipment worth several million dollars. Planning and safety\n are our guiding principles. Regardless of how tight the\n surroundings or the opening, we have the right equipment to\n do the job.`,\n photoUrl: rigging,\n altText: \"CJS Crane Rigging\",\n },\n {\n title: \"HAULING\",\n description: `We have years of experience transporting unique, over\n dimensioned loads, and we make sure your equipment arrives\n safely. We only work with the industry's best equipment ensuring that if the job can be done we can do it.`,\n photoUrl: hauling,\n altText: \"CJS Crane Truck Hauling\",\n },\n];\n\nconst ServicesSection = () => {\n return (\n <>\n
\n OUR SERVICES\n
\n
hoisting - rigging - hauling
\n \n
\n
\n At CJ Shaughnessy Crane Service, we focus on exceptional service for\n all your mobile hoisting and rigging needs. We realize all mobile\n hoisting and rigging jobs are not the same. Our goal is to form long\n term, professional relationships with customers, and our flexible\n scheduling options are designed to fit your needs.\n
\n At CJ Shaughnessy Crane Service, we believe in running with\n the industry's best equipment. This allows us to take on\n challenging work with ease while maintaining our core ethos of\n safety.\n
\n In 2012, founder Chris Shaughnessy took a risk as a young\n entrepreneur and purchased his first crane, a 35 ton boom\n truck. Coming from a family with over 100 years in the crane\n industry, Chris made a concious decision to break away and\n start a company of his own. With a focus on reliability,\n quality service and safety he saw an opportunity to grow.\n Since then CJ Shaughnessy Crane has done just that servicing\n the greater Boston area for the past {serviceYears} years. Now\n operating with {craneCount} cranes along with an entire\n trucking and warehousing service that is best in class we look\n forward to projects big and small.\n
\n \n
\n \n \n \n
\n
\n
\n OUR HISTORY\n
\n
Scroll through the growth of CJS Crane
\n \n
\n \n \n \n );\n};\n\nexport { About };\n","import { Job } from \"../../types\";\nimport { cranes } from \"../equipment/equipmentList\";\n\nimport childrensLift from \"../../images/childrens.jpg\";\n\nconst jobs: Job[] = [\n {\n title: \"Childrens Hospital Air Handler Replacement\",\n description: `We replaced a 30,000 lb air handler from the top of Childrens\n Hospital. This lift involved our LTM 1450 crane. The area was a\n tight fit but we were able to maneauver the air handler without any\n issues`,\n date: \"November 2020\",\n location: \"Boston MA\",\n equipmentUsed: [cranes[1]],\n specs: [\n { title: \"Pick Height\", value: \"300 ft\" },\n { title: \"Pick Radius\", value: \"400 ft\" },\n { title: \"Load Weight\", value: \"30,000 lbs\" },\n { title: \"Clearance\", value: \"10 ft\" },\n ],\n photoUrls: [childrensLift],\n summaryPhoto: childrensLift,\n },\n];\n\nexport { jobs };\n","import * as React from \"react\";\nimport { Container, Row, Col } from \"react-bootstrap\";\n\nimport {\n CjsJumbotron,\n Stack,\n Tiles,\n JobSummaryCard,\n PageHelmet,\n} from \"components\";\n\nimport { jobs } from \"./jobList\";\n\nconst Work = () => {\n return (\n \n \n \n \n
\n \n
\n
\n RECENT JOBS\n
\n
\n Check out some of our recent jobs we've finished. Click on each\n one for more information and photos!\n
\n \n \n \n \n \n );\n};\n\nexport { Contracts };\n","import React from \"react\";\nimport { Switch, Route, BrowserRouter } from \"react-router-dom\";\nimport { NavBar, Footer, ScrollToTop } from \"./components\";\nimport {\n Home,\n Equipment,\n About,\n Work,\n Quote,\n Contact,\n Career,\n Contracts,\n} from \"./routes\";\n\nimport \"./App.scss\";\n\nconst App = () => (\n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n);\n\nexport default App;\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(\n process.env.PUBLIC_URL,\n window.location.href\n );\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' }\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready\n .then(registration => {\n registration.unregister();\n })\n .catch(error => {\n console.error(error.message);\n });\n }\n}\n","import React from \"react\";\nimport ReactDOM from \"react-dom\";\n\nimport \"./App.scss\";\n\nimport App from \"./App\";\nimport * as serviceWorker from \"./serviceWorker\";\nimport { gaTracking } from \"./services\";\n\ngaTracking.init();\n\nconst renderApp = () => {\n ReactDOM.render(\n \n \n ,\n document.getElementById(\"root\")\n );\n // If you want your app to work offline and load faster, you can change\n // unregister() to register() below. Note this comes with some pitfalls.\n // Learn more about service workers: https://bit.ly/CRA-PWA\n serviceWorker.unregister();\n};\n\nrenderApp();\n"],"sourceRoot":""}