Help
RSS
API
Feed
Maltego
Contact
Domain > www.nickcelestin.com
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2025-03-02
3.171.85.85
(
ClassC
)
2025-08-27
3.175.34.113
(
ClassC
)
Port 80
HTTP/1.1 301 Moved PermanentlyServer: CloudFrontDate: Wed, 27 Aug 2025 17:28:31 GMTContent-Type: text/htmlContent-Length: 167Connection: keep-aliveLocation: https://www.nickcelestin.com/X-Cache: Redirect from cloudfrontVia: 1.1 1dec60e7743931415d677a5c5573774e.cloudfront.net (CloudFront)X-Amz-Cf-Pop: HIO52-P3X-Amz-Cf-Id: WpK85LmO0fIKRbM62oOA0FWNWLUhozNVejKRRDJjOk-1zTcH2g3ugw html>head>title>301 Moved Permanently/title>/head>body>center>h1>301 Moved Permanently/h1>/center>hr>center>CloudFront/center>/body>/html>
Port 443
HTTP/1.1 200 OKContent-Type: text/htmlContent-Length: 12743Connection: keep-aliveDate: Wed, 27 Aug 2025 17:28:32 GMTLast-Modified: Mon, 21 Oct 2024 11:56:08 GMTETag: bc8348309ada21d98d95e6a619c96eb3x-amz-server-side-encryption: AES256Accept-Ranges: bytesServer: AmazonS3X-Cache: Miss from cloudfrontVia: 1.1 17220d5b0843b7d6f37da152096b8a14.cloudfront.net (CloudFront)X-Amz-Cf-Pop: HIO52-P3X-Amz-Cf-Id: zi5ZCvpCS3EhVq3tSatPBsH57o-yXvlt7UvlcuvT8oersIA7VfFCeQ !doctype html>html langen> head> meta charsetutf-8> meta nameviewport contentwidthdevice-width, initial-scale1.0> link relstylesheet hrefhttps://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css /> link hrefhttps://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism-okaidia.min.css relstylesheet /> script srchttps://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-core.min.js>/script> script srchttps://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/plugins/autoloader/prism-autoloader.min.js>/script> link relicon typeimage/png sizes32x32 hrefimages/logo.png />style>pre.mermaid { background:transparent;}img { max-width: 500px; max-height: 500px; width: auto; height: auto; object-fit: contain; aspect-ratio: 1 / 1;}/style> title>Celestin AI/title> /head> !-- Google tag (gtag.js) -->script async srchttps://www.googletagmanager.com/gtag/js?idG-8G66FCVNVQ>/script>script>function initLightbox() { const images Array.from(document.querySelectorAll(img.lightbox)); const imageGroups groupAdjacentImages(images); imageGroups.forEach(processGroup);}function groupAdjacentImages(images) { return images.reduce((groups, currentImage) > { const isAdjacentToPreviousImage (previousImage) > previousImage && currentImage.previousElementSibling previousImage; const previousGroup groupsgroups.length - 1; const previousImage previousGroup ? previousGrouppreviousGroup.length - 1 : null; if (isAdjacentToPreviousImage(previousImage)) { previousGroup.push(currentImage); } else { groups.push(currentImage); } return groups; }, );}function processGroup(group) { if (group.length > 1) { createCarousel(group); } else { addLightboxToSingle(group0); }}function createCarousel(images) { const container document.createElement(div); container.className lightbox-carousel; container.style.cssText ` position: relative; display: inline-block; `; const mainImage document.createElement(img); mainImage.src images0.src; mainImage.style.cssText ` max-width: 100%; height: auto; `; const controls createControls(images.length); container.appendChild(mainImage); container.appendChild(controls); let currentIndex 0; function updateImage() { mainImage.src imagescurrentIndex.src; updateDots(); } function changeImage(direction) { currentIndex (currentIndex + direction + images.length) % images.length; updateImage(); } controls.querySelector(.prev).addEventListener(click, (e) > { e.stopPropagation(); changeImage(-1); }); controls.querySelector(.next).addEventListener(click, (e) > { e.stopPropagation(); changeImage(1); }); container.addEventListener(mouseenter, () > { controls.style.opacity 1; }); container.addEventListener(mouseleave, () > { controls.style.opacity 0; }); container.addEventListener(click, () > { openLightbox(images, currentIndex); }); // Replace original images with the carousel const parent images0.parentNode; const firstImage images0; parent.insertBefore(container, firstImage); images.forEach(img > parent.removeChild(img)); function updateDots() { const dots controls.querySelectorAll(.dot); dots.forEach((dot, index) > { dot.style.background index currentIndex ? #fff : transparent; }); }}function createControls(imageCount) { const controls document.createElement(div); controls.style.cssText ` position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; justify-content: space-between; opacity: 0; transition: opacity 0.3s; `; const arrows document.createElement(div); arrows.style.cssText ` display: flex; justify-content: space-between; align-items: center; height: 100%; `; prev, next.forEach(direction > { const arrow document.createElement(div); arrow.className direction; arrow.textContent direction prev ? ‹ : ›; arrow.style.cssText ` font-size: 2em; color: white; background: rgba(0,0,0,0.5); padding: 10px; cursor: pointer; `; arrows.appendChild(arrow); }); const dots document.createElement(div); dots.style.cssText ` display: flex; justify-content: center; padding: 10px; `; for (let i 0; i imageCount; i++) { const dot document.createElement(div); dot.className dot; dot.style.cssText ` width: 10px; height: 10px; border-radius: 50%; background: ${i 0 ? #fff : transparent}; border: 1px solid #fff; margin: 0 5px; `; dots.appendChild(dot); } controls.appendChild(arrows); controls.appendChild(dots); return controls;}function addLightboxToSingle(img) { img.addEventListener(click, () > { openLightbox(img, 0); });}function openLightbox(images, startIndex) { const lightbox document.createElement(div); lightbox.style.cssText ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center; z-index: 1000; `; const container document.createElement(div); container.style.cssText ` position: relative; width: 90%; height: 90%; display: flex; justify-content: center; align-items: center; `; const fullImg document.createElement(img); fullImg.style.cssText ` max-width: 100%; max-height: 100%; object-fit: contain; `; const controls createControls(images.length); controls.style.opacity 1; container.appendChild(fullImg); container.appendChild(controls); lightbox.appendChild(container); let currentIndex startIndex; function updateImage() { fullImg.src imagescurrentIndex.src; updateDots(); } function changeImage(direction) { currentIndex (currentIndex + direction + images.length) % images.length; updateImage(); } controls.querySelector(.prev).addEventListener(click, (e) > { e.stopPropagation(); changeImage(-1); }); controls.querySelector(.next).addEventListener(click, (e) > { e.stopPropagation(); changeImage(1); }); container.addEventListener(click, (e) > { if(e.target.closest(.prev) || e.target.closest(.next) || e.target.closest(.dot)) return; document.body.removeChild(lightbox); e.stopPropagation(); }); document.body.appendChild(lightbox); updateImage(); function updateDots() { const dots controls.querySelectorAll(.dot); dots.forEach((dot, index) > { dot.style.background index currentIndex ? #fff : transparent; }); }}// Call the function when the DOM is fully loadeddocument.addEventListener(DOMContentLoaded, initLightbox);document.addEventListener(DOMContentLoaded, () > { if (typeof Prism ! undefined) { Prism.highlightAll(); }});/script> body> main classcontainer> nav styleborder-bottom: 1px solid var(--pico-muted-color);margin-bottom: 1em;> ul> li>strong>Nick Celestin/strong>/li> /ul> ul> li>a href/index.html>AI Apps/a>/li> li>a href/llm_patterns/index.html>LLM Patterns/a>/li> li>a href/resume/index.html>Resume/a>/li> /ul> /nav> style>.application-card { display: flex; gap: 1.5em; flex-wrap: wrap;}.title-section, .details-section { flex: 1 1 300px; display: flex; flex-direction: column; align-items: center;}.title-section { border-right: 1px solid var(--pico-muted-color); padding-right: 1em;}.details-section { justify-content: center;}.title { font-size: 1.5em; margin: 0;}.title, .subtitle { text-align: center; }.stats { display: flex; flex-wrap: wrap; justify-content: center; gap: 1em; padding: 0; margin-top: 1em; font-size: 0.8em; color: var(--pico-muted-color); list-style-type: none;}.stats li { list-style-type: none;}.example-image { max-width: 100%; height: auto; margin-top: 1em; cursor: zoom-in;}.application-card a { color: var(--pico-secondary); text-decoration: none; border-bottom: 1px solid var(--pico-secondary); opacity: 0.8; transition: opacity 0.3s;}.application-card a:hover { opacity: 1; }.details-section ul { max-width: 40em; padding-left: 1.5em;}@media (max-width: 768px) { .application-card { flex-direction: column; } .title-section { border-right: none; border-bottom: 1px solid var(--pico-muted-color); padding-right: 0; padding-bottom: 1em; }}/style>p>I love creating vanilla JavaScript applications that use AI./p>p>The applications below are free to use and reference. Their code is transparent and unminified./p>p>They run strictly in your browser and they only communicate with the AI services you specify. Use your own OpenAI / OpenRouter / Etc API Keys./p>p>For a behind-the-scenes look at how theyre built, see a hrefllm_patterns/index.html>LLM Patterns/a>./p>p>If you have issues with the applications or would like to chat, you can email me at nick at this domain./p>article classapplication-card> div classtitle-section> h2 classtitle>a hrefapplications/journai/index.html>JournAI/a>/h2> p classsubtitle>An LLM-Powered Text Adventure Game Engine/p> p classversion>em>Updated 8/24/2024/em>/p> img classexample-image lightbox srcimg/journai-play.png altJournAI example> img classexample-image lightbox srcimg/journai-setup.png altJournAI example> img classexample-image lightbox srcimg/journai-setup-advanced.png altJournAI example> img classexample-image lightbox srcimg/journai-api-config.png altJournAI example> ul classstats> li>Browser Game/li> li>Vanilla Javascript/li> /ul> /div> div classdetails-section> ul> li>em>(New)/em> Easily manage ongoing adventures and templates/li> li>Immersive audio narration./li> li>Intelligent context control allows for massive game histories while keeping costs low./li> li>Customizable setups to play many types of games./li> li>Configurable stat tracking for things like Health, Mana, Existential Dread, etc./li> li>Instant feedback with real-time streaming of complex data to the user interface./li> li>All in-browser and no logging between you and the LLM service of your choice./li> li>Bring your own OpenAI-style URL and API Key./li> /ul> /div>/article>article classapplication-card> div classtitle-section> h2 classtitle>a hrefhttp://liminai.s3-website-us-east-1.amazonaws.com>Liminai/a>/h2> p classsubtitle>An LLM-Powered Escape Room Game/p> img classexample-image lightbox srcimg/liminai.png altLiminai example> ul classstats> li>Browser Game/li> li>Vanilla Javascript/li> /ul> /div> div classdetails-section> p> You wake up in a liminal hell, and you must escape, while suffering the poetic taunts of an unseen and omnipresent entity. /p> ul> li>AI-generated text, images, and audio./li> li>Converse with a malevolent omnipresent entity that speaks only in poetry./li> li>Explore endlessly sprawling interconnected locations, generated on the fly./li> li>Freedom to perform any possible action, challenge in what is actually possible./li> li>Dynamic win-condition -- even I dont know all possible ways to arrive at a win state./li> li>Robust LLM-powered state management allows for creative, complex, multi-step solutions to problems./li> /ul> /div>/article> /main> script typemodule async>import mermaid from https://unpkg.com/mermaid@10/dist/mermaid.esm.min.mjs;document.addEventListener(DOMContentLoaded, mermaid.initialize({loadOnSave:true}));/script> /body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]