Add (ai tool submission)

This commit is contained in:
2023-11-29 21:16:13 +08:00
parent 79326f74f1
commit 7ce1e93242
67 changed files with 686 additions and 474 deletions

View File

@@ -21,8 +21,7 @@ protected function schedule(Schedule $schedule)
$schedule->call(function () {
$url_to_crawl = UrlToCrawl::where('is_crawling', false)->inRandomOrder()->first();
if (!is_null($url_to_crawl))
{
if (! is_null($url_to_crawl)) {
GetUrlBodyJob::dispatch($url_to_crawl->id)->onQueue('default')->onConnection('default');
}

View File

@@ -10,9 +10,10 @@ class Cached
public static function tools_count()
{
$seconds_to_remember = 599;
// Retrieve the count from the cache or count and store it if not present
return Cache::remember('tools_count_' . $seconds_to_remember, $seconds_to_remember, function () {
return AiTool::where('status','live')->count();
return Cache::remember('tools_count_'.$seconds_to_remember, $seconds_to_remember, function () {
return AiTool::where('status', 'live')->count();
});
}
}

View File

@@ -4,3 +4,4 @@
require 'geo_helper.php';
require 'proxy_helper.php';
require 'route_helper.php';
require 'platform_helper.php';

View File

@@ -0,0 +1,21 @@
<?php
if (! function_exists('get_notification_channel')) {
function get_notification_channel()
{
return 'telegram';
}
}
if (! function_exists('get_notification_user_ids')) {
function get_notification_user_ids()
{
return [
'629991336', // me
];
}
}

View File

@@ -4,7 +4,8 @@
use Illuminate\Support\Str;
if (! function_exists('count_words')) {
function count_words($string) {
function count_words($string)
{
// Remove punctuation and line breaks
$cleanString = preg_replace('/[\p{P}\s]/u', ' ', $string);
@@ -16,7 +17,6 @@ function count_words($string) {
}
}
if (! function_exists('dmy')) {
function dmy(Carbon $carbon)
{

View File

@@ -71,7 +71,7 @@ public function discover(Request $request, $category_slug = null)
$ai_tools = AiTool::when(! is_null($category), function ($query) use ($category) {
$query->where('category_id', $category->id);
})
->where('status','live')
->where('status', 'live')
->whereNotNull('screenshot_img')
->orderBy('updated_at', 'DESC')->paginate(6);

View File

@@ -16,9 +16,9 @@ public function index(Request $request)
{
$tools_count_rounded = round_to_nearest_base(Cached::tools_count());
$latest_ai_tools = AiTool::where('status','live')->whereNotNull('screenshot_img')->take(12)->orderBy('created_at', 'DESC')->get();
$latest_ai_tools = AiTool::where('status', 'live')->whereNotNull('screenshot_img')->take(12)->orderBy('created_at', 'DESC')->get();
return view('front.home', compact('latest_ai_tools','tools_count_rounded'));
return view('front.home', compact('latest_ai_tools', 'tools_count_rounded'));
}
public function terms(Request $request)

View File

@@ -0,0 +1,97 @@
<?php
namespace App\Http\Controllers\Front;
use App\Http\Controllers\Controller;
use App\Models\SubmitTool;
use App\Models\UrlToCrawl;
use App\Notifications\AiToolSubmitted;
use Illuminate\Http\Request;
use Notification;
class FrontSubmitToolController extends Controller
{
public function index(Request $request)
{
$submitted_tool_count = SubmitTool::whereIn('status', ['initial', 'queued_for_crawl', 'crawled'])->count();
$max_submissions = 2000;
$submissions_left = $max_submissions - $submitted_tool_count;
return view('front.submit_tool_free', compact('submitted_tool_count', 'submissions_left', 'max_submissions'));
}
public function post(Request $request)
{
$submitted_tool_count = SubmitTool::whereIn('status', ['initial', 'queued_for_crawl', 'crawled'])->count();
$max_submissions = 2000;
$submissions_left = $max_submissions - $submitted_tool_count;
$submited_url = rtrim(trim($request->input('submitted_url')), '/\\');
if ($submissions_left <= 0) {
return redirect()->back()->withInput()->with('error', (object) ['timeout' => 5000, 'message' => 'Unfortunately, all submission slots have been filled. Please check try again later to see if there are any slots released from rejected submissions.']);
}
if (filter_var($submited_url, FILTER_VALIDATE_URL) === false) {
return redirect()->back()->withInput()->with('error', (object) ['timeout' => 5000, 'message' => 'Submitted URL is in invalid URL format. Please check your inputs and try again.']);
}
$submit_tool = SubmitTool::where('submitted_url', $submited_url)->first();
if (! is_null($submit_tool)) {
return redirect()->back()->withInput()->with('error', (object) ['timeout' => 5000, 'message' => 'You have submitted this URL before. Submission ignored.']);
}
$ignore_url_keywords = ['play.google.com', 'apps.apple.com', 'https://chromewebstore.google.com'];
$is_store_url = false;
foreach ($ignore_url_keywords as $keyword) {
if (str_contains($submited_url, $keyword)) {
$is_store_url = true;
break;
}
}
$url_to_crawl = null;
if ($is_store_url) {
$url_to_crawl = UrlToCrawl::where('url', $submited_url)->first();
} else {
$domain = get_domain_from_url($submited_url);
$url_to_crawl = UrlToCrawl::where('domain', $domain)->first();
}
if (! is_null($url_to_crawl)) {
return redirect()->back()->withInput()->with('success', (object) ['timeout' => 5000, 'message' => 'Our AI crawler has already identified & pre-approved your submission. It has been scheduled for live submission and should appear in our pages soon.']);
}
$submit_tool = new SubmitTool;
$submit_tool->submitted_url = $request->input('submitted_url');
$submit_tool->email = $request->input('email');
$submit_tool->social = $request->input('social');
$submit_tool->social_type = $request->input('social_type');
$submit_tool->source_type = $request->input('source_type');
$submit_tool->source = $request->input('source');
$submit_tool->comments = $request->input('comments');
if ($submit_tool->save()) {
$submitted_tool_count = SubmitTool::whereIn('status', ['initial', 'queued_for_crawl', 'crawled'])->count();
$telegram_ids = get_notification_user_ids();
foreach ($telegram_ids as $telegram_id) {
Notification::route(get_notification_channel(), $telegram_id)->notify(new AiToolSubmitted($submit_tool));
}
return redirect()->back()->withInput()->with('success', (object) ['timeout' => 5000, 'message' => 'AI tool submittted successfully! You are #'.$submitted_tool_count.' in submission list.']);
}
return redirect()->back()->withInput()->with('error', (object) ['timeout' => 5000, 'message' => 'Something went wrong. Please try again later.']);
}
}

View File

@@ -13,7 +13,7 @@ class FrontToolController extends Controller
{
public function show(Request $request, $ai_tool_slug)
{
$ai_tool = AiTool::where('slug', $ai_tool_slug)->where('status','live')->first();
$ai_tool = AiTool::where('slug', $ai_tool_slug)->where('status', 'live')->first();
if (is_null($ai_tool)) {
return abort(404);
@@ -74,8 +74,8 @@ public function show(Request $request, $ai_tool_slug)
$faq_context = Context::create(FAQPage::class, $faqData);
SEOTools::setTitle($ai_tool->tool_name . ": ". $ai_tool->tagline, false);
SEOTools::setDescription(implode(" ",str_extract_sentences($ai_tool->summary, 2)));
SEOTools::setTitle($ai_tool->tool_name.': '.$ai_tool->tagline, false);
SEOTools::setDescription(implode(' ', str_extract_sentences($ai_tool->summary, 2)));
SEOTools::metatags();
SEOTools::twitter()->addImage($ai_tool->screenshot_img);
SEOTools::opengraph()->addImage($ai_tool->screenshot_img);

View File

@@ -73,8 +73,7 @@ public static function handle($url_to_crawl_id, $ai_tool_id)
}
if ($ai_tool->isDirty()) {
if($ai_tool->save())
{
if ($ai_tool->save()) {
PublishIndexPostJob::dispatch($ai_tool->id)->onQueue('default')->onConnection('default');
}
}

View File

@@ -33,7 +33,6 @@ public static function handle(int $url_to_crawl_id)
$url_to_crawl->save();
$url_to_crawl->refresh();
// try {
$user_agent = config('platform.proxy.user_agent');
@@ -71,10 +70,8 @@ public static function handle(int $url_to_crawl_id)
// //throw $e;
// }
$markdown_output = self::getMarkdownFromHtml($raw_html);
if (! is_empty($markdown_output)) {
$url_to_crawl->output_type = 'markdown';
$url_to_crawl->output = $markdown_output;

View File

@@ -5,7 +5,6 @@
use App\Helpers\FirstParty\OpenAI\OpenAI;
use App\Jobs\GetAIToolScreenshotJob;
use App\Jobs\GetUrlBodyJob;
use App\Jobs\ParseUrlBodyJob;
use App\Jobs\StoreSearchEmbeddingJob;
use App\Models\AiTool;
use App\Models\AiToolKeyword;
@@ -32,15 +31,15 @@ public static function handle(int $url_to_crawl_id)
if (is_empty($url_to_crawl->output)) {
GetUrlBodyJob::dispatch($url_to_crawl->id)->onQueue('default')->onConnection('default');
return ;
return;
}
if (count_words($url_to_crawl->output) < 120)
{
if (count_words($url_to_crawl->output) < 120) {
$url_to_crawl->status = 'blocked';
$url_to_crawl->save();
return ;
return;
}
$url_meta_response = null;

View File

@@ -3,9 +3,7 @@
namespace App\Jobs\Tasks;
use App\Models\AiTool;
use App\Notifications\PostWasPublished;
use Exception;
use Illuminate\Support\Facades\Notification;
use LaravelFreelancerNL\LaravelIndexNow\Facades\IndexNow;
use LaravelGoogleIndexing;
@@ -19,13 +17,10 @@ public static function handle(int $ai_tool_id)
return;
}
if (!$ai_tool->is_ai_tool)
{
return ;
if (! $ai_tool->is_ai_tool) {
return;
}
if ((app()->environment() == 'production') && (config('platform.general.indexing'))) {
$ai_tool_url = route('front.aitool.show', ['ai_tool_slug' => $ai_tool->slug]);
@@ -41,5 +36,4 @@ public static function handle(int $ai_tool_id)
}
}
}

45
app/Models/SubmitTool.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
/**
* Created by Reliese Model.
*/
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
* Class SubmitTool
*
* @property int $id
* @property string $submit_type
* @property string $submitted_url
* @property string $email
* @property string|null $social
* @property string|null $social_type
* @property string|null $source
* @property string|null $source_type
* @property string|null $comments
* @property string $status
* @property string $queue_priority
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*/
class SubmitTool extends Model
{
protected $table = 'submit_tools';
protected $fillable = [
'submit_type',
'submitted_url',
'email',
'social',
'social_type',
'source',
'source_type',
'comments',
'status',
'queue_priority',
];
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Notifications;
use App\Models\SubmitTool;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use NotificationChannels\Telegram\TelegramMessage;
class AiToolSubmitted extends Notification
{
use Queueable;
protected $submit_tool;
/**
* Create a new notification instance.
*/
public function __construct(SubmitTool $submit_tool)
{
$this->submit_tool = $submit_tool;
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['telegram'];
}
public function toTelegram($notifiable)
{
return TelegramMessage::create()
->content("*AI Tool Submitted*:\nURL: ".$this->submit_tool->submitted_url."\nBy: ".$this->submit_tool->social.' in '.$this->submit_tool->social_type."\nEmail: ".$this->submit_tool->email."\nFound us from: ".$this->submit_tool->source.' from '.$this->submit_tool->source_type."\n\nComments: ".$this->submit_tool->comments);
}
}

View File

@@ -3,8 +3,6 @@
namespace App\View\Composers;
use App\Helpers\FirstParty\Cached\Cached;
use App\Models\AiTool;
use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;
class StatsComposer

View File

@@ -23,6 +23,7 @@
"intervention/image": "^2.7",
"kalnoy/nestedset": "^6.0",
"laravel-freelancer-nl/laravel-index-now": "^1.2",
"laravel-notification-channels/telegram": "^4.0",
"laravel/framework": "^10.10",
"laravel/horizon": "^5.21",
"laravel/sanctum": "^3.2",

75
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "63a6e2f82f8bc123bd492a8a3c168cda",
"content-hash": "5cf22553f6396a0cd2d2eec26316490a",
"packages": [
{
"name": "alaminfirdows/laravel-editorjs",
@@ -2531,6 +2531,79 @@
],
"time": "2023-02-17T14:44:51+00:00"
},
{
"name": "laravel-notification-channels/telegram",
"version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/laravel-notification-channels/telegram.git",
"reference": "c67b312193fcd59c8abad1ee1f5b1f4e5540c201"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel-notification-channels/telegram/zipball/c67b312193fcd59c8abad1ee1f5b1f4e5540c201",
"reference": "c67b312193fcd59c8abad1ee1f5b1f4e5540c201",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/guzzle": "^7.2",
"illuminate/contracts": "^10.0",
"illuminate/notifications": "^10.0",
"illuminate/support": "^10.0",
"php": "^8.1"
},
"require-dev": {
"mockery/mockery": "^1.4.4",
"nunomaduro/larastan": "^2.4",
"orchestra/testbench": "^8.0",
"pestphp/pest": "^1.22",
"pestphp/pest-plugin-laravel": "^1.4",
"phpstan/extension-installer": "^1.2",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpunit": "^9.5.10"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"NotificationChannels\\Telegram\\TelegramServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"NotificationChannels\\Telegram\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Irfaq Syed",
"email": "github@lukonet.net",
"homepage": "https://lukonet.com",
"role": "Developer"
}
],
"description": "Telegram Notifications Channel for Laravel",
"homepage": "https://github.com/laravel-notification-channels/telegram",
"keywords": [
"laravel",
"notification",
"telegram",
"telegram notification",
"telegram notifications channel"
],
"support": {
"issues": "https://github.com/laravel-notification-channels/telegram/issues",
"source": "https://github.com/laravel-notification-channels/telegram/tree/4.0.0"
},
"time": "2023-02-14T18:21:03+00:00"
},
{
"name": "laravel/framework",
"version": "v10.33.0",

View File

@@ -31,4 +31,8 @@
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'telegram-bot-api' => [
'token' => env('TELEGRAM_BOT_TOKEN', 'YOUR BOT TOKEN HERE'),
],
];

View File

@@ -13,7 +13,7 @@ public function up(): void
{
Schema::table('ai_tools', function (Blueprint $table) {
$table->string('priority')->default('default');
$table->enum('status',['live','trashed','blocked'])->default('live');
$table->enum('status', ['live', 'trashed', 'blocked'])->default('live');
$table->index('priority');
$table->index('status');

View File

@@ -0,0 +1,49 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('submit_tools', function (Blueprint $table) {
$table->id();
$table->enum('submit_type', ['free', 'paid'])->default('free');
$table->mediumText('submitted_url');
$table->string('email');
$table->string('social')->nullable();
$table->string('social_type')->nullable();
$table->mediumText('source')->nullable();
$table->string('source_type')->nullable();
$table->mediumText('comments')->nullable();
$table->enum('status', ['initial', 'queued_for_crawl', 'crawled', 'rejected'])->default('initial');
$table->enum('queue_priority', ['default', 'high_priority'])->default('default');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('submit_tools');
}
};

View File

@@ -1 +1 @@
import{_ as a,l as r,c as n,a as t,o as c}from"./app-front-ae9fe805.js";const m={name:"GetEmbedCode",mixins:[],components:{},props:["url","name"],data:()=>({imgSrc:"https://cdn.aibuddytool.com/featured-on-aibuddytool-1-1000.webp",showToast:!1}),computed:{embedCode(){return"<!-- "+this.name+' featured by AiBuddyTool.com --><a href="'+this.url+'" target="_blank"><img alt="'+this.name+'" style="width: 250px; height: auto" src="'+this.imgSrc+'"></a>'}},methods:{getEmbedCode(){const e=document.createElement("textarea");e.value=this.embedCode,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e),r("Copied! Paste the HTML embed code at the bottom of your business website footer.",{position:"bottom-center",type:"success",timeout:3e3,closeOnClick:!0,pauseOnFocusLoss:!0,pauseOnHover:!0,draggable:!0,draggablePercent:.6,showCloseButtonOnHover:!1,hideProgressBar:!1,closeButton:!0,icon:!0,rtl:!1})}},mounted(){}},u={class:"d-grid gap-2 mx-auto",style:{width:"250px"}},i=["src"];function l(e,o,b,p,h,s){return c(),n("div",null,[t("div",u,[t("img",{style:{width:"250px",height:"auto"},src:e.imgSrc,alt:"Featured banner"},null,8,i),t("button",{onClick:o[0]||(o[0]=(...d)=>s.getEmbedCode&&s.getEmbedCode(...d)),class:"btn btn-sm btn-outline-primary px-3"}," Get HTML embed code ")])])}const f=a(m,[["render",l]]);export{f as default};
import{_ as a,l as r,c as n,a as t,o as c}from"./app-front-d6902e40.js";const m={name:"GetEmbedCode",mixins:[],components:{},props:["url","name"],data:()=>({imgSrc:"https://cdn.aibuddytool.com/featured-on-aibuddytool-1-1000.webp",showToast:!1}),computed:{embedCode(){return"<!-- "+this.name+' featured by AiBuddyTool.com --><a href="'+this.url+'" target="_blank"><img alt="'+this.name+'" style="width: 250px; height: auto" src="'+this.imgSrc+'"></a>'}},methods:{getEmbedCode(){const e=document.createElement("textarea");e.value=this.embedCode,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e),r("Copied! Paste the HTML embed code at the bottom of your business website footer.",{position:"bottom-center",type:"success",timeout:3e3,closeOnClick:!0,pauseOnFocusLoss:!0,pauseOnHover:!0,draggable:!0,draggablePercent:.6,showCloseButtonOnHover:!1,hideProgressBar:!1,closeButton:!0,icon:!0,rtl:!1})}},mounted(){}},u={class:"d-grid gap-2 mx-auto",style:{width:"250px"}},i=["src"];function l(e,o,b,p,h,s){return c(),n("div",null,[t("div",u,[t("img",{style:{width:"250px",height:"auto"},src:e.imgSrc,alt:"Featured banner"},null,8,i),t("button",{onClick:o[0]||(o[0]=(...d)=>s.getEmbedCode&&s.getEmbedCode(...d)),class:"btn btn-sm btn-outline-primary px-3"}," Get HTML embed code ")])])}const f=a(m,[["render",l]]);export{f as default};

Binary file not shown.

View File

@@ -1 +0,0 @@
import{_ as a,l as r,c as n,a as t,o as c}from"./app-front-32dad050.js";const m={name:"GetEmbedCode",mixins:[],components:{},props:["url","name"],data:()=>({imgSrc:"https://cdn.aibuddytool.com/featured-on-aibuddytool-1-1000.webp",showToast:!1}),computed:{embedCode(){return"<!-- "+this.name+' featured by AiBuddyTool.com --><a href="'+this.url+'" target="_blank"><img alt="'+this.name+'" style="width: 250px; height: auto" src="'+this.imgSrc+'"></a>'}},methods:{getEmbedCode(){const e=document.createElement("textarea");e.value=this.embedCode,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e),r("Copied! Paste the HTML embed code at the bottom of your business website footer.",{position:"bottom-center",type:"success",timeout:3e3,closeOnClick:!0,pauseOnFocusLoss:!0,pauseOnHover:!0,draggable:!0,draggablePercent:.6,showCloseButtonOnHover:!1,hideProgressBar:!1,closeButton:!0,icon:!0,rtl:!1})}},mounted(){}},u={class:"d-grid gap-2 mx-auto",style:{width:"250px"}},i=["src"];function l(e,o,b,p,h,s){return c(),n("div",null,[t("div",u,[t("img",{style:{width:"250px",height:"auto"},src:e.imgSrc,alt:"Featured banner"},null,8,i),t("button",{onClick:o[0]||(o[0]=(...d)=>s.getEmbedCode&&s.getEmbedCode(...d)),class:"btn btn-sm btn-outline-primary px-3"}," Get HTML embed code ")])])}const f=a(m,[["render",l]]);export{f as default};

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import Qn from"./VueEditorJs-bbb0be71.js";import{r as Ft,_ as Mr}from"./NativeImageBlock-a8b03c38.js";import{L as hn}from"./bundle-c20bcf97.js";import{H as yn}from"./bundle-72871e75.js";import{g as Cr,d as Pr,b as ua,r as zt,e as ne,f as vt,u as nn,t as da,h as ct,i as rn,w as Nt,j as Z,o as R,c as Q,k as _t,m as nt,n as Fe,p as _e,q as ie,s as ze,v as ft,x as j,y as Qe,z as gn,A as Pe,B as G,C as Gn,T as Sr,D as Ce,E as he,a as J,F as ot,G as we,H as It,I as rt,J as Ve,K as Zt,L as At,M as yt,N as wa,O as Or,P as Nr,Q as Ar,_ as $r,R as Ir,S as Er,U as Yr,V as Ia,W as Ur,X as Lr,Y as wn}from"./app-front-32dad050.js";var Xn={exports:{}};/*!
import Qn from"./VueEditorJs-c40f6d08.js";import{r as Ft,_ as Mr}from"./NativeImageBlock-3623204f.js";import{L as hn}from"./bundle-f4b2cd77.js";import{H as yn}from"./bundle-7ca97fea.js";import{g as Cr,d as Pr,b as ua,r as zt,e as ne,f as vt,u as nn,t as da,h as ct,i as rn,w as Nt,j as Z,o as R,c as Q,k as _t,m as nt,n as Fe,p as _e,q as ie,s as ze,v as ft,x as j,y as Qe,z as gn,A as Pe,B as G,C as Gn,T as Sr,D as Ce,E as he,a as J,F as ot,G as we,H as It,I as rt,J as Ve,K as Zt,L as At,M as yt,N as wa,O as Or,P as Nr,Q as Ar,_ as $r,R as Ir,S as Er,U as Yr,V as Ia,W as Ur,X as Lr,Y as wn}from"./app-front-d6902e40.js";var Xn={exports:{}};/*!
* Image tool
*
* @version 2.8.1

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{_ as t,l as e,c as s,o}from"./app-front-d6902e40.js";const r={name:"ToastMessage",mixins:[],components:{},props:["type","message","timeout"],data:()=>({}),watch:{},computed:{},methods:{triggerMounted(){this.type=="error"&&e(this.message,{position:"bottom-center",type:"error",timeout:3e3,closeOnClick:!0,pauseOnFocusLoss:!0,pauseOnHover:!0,draggable:!0,draggablePercent:.6,showCloseButtonOnHover:!1,hideProgressBar:!1,closeButton:!0,icon:!0,rtl:!1}),this.type=="success"&&e(this.message,{position:"bottom-center",type:"success",timeout:3e3,closeOnClick:!0,pauseOnFocusLoss:!0,pauseOnHover:!0,draggable:!0,draggablePercent:.6,showCloseButtonOnHover:!1,hideProgressBar:!1,closeButton:!0,icon:!0,rtl:!1})}},mounted(){this.triggerMounted()}};function a(n,u,c,i,l,p){return o(),s("div")}const m=t(r,[["render",a]]);export{m as default};

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import{_ as Oe,a1 as Zt,f as Ne,c as De,r as Re,h as Pe,o as Fe}from"./app-front-ae9fe805.js";var He=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function xt(s){return s&&s.__esModule&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s}function Ct(){}Object.assign(Ct,{default:Ct,register:Ct,revert:function(){},__esModule:!0});Element.prototype.matches||(Element.prototype.matches=Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector||function(s){const t=(this.document||this.ownerDocument).querySelectorAll(s);let e=t.length;for(;--e>=0&&t.item(e)!==this;);return e>-1});Element.prototype.closest||(Element.prototype.closest=function(s){let t=this;if(!document.documentElement.contains(t))return null;do{if(t.matches(s))return t;t=t.parentElement||t.parentNode}while(t!==null);return null});Element.prototype.prepend||(Element.prototype.prepend=function(s){const t=document.createDocumentFragment();Array.isArray(s)||(s=[s]),s.forEach(e=>{const o=e instanceof Node;t.appendChild(o?e:document.createTextNode(e))}),this.insertBefore(t,this.firstChild)});Element.prototype.scrollIntoViewIfNeeded||(Element.prototype.scrollIntoViewIfNeeded=function(s){s=arguments.length===0?!0:!!s;const t=this.parentNode,e=window.getComputedStyle(t,null),o=parseInt(e.getPropertyValue("border-top-width")),i=parseInt(e.getPropertyValue("border-left-width")),n=this.offsetTop-t.offsetTop<t.scrollTop,r=this.offsetTop-t.offsetTop+this.clientHeight-o>t.scrollTop+t.clientHeight,a=this.offsetLeft-t.offsetLeft<t.scrollLeft,l=this.offsetLeft-t.offsetLeft+this.clientWidth-i>t.scrollLeft+t.clientWidth,c=n&&!r;(n||r)&&s&&(t.scrollTop=this.offsetTop-t.offsetTop-t.clientHeight/2-o+this.clientHeight/2),(a||l)&&s&&(t.scrollLeft=this.offsetLeft-t.offsetLeft-t.clientWidth/2-i+this.clientWidth/2),(n||r||a||l)&&!s&&this.scrollIntoView(c)});window.requestIdleCallback=window.requestIdleCallback||function(s){const t=Date.now();return setTimeout(function(){s({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-t))}})},1)};window.cancelIdleCallback=window.cancelIdleCallback||function(s){clearTimeout(s)};let je=(s=21)=>crypto.getRandomValues(new Uint8Array(s)).reduce((t,e)=>(e&=63,e<36?t+=e.toString(36):e<62?t+=(e-26).toString(36).toUpperCase():e>62?t+="-":t+="_",t),"");var se=(s=>(s.VERBOSE="VERBOSE",s.INFO="INFO",s.WARN="WARN",s.ERROR="ERROR",s))(se||{});const E={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,LEFT:37,UP:38,DOWN:40,RIGHT:39,DELETE:46,META:91},ze={LEFT:0,WHEEL:1,RIGHT:2,BACKWARD:3,FORWARD:4};function mt(s,t,e="log",o,i="color: inherit"){if(!("console"in window)||!window.console[e])return;const n=["info","log","warn","error"].includes(e),r=[];switch(mt.logLevel){case"ERROR":if(e!=="error")return;break;case"WARN":if(!["error","warn"].includes(e))return;break;case"INFO":if(!n||s)return;break}o&&r.push(o);const a="Editor.js 2.28.0",l=`line-height: 1em;
import{_ as Oe,a1 as Zt,f as Ne,c as De,r as Re,h as Pe,o as Fe}from"./app-front-d6902e40.js";var He=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function xt(s){return s&&s.__esModule&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s}function Ct(){}Object.assign(Ct,{default:Ct,register:Ct,revert:function(){},__esModule:!0});Element.prototype.matches||(Element.prototype.matches=Element.prototype.matchesSelector||Element.prototype.mozMatchesSelector||Element.prototype.msMatchesSelector||Element.prototype.oMatchesSelector||Element.prototype.webkitMatchesSelector||function(s){const t=(this.document||this.ownerDocument).querySelectorAll(s);let e=t.length;for(;--e>=0&&t.item(e)!==this;);return e>-1});Element.prototype.closest||(Element.prototype.closest=function(s){let t=this;if(!document.documentElement.contains(t))return null;do{if(t.matches(s))return t;t=t.parentElement||t.parentNode}while(t!==null);return null});Element.prototype.prepend||(Element.prototype.prepend=function(s){const t=document.createDocumentFragment();Array.isArray(s)||(s=[s]),s.forEach(e=>{const o=e instanceof Node;t.appendChild(o?e:document.createTextNode(e))}),this.insertBefore(t,this.firstChild)});Element.prototype.scrollIntoViewIfNeeded||(Element.prototype.scrollIntoViewIfNeeded=function(s){s=arguments.length===0?!0:!!s;const t=this.parentNode,e=window.getComputedStyle(t,null),o=parseInt(e.getPropertyValue("border-top-width")),i=parseInt(e.getPropertyValue("border-left-width")),n=this.offsetTop-t.offsetTop<t.scrollTop,r=this.offsetTop-t.offsetTop+this.clientHeight-o>t.scrollTop+t.clientHeight,a=this.offsetLeft-t.offsetLeft<t.scrollLeft,l=this.offsetLeft-t.offsetLeft+this.clientWidth-i>t.scrollLeft+t.clientWidth,c=n&&!r;(n||r)&&s&&(t.scrollTop=this.offsetTop-t.offsetTop-t.clientHeight/2-o+this.clientHeight/2),(a||l)&&s&&(t.scrollLeft=this.offsetLeft-t.offsetLeft-t.clientWidth/2-i+this.clientWidth/2),(n||r||a||l)&&!s&&this.scrollIntoView(c)});window.requestIdleCallback=window.requestIdleCallback||function(s){const t=Date.now();return setTimeout(function(){s({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-t))}})},1)};window.cancelIdleCallback=window.cancelIdleCallback||function(s){clearTimeout(s)};let je=(s=21)=>crypto.getRandomValues(new Uint8Array(s)).reduce((t,e)=>(e&=63,e<36?t+=e.toString(36):e<62?t+=(e-26).toString(36).toUpperCase():e>62?t+="-":t+="_",t),"");var se=(s=>(s.VERBOSE="VERBOSE",s.INFO="INFO",s.WARN="WARN",s.ERROR="ERROR",s))(se||{});const E={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,LEFT:37,UP:38,DOWN:40,RIGHT:39,DELETE:46,META:91},ze={LEFT:0,WHEEL:1,RIGHT:2,BACKWARD:3,FORWARD:4};function mt(s,t,e="log",o,i="color: inherit"){if(!("console"in window)||!window.console[e])return;const n=["info","log","warn","error"].includes(e),r=[];switch(mt.logLevel){case"ERROR":if(e!=="error")return;break;case"WARN":if(!["error","warn"].includes(e))return;break;case"INFO":if(!n||s)return;break}o&&r.push(o);const a="Editor.js 2.28.0",l=`line-height: 1em;
color: #006FEA;
display: inline-block;
font-size: 11px;
@@ -80,4 +80,4 @@ import{_ as Oe,a1 as Zt,f as Ne,c as De,r as Re,h as Pe,o as Fe}from"./app-front
* @license Apache-2.0
* @see Editor.js <https://editorjs.io>
* @author CodeX Team <https://codex.so>
*/class Si{static get version(){return"2.28.0"}constructor(t){let e=()=>{};z(t)&&R(t.onReady)&&(e=t.onReady);const o=new Ti(t);this.isReady=o.isReady.then(()=>{this.exportAPI(o),e()})}exportAPI(t){const e=["configuration"],o=()=>{Object.values(t.moduleInstances).forEach(i=>{R(i.destroy)&&i.destroy(),i.listeners.removeAll()}),t=null;for(const i in this)Object.prototype.hasOwnProperty.call(this,i)&&delete this[i];Object.setPrototypeOf(this,null)};e.forEach(i=>{this[i]=t[i]}),this.destroy=o,Object.setPrototypeOf(this,t.moduleInstances.API.methods),delete this.exportAPI,Object.entries({blocks:{clear:"clear",render:"render"},caret:{focus:"focus"},events:{on:"on",off:"off",emit:"emit"},saver:{save:"save"}}).forEach(([i,n])=>{Object.entries(n).forEach(([r,a])=>{this[a]=t.moduleInstances.API.methods[i][r]})})}}const Tt={header:Zt(()=>import("./bundle-8efc010f.js").then(s=>s.b),["assets/bundle-8efc010f.js","assets/app-front-ae9fe805.js","assets/app-front-935fc652.css"]),list:Zt(()=>import("./bundle-2f2c1632.js").then(s=>s.b),["assets/bundle-2f2c1632.js","assets/app-front-ae9fe805.js","assets/app-front-935fc652.css"])},Ii=Ne({name:"vue-editor-js",props:{holder:{type:String,default:()=>"vue-editor-js",require:!0},config:{type:Object,default:()=>({}),require:!0},initialized:{type:Function,default:()=>{}}},setup:(s,t)=>{const e=Re({editor:null});function o(r){i(),e.editor=new Si({holder:r.holder||"vue-editor-js",...r.config,onChange:(a,l)=>{n()}}),r.initialized(e.editor)}function i(){e.editor&&(e.editor.destroy(),e.editor=null)}function n(){console.log("saveEditor"),e.editor&&e.editor.save().then(r=>{console.log(r),t.emit("saved",r)})}return Pe(r=>o(s)),{props:s,state:e}},methods:{useTools(s,t){const e=Object.keys(Tt),o={...s.customTools};return e.every(i=>!s[i])?(e.forEach(i=>o[i]={class:Tt[i]}),Object.keys(t).forEach(i=>{o[i]!==void 0&&o[i]!==null&&(o[i].config=t[i])}),o):(e.forEach(i=>{const n=s[i];if(n&&(o[i]={class:Tt[i]},typeof n=="object")){const r=Object.assign({},s[i]);delete r.class,o[i]=Object.assign(o[i],r)}}),Object.keys(t).forEach(i=>{o[i]!==void 0&&o[i]!==null&&(o[i].config=t[i])}),o)}}}),Mi=["id"];function _i(s,t,e,o,i,n){return Fe(),De("div",{id:s.holder},null,8,Mi)}const Li=Oe(Ii,[["render",_i]]);export{Tt as PLUGINS,Li as default};
*/class Si{static get version(){return"2.28.0"}constructor(t){let e=()=>{};z(t)&&R(t.onReady)&&(e=t.onReady);const o=new Ti(t);this.isReady=o.isReady.then(()=>{this.exportAPI(o),e()})}exportAPI(t){const e=["configuration"],o=()=>{Object.values(t.moduleInstances).forEach(i=>{R(i.destroy)&&i.destroy(),i.listeners.removeAll()}),t=null;for(const i in this)Object.prototype.hasOwnProperty.call(this,i)&&delete this[i];Object.setPrototypeOf(this,null)};e.forEach(i=>{this[i]=t[i]}),this.destroy=o,Object.setPrototypeOf(this,t.moduleInstances.API.methods),delete this.exportAPI,Object.entries({blocks:{clear:"clear",render:"render"},caret:{focus:"focus"},events:{on:"on",off:"off",emit:"emit"},saver:{save:"save"}}).forEach(([i,n])=>{Object.entries(n).forEach(([r,a])=>{this[a]=t.moduleInstances.API.methods[i][r]})})}}const Tt={header:Zt(()=>import("./bundle-7ca97fea.js").then(s=>s.b),["assets/bundle-7ca97fea.js","assets/app-front-d6902e40.js","assets/app-front-935fc652.css"]),list:Zt(()=>import("./bundle-f4b2cd77.js").then(s=>s.b),["assets/bundle-f4b2cd77.js","assets/app-front-d6902e40.js","assets/app-front-935fc652.css"])},Ii=Ne({name:"vue-editor-js",props:{holder:{type:String,default:()=>"vue-editor-js",require:!0},config:{type:Object,default:()=>({}),require:!0},initialized:{type:Function,default:()=>{}}},setup:(s,t)=>{const e=Re({editor:null});function o(r){i(),e.editor=new Si({holder:r.holder||"vue-editor-js",...r.config,onChange:(a,l)=>{n()}}),r.initialized(e.editor)}function i(){e.editor&&(e.editor.destroy(),e.editor=null)}function n(){console.log("saveEditor"),e.editor&&e.editor.save().then(r=>{console.log(r),t.emit("saved",r)})}return Pe(r=>o(s)),{props:s,state:e}},methods:{useTools(s,t){const e=Object.keys(Tt),o={...s.customTools};return e.every(i=>!s[i])?(e.forEach(i=>o[i]={class:Tt[i]}),Object.keys(t).forEach(i=>{o[i]!==void 0&&o[i]!==null&&(o[i].config=t[i])}),o):(e.forEach(i=>{const n=s[i];if(n&&(o[i]={class:Tt[i]},typeof n=="object")){const r=Object.assign({},s[i]);delete r.class,o[i]=Object.assign(o[i],r)}}),Object.keys(t).forEach(i=>{o[i]!==void 0&&o[i]!==null&&(o[i].config=t[i])}),o)}}}),Mi=["id"];function _i(s,t,e,o,i,n){return Fe(),De("div",{id:s.holder},null,8,Mi)}const Li=Oe(Ii,[["render",_i]]);export{Tt as PLUGINS,Li as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import{g as N}from"./app-front-ae9fe805.js";function P(x,H){for(var g=0;g<H.length;g++){const b=H[g];if(typeof b!="string"&&!Array.isArray(b)){for(const l in b)if(l!=="default"&&!(l in x)){const n=Object.getOwnPropertyDescriptor(b,l);n&&Object.defineProperty(x,l,n.get?n:{enumerable:!0,get:()=>b[l]})}}}return Object.freeze(Object.defineProperty(x,Symbol.toStringTag,{value:"Module"}))}var E={exports:{}};(function(x,H){(function(g,b){x.exports=b()})(window,function(){return function(g){var b={};function l(n){if(b[n])return b[n].exports;var i=b[n]={i:n,l:!1,exports:{}};return g[n].call(i.exports,i,i.exports,l),i.l=!0,i.exports}return l.m=g,l.c=b,l.d=function(n,i,h){l.o(n,i)||Object.defineProperty(n,i,{enumerable:!0,get:h})},l.r=function(n){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},l.t=function(n,i){if(1&i&&(n=l(n)),8&i||4&i&&typeof n=="object"&&n&&n.__esModule)return n;var h=Object.create(null);if(l.r(h),Object.defineProperty(h,"default",{enumerable:!0,value:n}),2&i&&typeof n!="string")for(var m in n)l.d(h,m,(function(f){return n[f]}).bind(null,m));return h},l.n=function(n){var i=n&&n.__esModule?function(){return n.default}:function(){return n};return l.d(i,"a",i),i},l.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},l.p="/",l(l.s=5)}([function(g,b,l){var n=l(1);typeof n=="string"&&(n=[[g.i,n,""]]);var i={hmr:!0,transform:void 0,insertInto:void 0};l(3)(n,i),n.locals&&(g.exports=n.locals)},function(g,b,l){(g.exports=l(2)(!1)).push([g.i,`/**
import{g as N}from"./app-front-d6902e40.js";function P(x,H){for(var g=0;g<H.length;g++){const b=H[g];if(typeof b!="string"&&!Array.isArray(b)){for(const l in b)if(l!=="default"&&!(l in x)){const n=Object.getOwnPropertyDescriptor(b,l);n&&Object.defineProperty(x,l,n.get?n:{enumerable:!0,get:()=>b[l]})}}}return Object.freeze(Object.defineProperty(x,Symbol.toStringTag,{value:"Module"}))}var E={exports:{}};(function(x,H){(function(g,b){x.exports=b()})(window,function(){return function(g){var b={};function l(n){if(b[n])return b[n].exports;var i=b[n]={i:n,l:!1,exports:{}};return g[n].call(i.exports,i,i.exports,l),i.l=!0,i.exports}return l.m=g,l.c=b,l.d=function(n,i,h){l.o(n,i)||Object.defineProperty(n,i,{enumerable:!0,get:h})},l.r=function(n){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},l.t=function(n,i){if(1&i&&(n=l(n)),8&i||4&i&&typeof n=="object"&&n&&n.__esModule)return n;var h=Object.create(null);if(l.r(h),Object.defineProperty(h,"default",{enumerable:!0,value:n}),2&i&&typeof n!="string")for(var m in n)l.d(h,m,(function(f){return n[f]}).bind(null,m));return h},l.n=function(n){var i=n&&n.__esModule?function(){return n.default}:function(){return n};return l.d(i,"a",i),i},l.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},l.p="/",l(l.s=5)}([function(g,b,l){var n=l(1);typeof n=="string"&&(n=[[g.i,n,""]]);var i={hmr:!0,transform:void 0,insertInto:void 0};l(3)(n,i),n.locals&&(g.exports=n.locals)},function(g,b,l){(g.exports=l(2)(!1)).push([g.i,`/**
* Plugin styles
*/
.ce-header {

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import{g as E}from"./app-front-ae9fe805.js";function P(_,j){for(var v=0;v<j.length;v++){const p=j[v];if(typeof p!="string"&&!Array.isArray(p)){for(const c in p)if(c!=="default"&&!(c in _)){const o=Object.getOwnPropertyDescriptor(p,c);o&&Object.defineProperty(_,c,o.get?o:{enumerable:!0,get:()=>p[c]})}}}return Object.freeze(Object.defineProperty(_,Symbol.toStringTag,{value:"Module"}))}var T={exports:{}};(function(_,j){(function(v,p){_.exports=p()})(window,function(){return function(v){var p={};function c(o){if(p[o])return p[o].exports;var l=p[o]={i:o,l:!1,exports:{}};return v[o].call(l.exports,l,l.exports,c),l.l=!0,l.exports}return c.m=v,c.c=p,c.d=function(o,l,d){c.o(o,l)||Object.defineProperty(o,l,{enumerable:!0,get:d})},c.r=function(o){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},c.t=function(o,l){if(1&l&&(o=c(o)),8&l||4&l&&typeof o=="object"&&o&&o.__esModule)return o;var d=Object.create(null);if(c.r(d),Object.defineProperty(d,"default",{enumerable:!0,value:o}),2&l&&typeof o!="string")for(var f in o)c.d(d,f,(function(b){return o[b]}).bind(null,f));return d},c.n=function(o){var l=o&&o.__esModule?function(){return o.default}:function(){return o};return c.d(l,"a",l),l},c.o=function(o,l){return Object.prototype.hasOwnProperty.call(o,l)},c.p="/",c(c.s=4)}([function(v,p,c){var o=c(1),l=c(2);typeof(l=l.__esModule?l.default:l)=="string"&&(l=[[v.i,l,""]]);var d={insert:"head",singleton:!1};o(l,d),v.exports=l.locals||{}},function(v,p,c){var o,l=function(){return o===void 0&&(o=!!(window&&document&&document.all&&!window.atob)),o},d=function(){var r={};return function(i){if(r[i]===void 0){var s=document.querySelector(i);if(window.HTMLIFrameElement&&s instanceof window.HTMLIFrameElement)try{s=s.contentDocument.head}catch{s=null}r[i]=s}return r[i]}}(),f=[];function b(r){for(var i=-1,s=0;s<f.length;s++)if(f[s].identifier===r){i=s;break}return i}function S(r,i){for(var s={},u=[],m=0;m<r.length;m++){var g=r[m],y=i.base?g[0]+i.base:g[0],C=s[y]||0,O="".concat(y," ").concat(C);s[y]=C+1;var L=b(O),M={css:g[1],media:g[2],sourceMap:g[3]};L!==-1?(f[L].references++,f[L].updater(M)):f.push({identifier:O,updater:h(M,i),references:1}),u.push(O)}return u}function k(r){var i=document.createElement("style"),s=r.attributes||{};if(s.nonce===void 0){var u=c.nc;u&&(s.nonce=u)}if(Object.keys(s).forEach(function(g){i.setAttribute(g,s[g])}),typeof r.insert=="function")r.insert(i);else{var m=d(r.insert||"head");if(!m)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");m.appendChild(i)}return i}var w,x=(w=[],function(r,i){return w[r]=i,w.filter(Boolean).join(`
import{g as E}from"./app-front-d6902e40.js";function P(_,j){for(var v=0;v<j.length;v++){const p=j[v];if(typeof p!="string"&&!Array.isArray(p)){for(const c in p)if(c!=="default"&&!(c in _)){const o=Object.getOwnPropertyDescriptor(p,c);o&&Object.defineProperty(_,c,o.get?o:{enumerable:!0,get:()=>p[c]})}}}return Object.freeze(Object.defineProperty(_,Symbol.toStringTag,{value:"Module"}))}var T={exports:{}};(function(_,j){(function(v,p){_.exports=p()})(window,function(){return function(v){var p={};function c(o){if(p[o])return p[o].exports;var l=p[o]={i:o,l:!1,exports:{}};return v[o].call(l.exports,l,l.exports,c),l.l=!0,l.exports}return c.m=v,c.c=p,c.d=function(o,l,d){c.o(o,l)||Object.defineProperty(o,l,{enumerable:!0,get:d})},c.r=function(o){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},c.t=function(o,l){if(1&l&&(o=c(o)),8&l||4&l&&typeof o=="object"&&o&&o.__esModule)return o;var d=Object.create(null);if(c.r(d),Object.defineProperty(d,"default",{enumerable:!0,value:o}),2&l&&typeof o!="string")for(var f in o)c.d(d,f,(function(b){return o[b]}).bind(null,f));return d},c.n=function(o){var l=o&&o.__esModule?function(){return o.default}:function(){return o};return c.d(l,"a",l),l},c.o=function(o,l){return Object.prototype.hasOwnProperty.call(o,l)},c.p="/",c(c.s=4)}([function(v,p,c){var o=c(1),l=c(2);typeof(l=l.__esModule?l.default:l)=="string"&&(l=[[v.i,l,""]]);var d={insert:"head",singleton:!1};o(l,d),v.exports=l.locals||{}},function(v,p,c){var o,l=function(){return o===void 0&&(o=!!(window&&document&&document.all&&!window.atob)),o},d=function(){var r={};return function(i){if(r[i]===void 0){var s=document.querySelector(i);if(window.HTMLIFrameElement&&s instanceof window.HTMLIFrameElement)try{s=s.contentDocument.head}catch{s=null}r[i]=s}return r[i]}}(),f=[];function b(r){for(var i=-1,s=0;s<f.length;s++)if(f[s].identifier===r){i=s;break}return i}function S(r,i){for(var s={},u=[],m=0;m<r.length;m++){var g=r[m],y=i.base?g[0]+i.base:g[0],C=s[y]||0,O="".concat(y," ").concat(C);s[y]=C+1;var L=b(O),M={css:g[1],media:g[2],sourceMap:g[3]};L!==-1?(f[L].references++,f[L].updater(M)):f.push({identifier:O,updater:h(M,i),references:1}),u.push(O)}return u}function k(r){var i=document.createElement("style"),s=r.attributes||{};if(s.nonce===void 0){var u=c.nc;u&&(s.nonce=u)}if(Object.keys(s).forEach(function(g){i.setAttribute(g,s[g])}),typeof r.insert=="function")r.insert(i);else{var m=d(r.insert||"head");if(!m)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");m.appendChild(i)}return i}var w,x=(w=[],function(r,i){return w[r]=i,w.filter(Boolean).join(`
`)});function a(r,i,s,u){var m=s?"":u.media?"@media ".concat(u.media," {").concat(u.css,"}"):u.css;if(r.styleSheet)r.styleSheet.cssText=x(i,m);else{var g=document.createTextNode(m),y=r.childNodes;y[i]&&r.removeChild(y[i]),y.length?r.insertBefore(g,y[i]):r.appendChild(g)}}function e(r,i,s){var u=s.css,m=s.media,g=s.sourceMap;if(m?r.setAttribute("media",m):r.removeAttribute("media"),g&&btoa&&(u+=`
/*# sourceMappingURL=data:application/json;base64,`.concat(btoa(unescape(encodeURIComponent(JSON.stringify(g))))," */")),r.styleSheet)r.styleSheet.cssText=u;else{for(;r.firstChild;)r.removeChild(r.firstChild);r.appendChild(document.createTextNode(u))}}var t=null,n=0;function h(r,i){var s,u,m;if(i.singleton){var g=n++;s=t||(t=k(i)),u=a.bind(null,s,g,!1),m=a.bind(null,s,g,!0)}else s=k(i),u=e.bind(null,s,i),m=function(){(function(y){if(y.parentNode===null)return!1;y.parentNode.removeChild(y)})(s)};return u(r),function(y){if(y){if(y.css===r.css&&y.media===r.media&&y.sourceMap===r.sourceMap)return;u(r=y)}else m()}}v.exports=function(r,i){(i=i||{}).singleton||typeof i.singleton=="boolean"||(i.singleton=l());var s=S(r=r||[],i);return function(u){if(u=u||[],Object.prototype.toString.call(u)==="[object Array]"){for(var m=0;m<s.length;m++){var g=b(s[m]);f[g].references--}for(var y=S(u,i),C=0;C<s.length;C++){var O=b(s[C]);f[O].references===0&&(f[O].updater(),f.splice(O,1))}s=y}}}},function(v,p,c){(p=c(3)(!1)).push([v.i,`.cdx-list {
margin: 0;

Binary file not shown.

View File

@@ -3,25 +3,25 @@
"file": "assets/NativeImageBlock-e3b0c442.css",
"src": "NativeImageBlock.css"
},
"_NativeImageBlock-a8b03c38.js": {
"_NativeImageBlock-3623204f.js": {
"css": [
"assets/NativeImageBlock-e3b0c442.css"
],
"file": "assets/NativeImageBlock-a8b03c38.js",
"file": "assets/NativeImageBlock-3623204f.js",
"imports": [
"resources/js/app-front.js"
],
"isDynamicEntry": true
},
"_bundle-72871e75.js": {
"file": "assets/bundle-72871e75.js",
"_bundle-7ca97fea.js": {
"file": "assets/bundle-7ca97fea.js",
"imports": [
"resources/js/app-front.js"
],
"isDynamicEntry": true
},
"_bundle-c20bcf97.js": {
"file": "assets/bundle-c20bcf97.js",
"_bundle-f4b2cd77.js": {
"file": "assets/bundle-f4b2cd77.js",
"imports": [
"resources/js/app-front.js"
],
@@ -45,16 +45,17 @@
],
"dynamicImports": [
"resources/js/vue/GetEmbedCode.vue",
"_NativeImageBlock-a8b03c38.js",
"_NativeImageBlock-3623204f.js",
"resources/js/vue/PostEditor.vue",
"resources/js/vue/ToastMessage.vue",
"resources/js/vue/VueEditorJs.vue"
],
"file": "assets/app-front-32dad050.js",
"file": "assets/app-front-d6902e40.js",
"isEntry": true,
"src": "resources/js/app-front.js"
},
"resources/js/vue/GetEmbedCode.vue": {
"file": "assets/GetEmbedCode-767c2709.js",
"file": "assets/GetEmbedCode-1d44bdf3.js",
"imports": [
"resources/js/app-front.js"
],
@@ -69,23 +70,31 @@
"css": [
"assets/PostEditor-8d534a4a.css"
],
"file": "assets/PostEditor-86a4f765.js",
"file": "assets/PostEditor-3a06f7cf.js",
"imports": [
"resources/js/vue/VueEditorJs.vue",
"_NativeImageBlock-a8b03c38.js",
"_bundle-c20bcf97.js",
"_bundle-72871e75.js",
"_NativeImageBlock-3623204f.js",
"_bundle-f4b2cd77.js",
"_bundle-7ca97fea.js",
"resources/js/app-front.js"
],
"isDynamicEntry": true,
"src": "resources/js/vue/PostEditor.vue"
},
"resources/js/vue/ToastMessage.vue": {
"file": "assets/ToastMessage-cef385bb.js",
"imports": [
"resources/js/app-front.js"
],
"isDynamicEntry": true,
"src": "resources/js/vue/ToastMessage.vue"
},
"resources/js/vue/VueEditorJs.vue": {
"dynamicImports": [
"_bundle-72871e75.js",
"_bundle-c20bcf97.js"
"_bundle-7ca97fea.js",
"_bundle-f4b2cd77.js"
],
"file": "assets/VueEditorJs-bbb0be71.js",
"file": "assets/VueEditorJs-c40f6d08.js",
"imports": [
"resources/js/app-front.js"
],

Binary file not shown.

View File

@@ -0,0 +1,57 @@
<template>
<div></div>
</template>
<script>
import { toast } from "vue3-toastify";
export default {
name: "ToastMessage",
mixins: [],
components: {},
props: ["type", "message", "timeout"],
data: () => ({}),
watch: {},
computed: {},
methods: {
triggerMounted() {
if (this.type == "error") {
toast(this.message, {
position: "bottom-center",
type: "error",
timeout: 3000,
closeOnClick: true,
pauseOnFocusLoss: true,
pauseOnHover: true,
draggable: true,
draggablePercent: 0.6,
showCloseButtonOnHover: false,
hideProgressBar: false,
closeButton: true,
icon: true,
rtl: false,
});
}
if (this.type == "success") {
toast(this.message, {
position: "bottom-center",
type: "success",
timeout: 3000,
closeOnClick: true,
pauseOnFocusLoss: true,
pauseOnHover: true,
draggable: true,
draggablePercent: 0.6,
showCloseButtonOnHover: false,
hideProgressBar: false,
closeButton: true,
icon: true,
rtl: false,
});
}
},
},
mounted() {
this.triggerMounted();
},
};
</script>
<style scoped></style>

File diff suppressed because one or more lines are too long

View File

@@ -32,6 +32,8 @@
<div id="app">
@include('front.partials.alerts')
@include('googletagmanager::body')
@include('front.layouts.navigation')

View File

@@ -1,7 +1,9 @@
<div class="container-fluid shadow-sm">
<header class="d-flex flex-wrap align-items-center justify-content-center py-2">
<div class="col-auto">
<header
class="d-grid d-lg-flex flex-wrap justify-content-center justify-content-lg-between py-2 text-center text-lg-start">
<div class="align-self-center">
<a href="{{ route('front.home') }}"
class="btn btn-link d-inline-flex text-decoration-none hover-grow text-center gap-2">
<img class="align-self-center" style="height:50px; width:auto;"
@@ -11,5 +13,11 @@ class="btn btn-link d-inline-flex text-decoration-none hover-grow text-center ga
</p>
</a>
</div>
<div class="align-self-center">
<a href="{{ route('front.submit-tool') }}">Submit your AI Tool <span
class="badge text-bg-primary text-white">FREE!</span></a>
</div>
</header>
</div>

View File

@@ -0,0 +1,9 @@
@if (session()->has('error'))
<toast-message :timeout="{{ session()->get('error')->timeout }}" type="error"
message="{{ session()->get('error')->message }}"></toast-message>
@endif
@if (session()->has('success'))
<toast-message :timeout="{{ session()->get('success')->timeout }}" type="success"
message="{{ session()->get('success')->message }}"></toast-message>
@endif

View File

@@ -0,0 +1,182 @@
@extends('front.layouts.app')
@section('content')
<div class="container-lg pt-3 mb-3">
<div class="row justify-content-center">
<div class="col-12 col-lg-9">
<div class="card shadow border-0">
<div class="card-body text-center">
<div class="mb-3">
<h1 class="fw-bold font-family-zilla-slab mb-0">Submit your AI Tool for free!</h1>
<small>Limited to first {{ $max_submissions }} approved submissions.
@if ($submissions_left < $max_submissions / 2)
<br> {{ $submitted_tool_count }} submissions received, {{ $submissions_left }} free
slots left
@endif
</small>
</div>
<p class="mb-3">Perks of a new AI tool directory: <span
class="bg-highlighter-pink py-1 px-2 fw-bold ">free tool submission!</span> We are grateful
for your initial support and we wish to reward our early adopters with AI tool submission at
<span class="bg-highlighter-yellow py-1 px-2 fw-bold">$0 charge.</span></p>
<p class="mb-3">
While our platform is still relatively new, we are commited to becoming one of the leading AI
tool directories online, focusing on inspring the businesses & consumers with innovative AI
tools.
</p>
<p class="mb-1 fw-bold">Note:</p>
<p class="mb-3">Only AI tool founders and related employees can use this form. We will verify your
submission based on a combination of provided information submitted in this form.</p>
<p class="mb-3">You should only submit a website landing page, mobile app store link, browser
extension link, or a product link in its' completed state. This is because our AI crawlers will
visit these page to extract meaningful information, and incomplete product will derail our AI
crawler.</p>
<p class="mb-3">Please do not submit multiple URL sources, or multiple emails of the same product.
Please submit fairly and responsibly.</p>
<p class="mb-3">Our AI crawler may produce inaccurate results. If that is the case, please contact
us via DM and we will correct it manually.</p>
<p class="mb-3">If your submission is rejected and is found to be an error, we probably may have
found some incorrect details during your submission in the first place. As such, your submission
slot is removed to make room for other AI tool submissions. You may resubmit your AI tool again
while the slots are still available.</p>
<p class="mb-3">Your AI tool may have already been identified by our crawler engine in the first
place. If that is the case, your submission is already pre-approved, and your submission slot
will be released to make room for other AI tool submissions.</p>
<p class="mb-3">You may/may not be notified by email when the tool is approved or rejected. We are
still looking for a cost-effective email provider. In the meantime, DM us to check your
submission.</p>
<p class="mb-3">It may take up to a few days for us to provide you with a response. Please be
patient and if we still have not resolve it, DM us.</p>
<p class="mb-3">DM <a target="_blank" href="https://x.com/charlestehio">@charlestehio</a> for
support here.</p>
<form action="{{ route('front.submit-tool.post') }}" method="POST">
@csrf
{{-- Submitted URL --}}
<div class="mb-3">
<label for="submitted_url" class="fw-bold form-label">Your AI tool URL</label>
<input type="text" class="form-control" id="submitted_url" name="submitted_url"
placeholder="e.g. https://myaitool.com" value="{{ old('submitted_url') }}" required>
</div>
{{-- Email --}}
<div class="mb-3">
<label for="email" class="form-label fw-bold">Official Email for your AI Tool</label>
<input type="email" class="form-control" id="email" name="email"
value="{{ old('email') }}" placeholder="e.g. johndoe@myaitool.com | myaitool@gmail.com"
required>
</div>
{{-- Social --}}
<div class="mb-3">
<label for="social" class="form-label fw-bold">Your Social Username</label>
<input type="text" class="form-control" id="social" name="social"
value="{{ old('social') }}" placeholder="e.g. @johndoemyaitool" required>
</div>
{{-- Social Type --}}
<div class="mb-3">
<label for="social_type" class="form-label fw-bold">Your Social Platform (e.g.
Twitter/X)</label>
<select class="form-select" id="social_type" name="social_type" required>
<option value="" disabled>Select Social Platform</option>
<option value="Reddit" {{ old('social_type') == 'Reddit' ? 'selected' : '' }}>Reddit
</option>
<option value="Instagram" {{ old('social_type') == 'Instagram' ? 'selected' : '' }}>
Instagram</option>
<option value="Twitter" {{ old('social_type') == 'Twitter' ? 'selected' : '' }}>
Twitter/X</option>
<option value="TikTok" {{ old('social_type') == 'TikTok' ? 'selected' : '' }}>TikTok
</option>
<option value="Twitch" {{ old('social_type') == 'Twitch' ? 'selected' : '' }}>Twitch
</option>
<option value="Facebook" {{ old('social_type') == 'Facebook' ? 'selected' : '' }}>
Facebook</option>
<option value="YouTube" {{ old('social_type') == 'YouTube' ? 'selected' : '' }}>
YouTube</option>
<option value="Tumblr" {{ old('social_type') == 'Tumblr' ? 'selected' : '' }}>Tumblr
</option>
<option value="Discord" {{ old('social_type') == 'Discord' ? 'selected' : '' }}>
Discord</option>
<option value="Substack" {{ old('social_type') == 'Substack' ? 'selected' : '' }}>
Substack</option>
<option value="Others" {{ old('social_type') == 'Others' ? 'selected' : '' }}>Others
</option>
</select>
</div>
{{-- Source Type --}}
<div class="mb-3">
<label for="source_type" class="form-label fw-bold">Where did you find us?</label>
<select class="form-select" id="source_type" name="source_type" required>
<option value="" disabled>Select a Platform</option>
<option value="Google" {{ old('source_type') == 'Google' ? 'selected' : '' }}>Google
</option>
<option value="Bing" {{ old('source_type') == 'Bing' ? 'selected' : '' }}>Bing
</option>
<option value="Yahoo" {{ old('source_type') == 'Yahoo' ? 'selected' : '' }}>Yahoo
</option>
<option value="Reddit" {{ old('source_type') == 'Reddit' ? 'selected' : '' }}>Reddit
</option>
<option value="Instagram" {{ old('source_type') == 'Instagram' ? 'selected' : '' }}>
Instagram</option>
<option value="Twitter" {{ old('source_type') == 'Twitter' ? 'selected' : '' }}>
Twitter</option>
<option value="TikTok" {{ old('source_type') == 'TikTok' ? 'selected' : '' }}>TikTok
</option>
<option value="Twitch" {{ old('source_type') == 'Twitch' ? 'selected' : '' }}>Twitch
</option>
<option value="Facebook" {{ old('source_type') == 'Facebook' ? 'selected' : '' }}>
Facebook</option>
<option value="YouTube" {{ old('source_type') == 'YouTube' ? 'selected' : '' }}>
YouTube</option>
<option value="Tumblr" {{ old('source_type') == 'Tumblr' ? 'selected' : '' }}>Tumblr
</option>
<option value="Discord" {{ old('source_type') == 'Discord' ? 'selected' : '' }}>
Discord</option>
<option value="Substack" {{ old('source_type') == 'Substack' ? 'selected' : '' }}>
Substack</option>
<option value="Others" {{ old('source_type') == 'Others" ' ? 'selected' : '' }}>
Others</option>
</select>
</div>
{{-- Source --}}
<div class="mb-3">
<label for="source" class="form-label fw-bold">Share us the link of where you find us
(Optional)</label>
<textarea class="form-control" id="source" name="source">{{ old('source') }}</textarea>
</div>
{{-- Comments --}}
<div class="mb-3">
<label for="comments" class="form-label fw-bold">Any Comments/Feedback/Bugs/Feature Request
(Optional)</label>
<textarea class="form-control" id="comments" name="comments">{{ old('comments') }}</textarea>
</div>
<button type="submit" class="btn btn-primary rounded-pill px-4 breathing-effect">Submit AI
Tool</button>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -65,6 +65,14 @@
});
Route::prefix('submit-ai-tool-for-free')->group(function () {
Route::get('/', [\App\Http\Controllers\Front\FrontSubmitToolController::class, 'index'])->name('front.submit-tool');
Route::post('/', [\App\Http\Controllers\Front\FrontSubmitToolController::class, 'post'])->name('front.submit-tool.post');
});
Route::get('/terms', [App\Http\Controllers\Front\FrontHomeController::class, 'terms'])->name('front.terms')->middleware('cacheResponse:2630000');
Route::get('/privacy', [App\Http\Controllers\Front\FrontHomeController::class, 'privacy'])->name('front.privacy')->middleware('cacheResponse:2630000');