main
Ilham Wara Nugroho 2026-07-21 15:18:09 +07:00
parent 8c0968e5c6
commit 56be7efdaf
49 changed files with 1638 additions and 615 deletions

View File

@ -22,6 +22,8 @@ public class HomeController : Controller
{ {
//memanggil data lokasi dari master DB Lokasi //memanggil data lokasi dari master DB Lokasi
ViewBag.lokasiHome = await db.Lokasi ViewBag.lokasiHome = await db.Lokasi
.Include(x => x.LokasiFauna)
.Include(x => x.LokasiTumbuhan)
.OrderByDescending(l => l.MsLokasiId) .OrderByDescending(l => l.MsLokasiId)
.Take(3) .Take(3)
.ToListAsync(); .ToListAsync();
@ -35,18 +37,23 @@ public class HomeController : Controller
.Take(4) .Take(4)
.ToListAsync(); .ToListAsync();
var model = new HomeViewModel ViewBag.TotalLokasi = await db.Lokasi.CountAsync();
{ ViewBag.TotalTumbuhan = await db.Tumbuhan.CountAsync();
Statistik = new StatistikHomeModel ViewBag.TotalFauna = await db.Fauna.CountAsync();
{ ViewBag.Total = (ViewBag.TotalTumbuhan+ViewBag.TotalFauna);
TotalLocations = 10,
TotalFlora = 50,
TotalFauna = 30,
TotalSpecies = 80
},
};
return View(model); // var model = new HomeViewModel
// {
// Statistik = new StatistikHomeModel
// {
// TotalLocations = 10,
// TotalFlora = 50,
// TotalFauna = 30,
// TotalSpecies = 80
// },
// };
return View();
} }
public IActionResult Privacy() public IActionResult Privacy()

View File

@ -2,6 +2,7 @@ using System.Diagnostics;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using kehati.Models.View; using kehati.Models.View;
using kehati.Database; using kehati.Database;
using kehati.Helpers;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -17,208 +18,21 @@ namespace kehati.Controllers
public async Task<IActionResult> Index(int page = 1) public async Task<IActionResult> Index(int page = 1)
{ {
ViewBag.lokasiHome = await Pagination.PaginateAsync( ViewBag.lokasiHome = await Pagination.PaginateAsync(
db.Lokasi.OrderByDescending(l => l.MsLokasiId), db.Lokasi
.Include(x => x.LokasiFauna)
.Include(x => x.LokasiTumbuhan)
.OrderByDescending(l => l.MsLokasiId),
page,12); page,12);
return View(); return View();
} }
public IActionResult Detail(string slug) public async Task<IActionResult> Detail(string slug)
{ {
ViewBag.Slug = slug; var decode = Custom.DecodeInt(slug);
var lokasi = new LokasiModel ViewBag.data = await db.Lokasi.FirstOrDefaultAsync(x => x.MsLokasiId == decode);
{ ViewBag.lokasiTumbuhan = await db.LokasiTumbuhan.Include(x => x.Tumbuhan).Where(x => x.MsLokasiId == decode).ToListAsync();
Slug = "tebet-eco-park", ViewBag.lokasiFauna = await db.LokasiFauna.Include(x => x.Fauna).Where(x => x.MsLokasiId == decode).ToListAsync();
Name = "Tebet Eco Park", return View();
Region = "Jakarta Selatan",
Area = "15.3 Ha",
FloraCount = 45,
FaunaCount = 20,
Total = 100,
Description = "Taman kota modern yang mengintegrasikan ekologi dan ruang publik. Rumah bagi puluhan jenis tanaman lokal serta berbagai burung dan serangga penyerbuk.",
Image = "loc-tebet.jpg"
};
var model = new HomeViewModel
{
Location = lokasi,
FeaturedSpesies = new List<SpesiesModel>
{
new()
{
Slug = "pohon-trembesi",
Type = "flora",
CommonName = "Pohon Trembesi",
ScientificName = "Samanea saman",
Description =
"Pohon peneduh raksasa dengan tajuk lebar menyerupai payung. Sangat efektif menyerap karbon dioksida sehingga banyak ditanam di ruang publik Jakarta.",
Habitat = "Tumbuh baik di dataran rendah tropis, tanah subur, sinar matahari penuh.",
ConservationStatus = "Aman",
Image = "sp-trembesi.jpg",
LocationSlugs = new List<string>
{
"tebet-eco-park",
"hutan-kota-gbk",
"taman-menteng"
}
},
new()
{
Slug= "pohon-beringin",
Type= "flora",
CommonName= "Pohon Beringin",
ScientificName= "Ficus benjamina",
Description=
"Pohon rindang dengan akar udara khas yang menjuntai. Simbol keteduhan dan sering dijumpai di taman kota serta ruang publik Jakarta.",
Habitat= "Iklim tropis, tanah lembab, tahan terhadap polusi udara perkotaan.",
ConservationStatus= "Aman",
Image= "sp-beringin.jpg",
LocationSlugs = new List<string>
{"hutan-kota-srengseng", "taman-menteng", "hutan-kota-gbk"}
},
new()
{
Slug= "mangrove-rhizophora",
Type= "flora",
CommonName= "Bakau Merah",
ScientificName= "Rhizophora mucronata",
Description=
"Tumbuhan bakau dengan akar tunjang khas. Berfungsi sebagai benteng alami pesisir Jakarta terhadap abrasi dan intrusi air laut.",
Habitat= "Kawasan pesisir berlumpur, muara sungai, air payau.",
ConservationStatus= "Dilindungi",
Image= "sp-mangrove.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
},
new()
{
Slug= "bunga-kamboja",
Type= "flora",
CommonName= "Kamboja Putih",
ScientificName= "Plumeria alba",
Description=
"Pohon hias berbunga harum dengan kelopak putih dan kuning di tengah. Populer di pekarangan dan taman kota.",
Habitat= "Daerah tropis kering, tanah berdrainase baik.",
ConservationStatus= "Aman",
Image= "sp-kamboja.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "taman-menteng"}
},
new()
{
Slug= "anggrek-bulan",
Type= "flora",
CommonName= "Anggrek Bulan",
ScientificName= "Phalaenopsis amabilis",
Description=
"Bunga nasional Indonesia (Puspa Pesona). Berkelopak lebar putih murni, tumbuh menempel pada batang pohon.",
Habitat= "Epifit pada pohon di hutan tropis lembab.",
ConservationStatus= "Rentan",
Image= "sp-anggrek.jpg",
LocationSlugs = new List<string>
{"hutan-kota-srengseng", "tebet-eco-park"}
},
new()
{
Slug= "bambu-kuning",
Type= "flora",
CommonName= "Bambu Kuning",
ScientificName= "Bambusa vulgaris",
Description=
"Rumpun bambu berbatang kuning cerah yang tumbuh cepat. Berperan penting menyerap air tanah dan mencegah erosi.",
Habitat= "Tanah lembab di tepi sungai, taman, dan hutan kota.",
ConservationStatus= "Aman",
Image= "sp-bambu.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "hutan-kota-srengseng"}
},
new()
{
Slug= "burung-kutilang",
Type= "fauna",
CommonName= "Burung Kutilang",
ScientificName= "Pycnonotus aurigaster",
Description=
"Burung pengicau kecil dengan tunggir kuning cerah. Salah satu burung liar paling umum di taman-taman Jakarta.",
Habitat= "Taman kota, pekarangan, hutan sekunder.",
ConservationStatus= "Aman",
Image= "sp-kutilang.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "taman-menteng", "hutan-kota-gbk"}
},
new()
{
Slug= "burung-madu-sriganti",
Type= "fauna",
CommonName= "Burung Madu Sriganti",
ScientificName= "Cinnyris jugularis",
Description=
"Burung kecil berwarna cerah, jantan berdada hitam berkilau. Penghisap nektar bunga di taman dan hutan kota.",
Habitat= "Taman berbunga, semak berbunga, pinggir hutan.",
ConservationStatus= "Dilindungi",
Image= "sp-madu-sriganti.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "hutan-kota-srengseng", "mangrove-pik"}
},
new()
{
Slug= "kupu-kupu-raja",
Type= "fauna",
CommonName= "Kupu-kupu Raja",
ScientificName= "Papilio memnon",
Description=
"Kupu-kupu besar berwarna hitam kebiruan dengan sayap lebar. Penyerbuk penting bagi berbagai tanaman berbunga.",
Habitat= "Taman berbunga, hutan sekunder, pinggir sungai.",
ConservationStatus= "Aman",
Image= "sp-kupu-kupu.jpg",
LocationSlugs = new List<string>
{"tebet-eco-park", "hutan-kota-srengseng"}
},
new()
{
Slug= "biawak-air",
Type= "fauna",
CommonName= "Biawak Air",
ScientificName= "Varanus salvator",
Description=
"Reptil besar semi-akuatik dengan lidah bercabang. Predator alami yang membantu mengendalikan populasi tikus di ekosistem kota.",
Habitat= "Rawa, sungai, hutan mangrove.",
ConservationStatus= "Dilindungi",
Image= "sp-biawak.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
},
new()
{
Slug= "monyet-ekor-panjang",
Type= "fauna",
CommonName= "Monyet Ekor Panjang",
ScientificName= "Macaca fascicularis",
Description=
"Primata berbulu abu-abu kecoklatan dengan ekor panjang. Hidup berkelompok di kawasan hutan yang tersisa.",
Habitat= "Hutan mangrove, hutan sekunder, tepi sungai.",
ConservationStatus= "Rentan",
Image= "sp-monyet.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
},
new()
{
Slug= "elang-bondol",
Type= "fauna",
CommonName= "Elang Bondol",
ScientificName= "Haliastur indus",
Description=
"Elang berkepala putih dengan tubuh coklat kemerahan. Maskot Provinsi DKI Jakarta dan simbol kekayaan hayati pesisir.",
Habitat= "Pesisir, mangrove, muara sungai.",
ConservationStatus= "Dilindungi",
Image= "sp-elang-bondol.jpg",
LocationSlugs = new List<string>
{"muara-angke", "mangrove-pik"}
}
}
};
return View(model);
} }
} }
} }

View File

@ -1,56 +1,27 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using kehati.Database;
using kehati.Models.View; using kehati.Models.View;
using Microsoft.EntityFrameworkCore;
namespace kehati.Controllers namespace kehati.Controllers
{ {
public class MapController : Controller public class MapController : Controller
{ {
public IActionResult Index() private readonly ApplicationDbContext db;
{
var model = new HomeViewModel
{
FeaturedLocations = new List<LokasiModel>
{
new()
{
Slug = "tebet-eco-park",
Name = "Tebet Eco Park",
Region = "Jakarta Selatan",
Area = "15.3 Ha",
Latitude = "-6.236993826064424",
Longitude = "106.85290802883573",
FloraCount = 45,
FaunaCount = 20,
Image = "loc-tebet.jpg"
},
new()
{
Slug = "hutan-kota-srengseng",
Name = "Hutan Kota Srengseng",
Image = "loc-srengseng.jpg",
Region = "Jakarta Barat",
Area = "15.3 Ha",
Latitude = "",
Longitude = "",
FloraCount = 45,
FaunaCount = 20
},
new() public MapController(ApplicationDbContext context)
{ {
Slug = "mangrove-angke", db = context;
Name = "Hutan Mangrove Angke",
Region = "Jakarta Barat",
Area = "15.3 Ha",
Latitude = "",
Longitude = "",
FloraCount = 45,
FaunaCount = 20,
Image = "loc-mangrove-pik.jpg"
} }
} public async Task<IActionResult> Index()
}; {
return View(model); ViewBag.lokasiHome = await db.Lokasi
.Where(x => x.Lat != null)
.Include(x => x.LokasiFauna)
.Include(x => x.LokasiTumbuhan)
.OrderByDescending(l => l.MsLokasiId)
.ToListAsync();
return View();
} }
public IActionResult Detail(string slug) public IActionResult Detail(string slug)

View File

@ -20,6 +20,7 @@ namespace kehati.Database
public DbSet<Group> Group { get; set; } public DbSet<Group> Group { get; set; }
public DbSet<Habitat> Habitat { get; set; } public DbSet<Habitat> Habitat { get; set; }
public DbSet<LokasiTumbuhan> LokasiTumbuhan { get; set; } public DbSet<LokasiTumbuhan> LokasiTumbuhan { get; set; }
public DbSet<LokasiFauna> LokasiFauna { get; set; }
public DbSet<Menu> Menu { get; set; } public DbSet<Menu> Menu { get; set; }
public DbSet<Tumbuhan> Tumbuhan { get; set; } public DbSet<Tumbuhan> Tumbuhan { get; set; }
public DbSet<Fauna> Fauna { get; set; } public DbSet<Fauna> Fauna { get; set; }

109
Helpers/Custom.cs 100644
View File

@ -0,0 +1,109 @@
namespace kehati.Helpers;
using System.Security.Cryptography;
using System.Text;
using kehati.Models.Common;
using Microsoft.EntityFrameworkCore;
public static class Custom
{
// Ganti dengan secret Anda sendiri
private const string Secret = "kehatiDINASLHDKI-2026";
private static byte[] GetKey()
{
return MD5.HashData(Encoding.UTF8.GetBytes(Secret));
}
private static byte[] GetIV()
{
byte[] sha = SHA1.HashData(Encoding.UTF8.GetBytes(Secret));
return sha.Take(16).ToArray();
}
public static string Encode(int value)
{
return Encode(value.ToString());
}
public static string Encode(string value)
{
string random = RandomString(4);
string text = random + value;
using var aes = Aes.Create();
aes.Key = GetKey();
aes.IV = GetIV();
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using var encryptor = aes.CreateEncryptor();
byte[] bytes = Encoding.UTF8.GetBytes(text);
byte[] encrypted = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);
string hex = Convert.ToHexString(encrypted).ToLower();
return FormatUuid(hex);
}
public static string Decode(string value)
{
value = value.Replace("-", "");
byte[] encrypted = Convert.FromHexString(value);
using var aes = Aes.Create();
aes.Key = GetKey();
aes.IV = GetIV();
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using var decryptor = aes.CreateDecryptor();
byte[] plain = decryptor.TransformFinalBlock(
encrypted,
0,
encrypted.Length);
string result = Encoding.UTF8.GetString(plain);
// Hilangkan random 4 karakter
return result.Substring(4);
}
public static int DecodeInt(string value)
{
return int.Parse(Decode(value));
}
private static string RandomString(int length)
{
const string chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Span<byte> bytes = stackalloc byte[length];
RandomNumberGenerator.Fill(bytes);
var sb = new StringBuilder(length);
foreach (byte b in bytes)
sb.Append(chars[b % chars.Length]);
return sb.ToString();
}
private static string FormatUuid(string hex)
{
return
$"{hex[..8]}-" +
$"{hex.Substring(8, 4)}-" +
$"{hex.Substring(12, 4)}-" +
$"{hex.Substring(16, 4)}-" +
$"{hex.Substring(20)}";
}
}

View File

@ -0,0 +1,362 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using kehati.Database;
#nullable disable
namespace kehati.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20260721071042_LokasiFauna")]
partial class LokasiFauna
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.1")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("kehati.Models.Entity.Master.Famili", b =>
{
b.Property<int>("MsFamiliId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFamiliId"));
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("MsFamiliId");
b.ToTable("ms_famili");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Fauna", b =>
{
b.Property<int>("MsFaunaId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFaunaId"));
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<string>("MsFamiliId")
.HasColumnType("text")
.HasColumnName("ms_famili_id");
b.Property<string>("MsHabitusId")
.HasColumnType("text")
.HasColumnName("ms_habitus_id");
b.Property<string>("NamaIlmiah")
.HasColumnType("text")
.HasColumnName("nama_ilmiah");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.HasKey("MsFaunaId");
b.ToTable("ms_fauna");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Group", b =>
{
b.Property<int>("MsGroupId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsGroupId"));
b.Property<string>("Alias")
.HasColumnType("text")
.HasColumnName("alias");
b.Property<int?>("CreatedBy")
.HasColumnType("integer")
.HasColumnName("created_by");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.Property<int?>("UpdatedBy")
.HasColumnType("integer")
.HasColumnName("updated_by");
b.HasKey("MsGroupId");
b.ToTable("ms_group");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Habitat", b =>
{
b.Property<int>("MsHabitusId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsHabitusId"));
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("MsHabitusId");
b.ToTable("ms_habitus");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Lokasi", b =>
{
b.Property<int>("MsLokasiId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsLokasiId"));
b.Property<string>("Area")
.HasColumnType("text")
.HasColumnName("area");
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<int?>("Kode")
.HasColumnType("integer")
.HasColumnName("kode");
b.Property<string>("Lat")
.HasColumnType("text")
.HasColumnName("lat");
b.Property<string>("Long")
.HasColumnType("text")
.HasColumnName("long");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Region")
.HasColumnType("text")
.HasColumnName("region");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.HasKey("MsLokasiId");
b.ToTable("ms_lokasi");
});
modelBuilder.Entity("kehati.Models.Entity.Master.LokasiTumbuhan", b =>
{
b.Property<int>("MsLokasiTumbuhanId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsLokasiTumbuhanId"));
b.Property<int>("MsLokasiId")
.HasColumnType("integer")
.HasColumnName("ms_lokasi_id");
b.Property<int>("MsTumbuhanId")
.HasColumnType("integer")
.HasColumnName("ms_tumbuhan_id");
b.HasKey("MsLokasiTumbuhanId");
b.HasIndex("MsLokasiId");
b.HasIndex("MsTumbuhanId");
b.ToTable("ms_lokasi_tumbuhan");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Menu", b =>
{
b.Property<int>("MsMenuId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsMenuId"));
b.Property<string>("MenuIcon")
.HasColumnType("text")
.HasColumnName("menu_icon");
b.Property<string>("MenuType")
.HasColumnType("text")
.HasColumnName("menu_type");
b.Property<string>("Module")
.HasColumnType("text")
.HasColumnName("module");
b.Property<string>("Ordering")
.HasColumnType("text")
.HasColumnName("ordering");
b.Property<int?>("ParentId")
.HasColumnType("integer")
.HasColumnName("parent_id");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.Property<string>("Title")
.HasColumnType("text")
.HasColumnName("title");
b.Property<string>("Url")
.HasColumnType("text")
.HasColumnName("url");
b.HasKey("MsMenuId");
b.ToTable("ms_menu");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Tumbuhan", b =>
{
b.Property<int>("MsTumbuhanId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsTumbuhanId"));
b.Property<string>("Cites")
.HasColumnType("text")
.HasColumnName("cites");
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<string>("Iucn")
.HasColumnType("text")
.HasColumnName("iucn");
b.Property<int>("MsFamiliId")
.HasColumnType("integer")
.HasColumnName("ms_famili_id");
b.Property<int>("MsHabitatId")
.HasColumnType("integer")
.HasColumnName("ms_habitus_id");
b.Property<string>("NamaIlmiah")
.HasColumnType("text")
.HasColumnName("name_ilmiah");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("StatusPerlindungan")
.HasColumnType("text")
.HasColumnName("status_perlindungan");
b.Property<bool>("TanamanKhasJakarta")
.HasColumnType("boolean")
.HasColumnName("tanaman_khas_jakarta");
b.HasKey("MsTumbuhanId");
b.ToTable("ms_tumbuhan");
});
modelBuilder.Entity("kehati.Models.Entity.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<int>("MsGroupId")
.HasColumnType("integer")
.HasColumnName("ms_group_id");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("users");
});
modelBuilder.Entity("kehati.Models.Entity.Master.LokasiTumbuhan", b =>
{
b.HasOne("kehati.Models.Entity.Master.Lokasi", "Lokasi")
.WithMany()
.HasForeignKey("MsLokasiId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("kehati.Models.Entity.Master.Tumbuhan", "Tumbuhan")
.WithMany()
.HasForeignKey("MsTumbuhanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Lokasi");
b.Navigation("Tumbuhan");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,47 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace kehati.Migrations
{
/// <inheritdoc />
public partial class LokasiFauna : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ms_lokasi_fauna",
columns: table => new
{
MsLokasiFaunaId = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ms_lokasi_id = table.Column<int>(type: "integer", nullable: false),
ms_fauna_id = table.Column<int>(type: "integer", nullable: false),
created_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
updated_at = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
},
constraints: table =>
{
table.PrimaryKey("PK_MsLokasiFaunaId", x => x.MsLokasiFaunaId);
table.ForeignKey(
name: "FK_LokasiId",
column: x => x.ms_lokasi_id,
principalTable: "ms_lokasi",
principalColumn: "MsLokasiId");
table.ForeignKey(
name: "FK_FaunaId",
column: x => x.ms_fauna_id,
principalTable: "ms_fauna",
principalColumn: "MsFaunaId");
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -30,14 +30,55 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFamiliId")); NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFamiliId"));
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("name");
b.HasKey("MsFamiliId"); b.HasKey("MsFamiliId");
b.ToTable("ms_famili"); b.ToTable("ms_famili");
}); });
modelBuilder.Entity("kehati.Models.Entity.Master.Fauna", b =>
{
b.Property<int>("MsFaunaId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsFaunaId"));
b.Property<string>("Image")
.HasColumnType("text")
.HasColumnName("image");
b.Property<string>("MsFamiliId")
.HasColumnType("text")
.HasColumnName("ms_famili_id");
b.Property<string>("MsHabitusId")
.HasColumnType("text")
.HasColumnName("ms_habitus_id");
b.Property<string>("NamaIlmiah")
.HasColumnType("text")
.HasColumnName("nama_ilmiah");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.Property<string>("Slug")
.HasColumnType("text")
.HasColumnName("slug");
b.Property<string>("Status")
.HasColumnType("text")
.HasColumnName("status");
b.HasKey("MsFaunaId");
b.ToTable("ms_fauna");
});
modelBuilder.Entity("kehati.Models.Entity.Master.Group", b => modelBuilder.Entity("kehati.Models.Entity.Master.Group", b =>
{ {
b.Property<int>("MsGroupId") b.Property<int>("MsGroupId")
@ -47,22 +88,24 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsGroupId")); NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsGroupId"));
b.Property<string>("Alias") b.Property<string>("Alias")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("alias");
b.Property<int>("CreatedBy") b.Property<int?>("CreatedBy")
.HasColumnType("integer"); .HasColumnType("integer")
.HasColumnName("created_by");
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("name");
b.Property<string>("Status") b.Property<string>("Status")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("status");
b.Property<int>("UpdatedBy") b.Property<int?>("UpdatedBy")
.HasColumnType("integer"); .HasColumnType("integer")
.HasColumnName("updated_by");
b.HasKey("MsGroupId"); b.HasKey("MsGroupId");
@ -78,8 +121,8 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsHabitusId")); NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsHabitusId"));
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("name");
b.HasKey("MsHabitusId"); b.HasKey("MsHabitusId");
@ -106,6 +149,14 @@ namespace kehati.Migrations
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("kode"); .HasColumnName("kode");
b.Property<string>("Lat")
.HasColumnType("text")
.HasColumnName("lat");
b.Property<string>("Long")
.HasColumnType("text")
.HasColumnName("long");
b.Property<string>("Name") b.Property<string>("Name")
.IsRequired() .IsRequired()
.HasColumnType("text") .HasColumnType("text")
@ -146,6 +197,10 @@ namespace kehati.Migrations
b.HasKey("MsLokasiTumbuhanId"); b.HasKey("MsLokasiTumbuhanId");
b.HasIndex("MsLokasiId");
b.HasIndex("MsTumbuhanId");
b.ToTable("ms_lokasi_tumbuhan"); b.ToTable("ms_lokasi_tumbuhan");
}); });
@ -158,38 +213,36 @@ namespace kehati.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsMenuId")); NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("MsMenuId"));
b.Property<string>("MenuIcon") b.Property<string>("MenuIcon")
.IsRequired()
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("menu_icon"); .HasColumnName("menu_icon");
b.Property<string>("MenuType") b.Property<string>("MenuType")
.IsRequired()
.HasColumnType("text") .HasColumnType("text")
.HasColumnName("menu_type"); .HasColumnName("menu_type");
b.Property<string>("Module") b.Property<string>("Module")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("module");
b.Property<string>("Ordering") b.Property<string>("Ordering")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("ordering");
b.Property<int>("ParentId") b.Property<int?>("ParentId")
.HasColumnType("integer") .HasColumnType("integer")
.HasColumnName("parent_id"); .HasColumnName("parent_id");
b.Property<string>("Status") b.Property<string>("Status")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("status");
b.Property<string>("Title") b.Property<string>("Title")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("title");
b.Property<string>("Url") b.Property<string>("Url")
.IsRequired() .HasColumnType("text")
.HasColumnType("text"); .HasColumnName("url");
b.HasKey("MsMenuId"); b.HasKey("MsMenuId");
@ -281,6 +334,25 @@ namespace kehati.Migrations
b.ToTable("users"); b.ToTable("users");
}); });
modelBuilder.Entity("kehati.Models.Entity.Master.LokasiTumbuhan", b =>
{
b.HasOne("kehati.Models.Entity.Master.Lokasi", "Lokasi")
.WithMany()
.HasForeignKey("MsLokasiId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("kehati.Models.Entity.Master.Tumbuhan", "Tumbuhan")
.WithMany()
.HasForeignKey("MsTumbuhanId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Lokasi");
b.Navigation("Tumbuhan");
});
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }

View File

@ -21,4 +21,13 @@ public class Lokasi
public string? Region { get; set; } = ""; public string? Region { get; set; } = "";
[Column("area")] [Column("area")]
public string? Area { get; set; } = ""; public string? Area { get; set; } = "";
[Column("lat")]
public string? Lat { get; set; } = "";
[Column("long")]
public string? Long { get; set; } = "";
public ICollection<LokasiTumbuhan> LokasiTumbuhan { get; set; } = new List<LokasiTumbuhan>();
public ICollection<LokasiFauna> LokasiFauna { get; set; } = new List<LokasiFauna>();
} }

View File

@ -0,0 +1,23 @@
namespace kehati.Models.Entity.Master;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
[Table("ms_lokasi_fauna")]
public class LokasiFauna
{
[Key]
public int MsLokasiFaunaId { get; set; }
[Column("ms_fauna_id")]
public int MsFaunaId { get; set; }
[Column("ms_lokasi_id")]
public int MsLokasiId { get; set; }
//contoh untuk one to many
// public ICollection<Tumbuhan> Tumbuhan { get; set; } = new List<Tumbuhan>();
//ini one to one
[ForeignKey(nameof(MsFaunaId))]
public Fauna Fauna { get; set; } = null!;
[ForeignKey(nameof(MsLokasiId))]
public Lokasi Lokasi { get; set; } = null!;
}

View File

@ -10,4 +10,14 @@ public class LokasiTumbuhan
public int MsTumbuhanId { get; set; } public int MsTumbuhanId { get; set; }
[Column("ms_lokasi_id")] [Column("ms_lokasi_id")]
public int MsLokasiId { get; set; } public int MsLokasiId { get; set; }
//contoh untuk one to many
// public ICollection<Tumbuhan> Tumbuhan { get; set; } = new List<Tumbuhan>();
//ini one to one
[ForeignKey(nameof(MsTumbuhanId))]
public Tumbuhan Tumbuhan { get; set; } = null!;
[ForeignKey(nameof(MsLokasiId))]
public Lokasi Lokasi { get; set; } = null!;
} }

View File

@ -1,3 +1,4 @@
@using kehati.Helpers
@using kehati.Models.View @using kehati.Models.View
@using kehati.Models.Entity.Master @using kehati.Models.Entity.Master
@using kehati.Models.Common @using kehati.Models.Common
@ -20,7 +21,7 @@
Katalog Katalog
</div> </div>
<h1 class="mt-3 font-serif text-5xl leading-tight text-foreground"> <h1 class="mt-3 font-serif text-5xl leading-tight text-foreground">
Flora &amp; Fauna Jakarta Fauna Jakarta
</h1> </h1>
<p class="mt-4 text-lg text-muted-foreground"> <p class="mt-4 text-lg text-muted-foreground">
Telusuri spesies yang terdokumentasi di kawasan konservasi Jakarta. Telusuri spesies yang terdokumentasi di kawasan konservasi Jakarta.
@ -84,8 +85,7 @@
{ {
<a asp-controller="katalog" <a asp-controller="katalog"
asp-action="detail" asp-action="detail"
asp-route-slug="@s.Slug" asp-route-slug="@Custom.Encode(s.MsFaunaId)" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted"> <div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image" <img src="~/images/@s.Image"

View File

@ -1,6 +1,7 @@
@using kehati.Models.View @using kehati.Models.View
@using kehati.Models.Entity.Master @using kehati.Models.Entity.Master
@using kehati.Models.Common @using kehati.Models.Common
@using kehati.Helpers
@{ @{
ViewData["Title"] = "Katalog"; ViewData["Title"] = "Katalog";
var tumbuhan = ViewBag.tumbuhanHome as PagedResult<Tumbuhan>; var tumbuhan = ViewBag.tumbuhanHome as PagedResult<Tumbuhan>;
@ -84,7 +85,7 @@
{ {
<a asp-controller="katalog" <a asp-controller="katalog"
asp-action="detail" asp-action="detail"
asp-route-slug="@s.Slug" asp-route-slug="@Custom.Encode(s.MsTumbuhanId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg"> class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted"> <div class="relative aspect-[4/3] overflow-hidden bg-muted">

View File

@ -1,4 +1,5 @@
@using kehati.Models.View @using kehati.Models.View
@using kehati.Helpers
@{ @{
ViewData["Title"] = "Beranda"; ViewData["Title"] = "Beranda";
var statusColor = new Dictionary<string, string> var statusColor = new Dictionary<string, string>
@ -52,11 +53,11 @@
Jelajahi Lokasi Jelajahi Lokasi
<i data-lucide="arrow-right" class="h-4 w-4"></i> <i data-lucide="arrow-right" class="h-4 w-4"></i>
</a> </a>
<a asp-controller="katalog" @* <a asp-controller="katalog"
asp-action="Index" asp-action="Index"
class="inline-flex items-center gap-2 rounded-lg border border-border bg-background/80 px-5 py-3 text-sm font-medium text-foreground backdrop-blur transition-colors hover:bg-secondary"> class="inline-flex items-center gap-2 rounded-lg border border-border bg-background/80 px-5 py-3 text-sm font-medium text-foreground backdrop-blur transition-colors hover:bg-secondary">
Lihat Katalog Lihat Katalog
</a> </a> *@
</div> </div>
</div> </div>
</div> </div>
@ -65,38 +66,38 @@
<!-- STATISTIK SECTION --> <!-- STATISTIK SECTION -->
<section class="border-y border-border/60 bg-secondary/30"> <section class="border-y border-border/60 bg-secondary/30">
<div class="mx-auto grid max-w-7xl grid-cols-2 divide-x divide-border/60 px-4 sm:px-6 lg:grid-cols-4 lg:px-8"> <div class="mx-auto grid max-w-7xl grid-cols-2 divide-x divide-border/60 px-4 sm:px-6 lg:grid-cols-4 lg:px-8">
@{
var stats = new[]
{
new {
Label = "Lokasi Konservasi",
Value = @Model.Statistik.TotalLocations
},
new {
Label = "Jenis Flora",
Value = @Model.Statistik.TotalFlora
},
new {
Label = "Jenis Fauna",
Value = @Model.Statistik.TotalFauna
},
new {
Label = "Total Spesies",
Value = @Model.Statistik.TotalSpecies
}
};
}
@foreach (var item in stats)
{
<div class="px-4 py-8 text-center sm:py-10"> <div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl"> <div class="font-serif text-4xl text-primary sm:text-5xl">
@item.Value @ViewBag.TotalLokasi
</div> </div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground"> <div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
@item.Label Lokasi Konservasi
</div>
</div>
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@ViewBag.TotalTumbuhan
</div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
Jenis Flora
</div>
</div>
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@ViewBag.TotalFauna
</div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
Jenis Fauna
</div>
</div>
<div class="px-4 py-8 text-center sm:py-10">
<div class="font-serif text-4xl text-primary sm:text-5xl">
@ViewBag.Total
</div>
<div class="mt-2 text-xs uppercase tracking-widest text-muted-foreground">
Total Spesies
</div> </div>
</div> </div>
}
</div> </div>
</section> </section>
@ -141,7 +142,7 @@
Habitat di jantung Jakarta Habitat di jantung Jakarta
</h2> </h2>
</div> </div>
<a asp-controller="LokasiModel" <a asp-controller="lokasi"
asp-action="Index" asp-action="Index"
class="hidden shrink-0 items-center gap-1.5 text-sm font-medium text-primary hover:underline sm:inline-flex"> class="hidden shrink-0 items-center gap-1.5 text-sm font-medium text-primary hover:underline sm:inline-flex">
Semua lokasi Semua lokasi
@ -153,7 +154,7 @@
{ {
<a asp-controller="lokasi" <a asp-controller="lokasi"
asp-action="detail" asp-action="detail"
asp-route-slug="@loc.Slug" asp-route-slug="@Custom.Encode(loc.MsLokasiId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg"> class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[16/10] overflow-hidden bg-muted"> <div class="relative aspect-[16/10] overflow-hidden bg-muted">
@ -184,12 +185,12 @@
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<i data-lucide="leaf" <i data-lucide="leaf"
class="h-4 w-4 text-primary"></i> class="h-4 w-4 text-primary"></i>
12 Flora @loc.LokasiTumbuhan.Count Flora
</span> </span>
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<i data-lucide="bird" <i data-lucide="bird"
class="h-4 w-4 text-primary"></i> class="h-4 w-4 text-primary"></i>
12 Fauna @loc.LokasiFauna.Count Fauna
</span> </span>
</div> </div>
</div> </div>
@ -224,7 +225,7 @@
{ {
<a asp-controller="flora" <a asp-controller="flora"
asp-action="detail" asp-action="detail"
asp-route-slug="@s.Slug" asp-route-slug="@Custom.Encode(s.MsTumbuhanId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg"> class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted"> <div class="relative aspect-[4/3] overflow-hidden bg-muted">
@ -236,15 +237,7 @@
<!-- Type Badge --> <!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur"> <div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@* @if(s.Type == "Flora") *@
@* { *@
<i data-lucide="leaf" class="h-3 w-3"></i> <i data-lucide="leaf" class="h-3 w-3"></i>
@* } *@
@* else *@
@* { *@
@* <i data-lucide="bird" class="h-3 w-3"></i> *@
@* } *@
@* @s.Cites *@
</div> </div>
</div> </div>
<!-- Content --> <!-- Content -->
@ -302,7 +295,7 @@
{ {
<a asp-controller="fauna" <a asp-controller="fauna"
asp-action="detail" asp-action="detail"
asp-route-slug="@s.Slug" asp-route-slug="@Custom.Encode(s.MsFaunaId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg"> class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted"> <div class="relative aspect-[4/3] overflow-hidden bg-muted">
@ -314,15 +307,7 @@
<!-- Type Badge --> <!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur"> <div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@* @if(s.Type == "Flora") *@ <i data-lucide="bird" class="h-3 w-3"></i>
@* { *@
<i data-lucide="leaf" class="h-3 w-3"></i>
@* } *@
@* else *@
@* { *@
@* <i data-lucide="bird" class="h-3 w-3"></i> *@
@* } *@
@* @s.Cites *@
</div> </div>
</div> </div>
<!-- Content --> <!-- Content -->

View File

@ -9,14 +9,11 @@
{ "Kritis", "bg-red-100 text-red-800 border-red-200" }, { "Kritis", "bg-red-100 text-red-800 border-red-200" },
{ "Dilindungi", "bg-emerald-100 text-emerald-800 border-emerald-200" } { "Dilindungi", "bg-emerald-100 text-emerald-800 border-emerald-200" }
}; };
@model kehati.Models.View.HomeViewModel
var flora = Model.FeaturedSpesies.Where(x => x.Type == "flora").ToList();
var fauna = Model.FeaturedSpesies.Where(x => x.Type == "fauna").ToList();
} }
<div> <div>
<div class="relative h-[45vh] min-h-[320px] overflow-hidden"> <div class="relative h-[45vh] min-h-[320px] overflow-hidden">
<img src="~/images/@Model.Location.Image" asp-append-version="true" alt="@Model.Location.Name" class="h-full w-full object-cover"/> <img src="~/images/@ViewBag.data.Image" asp-append-version="true" alt="@ViewBag.data.Name" class="h-full w-full object-cover"/>
<div class="absolute inset-0 bg-gradient-to-t from-background via-background/40 to-background/10"></div> <div class="absolute inset-0 bg-gradient-to-t from-background via-background/40 to-background/10"></div>
</div> </div>
</div> </div>
@ -30,25 +27,25 @@
Semua lokasi Semua lokasi
</a> </a>
<h1 class="mt-4 font-serif text-4xl leading-tight text-foreground sm:text-5xl"> <h1 class="mt-4 font-serif text-4xl leading-tight text-foreground sm:text-5xl">
@Model.Location.Name @ViewBag.data.Name
</h1> </h1>
<div class="mt-4 flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground"> <div class="mt-4 flex flex-wrap gap-x-6 gap-y-2 text-sm text-muted-foreground">
<span class="inline-flex items-center gap-1.5"> <span class="inline-flex items-center gap-1.5">
<i data-lucide="map-pin" class="h-4 w-4 text-primary"></i> <i data-lucide="map-pin" class="h-4 w-4 text-primary"></i>
@Model.Location.Region @ViewBag.data.Region
</span> </span>
<span class="inline-flex items-center gap-1.5"> <span class="inline-flex items-center gap-1.5">
<i data-lucide="ruler" class="h-4 w-4 text-primary"></i> <i data-lucide="ruler" class="h-4 w-4 text-primary"></i>
@Model.Location.Area @ViewBag.data.Area
</span> </span>
</div> </div>
<p class="mt-6 max-w-3xl text-base leading-relaxed text-muted-foreground"> <p class="mt-6 max-w-3xl text-base leading-relaxed text-muted-foreground">
@Model.Location.Description Lorem ipsum dolor sit amet consectetur adipisicing elit. Maiores, praesentium at. Asperiores quasi explicabo, reiciendis ut nulla distinctio numquam labore dignissimos enim quisquam error et deleniti corrupti possimus nihil! Libero?
</p> </p>
<div class="mt-6 flex gap-8 text-sm"> <div class="mt-6 flex gap-8 text-sm">
<div> <div>
<div class="font-serif text-3xl text-primary"> <div class="font-serif text-3xl text-primary">
@Model.Location.FloraCount @ViewBag.lokasiTumbuhan.Count
</div> </div>
<div class="text-xs uppercase tracking-widest text-muted-foreground"> <div class="text-xs uppercase tracking-widest text-muted-foreground">
Flora Flora
@ -56,7 +53,7 @@
</div> </div>
<div> <div>
<div class="font-serif text-3xl text-primary"> <div class="font-serif text-3xl text-primary">
@Model.Location.FaunaCount @ViewBag.lokasiFauna.Count
</div> </div>
<div class="text-xs uppercase tracking-widest text-muted-foreground"> <div class="text-xs uppercase tracking-widest text-muted-foreground">
Fauna Fauna
@ -69,116 +66,46 @@
<div class="mx-auto max-w-5xl px-4 py-16 sm:px-6 lg:px-8"> <div class="mx-auto max-w-5xl px-4 py-16 sm:px-6 lg:px-8">
<div class="flex flex-wrap gap-3"> <div class="flex flex-wrap gap-3">
<button class="tab-btn active" data-tab="all"> <button class="tab-btn hover:cursor-pointer" data-tab="flora">
Semua (@Model.FeaturedSpesies.Count) Flora (@ViewBag.lokasiTumbuhan.Count)
</button> </button>
<button class="tab-btn" data-tab="flora"> <button class="tab-btn hover:cursor-pointer" data-tab="fauna">
Flora (@flora.Count) Fauna (@ViewBag.lokasiFauna.Count)
</button>
<button class="tab-btn" data-tab="fauna">
Fauna (@fauna.Count)
</button> </button>
</div> </div>
<div id="tab-all" class="tab-content mt-8"> <div id="tab-flora" class="tab-content mt-8">
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
@foreach(SpesiesModel s in Model.FeaturedSpesies) @foreach(var s in ViewBag.lokasiTumbuhan)
{ {
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg"> <a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Tumbuhan.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted"> <div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image" <img src="~/images/@s.Tumbuhan.Image"
alt="@s.CommonName" alt="@s.Tumbuhan.Name"
loading="lazy" loading="lazy"
asp-append-version="true" asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" /> class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@if(s.Type == "Flora")
{
<i data-lucide="leaf" class="h-3 w-3"></i>
}
else
{
<i data-lucide="bird" class="h-3 w-3"></i>
}
@s.Type
</div>
</div> </div>
<!-- Content --> <!-- Content -->
<div class="p-4"> <div class="p-4">
<div class="flex items-start justify-between gap-2"> <div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground"> <h3 class="font-serif text-lg leading-tight text-foreground">
@s.CommonName @s.Tumbuhan.Name
</h3> </h3>
</div> </div>
<p class="mt-0.5 text-xs italic text-muted-foreground"> <p class="mt-0.5 text-xs italic text-muted-foreground">
@s.ScientificName @s.Tumbuhan.NamaIlmiah
</p> </p>
<!-- Status Badge --> <!-- Status Badge -->
<div class="mt-3"> <div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium <span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.ConservationStatus) @(statusColor.ContainsKey(s.Tumbuhan.StatusPerlindungan)
? statusColor[s.ConservationStatus] ? statusColor[s.Tumbuhan.StatusPerlindungan]
: "")"> : "")">
@s.ConservationStatus @s.Tumbuhan.StatusPerlindungan
</span>
</div>
</div>
</a>
}
</div>
</div>
<div id="tab-flora" class="tab-content mt-8 hidden">
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
@foreach(var s in flora)
{
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image"
alt="@s.CommonName"
loading="lazy"
asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@if(s.Type == "Flora")
{
<i data-lucide="leaf" class="h-3 w-3"></i>
}
else
{
<i data-lucide="bird" class="h-3 w-3"></i>
}
@s.Type
</div>
</div>
<!-- Content -->
<div class="p-4">
<div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground">
@s.CommonName
</h3>
</div>
<p class="mt-0.5 text-xs italic text-muted-foreground">
@s.ScientificName
</p>
<!-- Status Badge -->
<div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.ConservationStatus)
? statusColor[s.ConservationStatus]
: "")">
@s.ConservationStatus
</span> </span>
</div> </div>
</div> </div>
@ -193,47 +120,39 @@
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3"> <div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
@foreach(SpesiesModel s in fauna) @foreach(var s in ViewBag.lokasiFauna)
{ {
<a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg"> <a asp-controller="katalog" asp-action="detail" asp-route-slug="@s.Fauna.Slug" class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[4/3] overflow-hidden bg-muted"> <div class="relative aspect-[4/3] overflow-hidden bg-muted">
<img src="~/images/@s.Image" <img src="~/images/@s.Fauna.Image"
alt="@s.CommonName" alt="@s.Fauna.Name"
loading="lazy" loading="lazy"
asp-append-version="true" asp-append-version="true"
class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" /> class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" />
<!-- Type Badge --> <!-- Type Badge -->
<div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur"> <div class="absolute left-3 top-3 flex items-center gap-1.5 rounded-full bg-background/90 px-2.5 py-1 text-[11px] font-medium capitalize backdrop-blur">
@if(s.Type == "Flora") <i data-lucide="bird" class="h-3 w-3"></i> Fauna
{
<i data-lucide="leaf" class="h-3 w-3"></i>
}
else
{
<i data-lucide="bird" class="h-3 w-3"></i>
}
@s.Type
</div> </div>
</div> </div>
<!-- Content --> <!-- Content -->
<div class="p-4"> <div class="p-4">
<div class="flex items-start justify-between gap-2"> <div class="flex items-start justify-between gap-2">
<h3 class="font-serif text-lg leading-tight text-foreground"> <h3 class="font-serif text-lg leading-tight text-foreground">
@s.CommonName @s.Fauna.Name
</h3> </h3>
</div> </div>
<p class="mt-0.5 text-xs italic text-muted-foreground"> <p class="mt-0.5 text-xs italic text-muted-foreground">
@s.ScientificName @s.Fauna.NamaIlmiah
</p> </p>
<!-- Status Badge --> <!-- Status Badge -->
<div class="mt-3"> <div class="mt-3">
<span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium <span class="inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-medium
@(statusColor.ContainsKey(s.ConservationStatus) @(statusColor.ContainsKey(s.Fauna.Status)
? statusColor[s.ConservationStatus] ? statusColor[s.Fauna.Status]
: "")"> : "")">
@s.ConservationStatus @s.Fauna.Status
</span> </span>
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
@using kehati.Models.View @using kehati.Models.View
@using kehati.Models.Entity.Master @using kehati.Models.Entity.Master
@using kehati.Models.Common @using kehati.Models.Common
@using kehati.Helpers
@{ @{
ViewData["Title"] = "Lokasi"; ViewData["Title"] = "Lokasi";
@ -27,7 +28,7 @@
{ {
<a asp-controller="lokasi" <a asp-controller="lokasi"
asp-action="detail" asp-action="detail"
asp-route-slug="@loc.Slug" asp-route-slug="@Custom.Encode(loc.MsLokasiId)"
class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg"> class="group block overflow-hidden rounded-2xl border border-border bg-card transition-all hover:-translate-y-1 hover:shadow-lg">
<!-- Image --> <!-- Image -->
<div class="relative aspect-[16/10] overflow-hidden bg-muted"> <div class="relative aspect-[16/10] overflow-hidden bg-muted">
@ -58,12 +59,12 @@
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<i data-lucide="leaf" <i data-lucide="leaf"
class="h-4 w-4 text-primary"></i> class="h-4 w-4 text-primary"></i>
12 Flora @loc.LokasiTumbuhan.Count Flora
</span> </span>
<span class="flex items-center gap-1"> <span class="flex items-center gap-1">
<i data-lucide="bird" <i data-lucide="bird"
class="h-4 w-4 text-primary"></i> class="h-4 w-4 text-primary"></i>
13 Fauna @loc.LokasiFauna.Count Fauna
</span> </span>
</div> </div>
</div> </div>

View File

@ -1,52 +1,23 @@
@using kehati.Models.View @using kehati.Models.View
@using kehati.Helpers
@{ @{
ViewData["Title"] = "Map"; ViewData["Title"] = "Map";
} }
<div class="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8"> <div class="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8">
<div class="max-w-2xl"> <div class="max-w-2xl">
<div class="text-xs font-medium uppercase tracking-widest text-primary"> <div class="text-xs font-medium uppercase tracking-widest text-primary">
Peta Interaktif Peta Interaktif
</div> </div>
<h1 class="mt-3 font-serif text-5xl leading-tight text-foreground"> <h1 class="mt-3 font-serif text-5xl leading-tight text-foreground">
Sebaran Lokasi Konservasi Sebaran Lokasi Konservasi
</h1> </h1>
<p class="mt-4 text-lg text-muted-foreground"> <p class="mt-4 text-lg text-muted-foreground">
Titik-titik hijau di peta Jakarta. Klik setiap penanda untuk melihat detail lokasi. Titik-titik hijau di peta Jakarta. Klik setiap penanda untuk melihat detail lokasi.
</p> </p>
</div> </div>
<!-- Leaflet --> <!-- Leaflet -->
<div class="mt-10 overflow-hidden rounded-2xl border border-border shadow-sm"> <div class="mt-10 overflow-hidden rounded-2xl border border-border shadow-sm">
<div id="map" class="h-[600px] w-full"></div> <div id="map" class="h-[600px] w-full"></div>
</div>
<!-- Daftar Lokasi -->
<div class="mt-10 grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
@foreach(LokasiModel loc in Model.FeaturedLocations)
{
<div class="rounded-xl border border-border bg-card p-4">
<div class="font-serif text-lg text-foreground">
@loc.Name
</div>
<div class="mt-1 text-xs text-muted-foreground">
@loc.Region · @loc.FloraCount spesies terdokumentasi
</div>
</div>
}
</div> </div>
</div> </div>
@ -55,21 +26,42 @@
<script> <script>
var map = L.map('map').setView([-6.2088,106.8456],11); var map = L.map('map').setView([-6.2088,106.8456],11);
var customIcon = L.icon({
iconUrl: '/images/marker-icon.png',
iconRetinaUrl: '/images/marker-icon-2x.png',
shadowUrl: '/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution:'© OpenStreetMap' attribution:'© OpenStreetMap'
}).addTo(map); }).addTo(map);
@foreach(LokasiModel l in Model.FeaturedLocations) @foreach(var l in ViewBag.lokasiHome)
{ {
<text> <text>
L.marker([@l.Latitude,@l.Longitude]) L.marker([@l.Lat,@l.Long],{
.addTo(map) icon: customIcon
}).addTo(map)
.bindPopup(` .bindPopup(`
<strong>@l.Name - @l.Region</strong><br> <div style="font-size:11px!important;">
@l.FloraCount Flora terdokumentasi <br> <strong>@l.Name</strong> <br />
@l.FaunaCount Fauna terdokumentasi Status Lokasi : @l.Status <br />
Flora : @l.LokasiTumbuhan.Count <br />
Fauna : @l.LokasiFauna.Count <br /><br />
@* <a class="" href="https://www.google.com/maps?q=@l.Lat,@l.Long" target="_blank"> *@
<a asp-controller="lokasi"
asp-action="detail"
asp-route-slug="@Custom.Encode(l.MsLokasiId)"
target="_blank">
Lihat Detail
</a>
</div>
`); `);
</text> </text>

View File

@ -20,7 +20,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> <link rel="stylesheet" href="~/css/leaflet.css" />
</head> </head>
<body> <body>
@{ @{
@ -194,10 +194,18 @@
</li> </li>
<li> <li>
<a asp-controller="katalog" <a asp-controller="flora"
asp-action="Index" asp-action="Index"
class="hover:text-foreground"> class="hover:text-foreground">
Katalog Flora
</a>
</li>
<li>
<a asp-controller="fauna"
asp-action="Index"
class="hover:text-foreground">
Fauna
</a> </a>
</li> </li>
@ -249,8 +257,8 @@
<script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script> <script src="~/js/site.js" asp-append-version="true"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script src="~/js/leaflet.js"></script>
<script src="https://unpkg.com/lucide@latest"></script> <script src="~/js/lucide.js"></script>
<script> <script>
const btn = document.getElementById('menuButton'); const btn = document.getElementById('menuButton');
const menu = document.getElementById('mobileMenu'); const menu = document.getElementById('mobileMenu');

View File

@ -8,7 +8,7 @@
} }
<div class="mt-8"> <div class="mt-8">
<nav> <nav>
<ul class="pagination flex gap-1"> <ul class="pagination flex gap-1">
@* Previous *@ @* Previous *@
@ -79,4 +79,5 @@
} }
</ul> </ul>
</nav> </nav>
</div>

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("kehati")] [assembly: System.Reflection.AssemblyCompanyAttribute("kehati")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+6bc16bcdaded40520ae17144836179cbbb9ddf3b")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8c0968e5c63c2995ca864ca0475ff76c7cb0facc")]
[assembly: System.Reflection.AssemblyProductAttribute("kehati")] [assembly: System.Reflection.AssemblyProductAttribute("kehati")]
[assembly: System.Reflection.AssemblyTitleAttribute("kehati")] [assembly: System.Reflection.AssemblyTitleAttribute("kehati")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
848d969054017e66ab06effc21957ea2250c3a56c687ec408f03a6b808daf569 287e6a2bd57b39a0597392f9bf6262b61772e83b7098c18d98c1399a76d6cc7e

View File

@ -1 +1 @@
3c47bf4ab7b38e3a0eb2f760261c7bb595133e0d70d143ddbd06f1d167e6b215 2aa414e5f0c16ea07a1df50d4b47ec5e8c134cd12f4762a9d39ad7bd1b4d8b0c

View File

@ -196,3 +196,6 @@
/Applications/MAMP/htdocs/kehati/bin/Debug/net9.0/zh-Hans/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll /Applications/MAMP/htdocs/kehati/bin/Debug/net9.0/zh-Hans/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll
/Applications/MAMP/htdocs/kehati/bin/Debug/net9.0/zh-Hant/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll /Applications/MAMP/htdocs/kehati/bin/Debug/net9.0/zh-Hant/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.resources.dll
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/y5cxcra3jr-6m5wzhvvn1.gz /Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/y5cxcra3jr-6m5wzhvvn1.gz
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/zoo8rffbr6-i65bx55hda.gz
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/7h6jxd9k8n-47ih3oe4t7.gz
/Applications/MAMP/htdocs/kehati/obj/Debug/net9.0/compressed/wkd5h07ok4-cf9mtx7t7r.gz

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
{"GlobalPropertiesHash":"hc8FL4d4SDyJq22ZKuiHZVVsIHQC48YE/mA5pBHYKc4=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"R7Rea/YQmcweqCbKffD9oUelggfpJQX85r65aYZsas0=","InputHashes":["Hhi2dhY28P3DU8GGefeY6F0yaYH0cMHiKCpVh33YhIU=","VOxc8xcqWt6gAM\u002BRuyfRLL1iQY9qPYh4n8cvKjwI3NY=","Sncp4ww/tjimD30ejpDv5D5eCiY\u002BGNCBHG31XvywcgE=","RSbekUJC7incuVtr7C0tXRzZN4BZamYDVsEZmrfQMcY=","0dj\u002B7dC25IeuLKXvwnTzfQVy\u002BUdHnl40sHhE/lKWrRI=","KPTC6joZ0rLn0eml9/Lsh6v1w6OotgKIxbWPkQPSc2U=","oc5dZJn7YA7RsQ0gtAnGAh7rgEphv3dYfFRixIhMKuU=","IBx1Zpi0iRpuwQy5fUr\u002B0BIjRN/f7k\u002BLtsRCoyIqdKg=","x60hTcC5q95RUcHEJci6kZJX\u002BOP5ZncNTZnLKMrK9TQ=","c4VjrF07youw\u002BkifvjAy7plxc6xm5/C/wcqlFxdrIoE=","MSox7E\u002BjIAaACE45MT\u002BrcCsRTWCQiB2IsO7d5a\u002BMvfY=","qTTBic4VK\u002B05MRJnLp9bSltvqEXfvU1zYGb2Yq\u002BZ1Pk=","NQukUql2iNTO4MQCyXa8T8bDU1wDElRnV\u002BBc2yCjEHg=","MgtQemV1N1h3/pFRW/IBNT4EgLJYsuxU0zbAcfbRCb4=","Goe41XQAQHCAcUIB4rTr07EWxMhW4VLC35VQ3i8zogk=","8bEfz8MdGCT\u002BUqVKCJhjT0KyMmRaMYgY/zLLZ1asfpE=","Ibz6Ix07csPbM7Pw2WcZZH0awAHeeZ0osg23I/UHwso=","icl4Xuqd3wVKdyQVGN6K0RJuiPUiZ1J3ZMQUAoAzfT0=","dweympdBNxv56b5xEWZUlkihih0FcF9WdEhWCjq2cXc=","fiFS/KvqSehFNqqcPmIkVbUMcMmBAjue0bCe3g32ZYs=","T3X1M\u002BUddK1SoFQOwNXuQKnudpv8ohop7rTlXDRkn4A=","QDGCJ/H0sJVm29CRqaE0VjtfDzWSx48qBmGqriGN89I=","WWNvV\u002BI7oSnu9ecmCS0Mck2eCGJvRs9a5UgkPxCOjRA=","Xc9BeHGukGDOMxRJ4DWKsD4Hl/eb6mEQZL6YmMBPRoY=","fOkK1386yU0SP0SXkMTynAZIbKu8kDOYliwg0q\u002BNskY=","oct6eD0w1zvUhMj0MXoNwhWFE2YjuoYqg3X96Ucuj4s=","67V7nn6u9b0acsh53M2HmglNpcktUtvOaw3gSRkwjx4=","ma1u/4RE/To974RJYUPGyGaqvCCeme6zJysx9w1ss3c=","o55JlXqf9P5uAQ2khL\u002B6zb9Tdmwm6I1og1gMy1YLpYY=","e0xtx5OOXKYFYOH5RifNbjh4spMMZ4OJe/5WIl23q7I=","5tm4FTjJTYh\u002BIfly7jRHNn4wSziZxSIN8wAEvIw\u002Bqjw=","BHdvCHnZlyS4zwSKcVy3ayvJezMLJXLcVN9R8deaH0g=","ntzaTVX8xBXsH995gvvXvmliXlCQotIsZXpZcglhOaE=","5kR/aL1DviNsyODfcczgmMzxSZCePCH9RPdTfI\u002BcgyA=","85jPWChWoCRZbXQRGb0iFqvZVPOqR7ev3FjdbkOn3N8=","Nbx2WCrP2GEddQzxS83sJa0zFj93vdmpK4GM2nty9uc=","QJPJj2QugL4XCdpHR\u002BUjqru7nIH7z/53/LJfz\u002B2u78E=","0OChFB9xM4RUbmHFnou7uAEh\u002BDlF54KM6B6j00g5Tmw=","ykyMr/QcfGzV063qPhl8tX3/1moBCOJG611QWUQ\u002BbHY=","/CLnWX/m7JPrsLGY\u002BXHRNWDTPsPKGvhpoUNMvUVySdk=","CkYBQvKkMzORePi8WPMM9aW2Lc3xVg5GJyDtKLXwYmY=","xwGlvpWqKnaz0RVaeRVxQ0PJMwOhvULJb3PN/FnF55I=","4xahvZCLorqqeX8Bk5JA9YF2zYf76VJFw\u002BFYV0Le/k0=","5SqPyjpm7H9Zc\u002BBbXBtZiOjmSi5f2cQeYLc7FuoB/ek=","0O4aVW29Vzt0B4Iet0T1oBGOM020UM\u002BLK2/yEbKH2dU=","HMwYA0Zexo0VNDlvtKgkk/e28ujKc1aNC91bm0MLMdk=","iNfcu84P3JCmFtqZp1chAvwyIZTOhH2RqhEneyvLrhs=","2hARyYn7NC4gbrlXbXtVzxaTHpcnwtUTyyjbnSGMmcs=","wHeoBQH8D12d4FpBCQgSAl7Y98J2wIbXVO87I4Oqnmo=","8cQHbaseDOOEdr82\u002B4L1dLbZfVOBGCzj7m1oStCM4RY=","8WGZEIW0hbJT1XkzSCtnaB50AHFRFH4MihnUs34mxhA=","3ZZyBE\u002BdA6aG7oGYzH8eisN1SphrAdQG8rxBn\u002BDzo/w=","BfFJRPyrADpgktkNNc2mfyFFZoBqauN9MCmAUWxe9Ug=","97Ja5zuGdMucJqedxH7CguZ\u002BiLSY4xYuyTXfJE/3mUs=","Gd2mz0U9mny2BKIeKQ\u002BRDt3csebXGOTHzvpBKmzTj9M=","ymiC674Nr\u002BpzpfZQAvz7VgMKWyqBem/OjSN8QeM3478=","tXqEhWxbNOqNYKJvB\u002B6TTsEx8KNlmzLfTndlyi8dcpg=","nYQ\u002BrXWj8wJ\u002BUt/T6U/wVc9UHvQjMUXDgcAtNNlnlcA=","qkZKbEyxkxbCDFtQ06Z9p3Fqpr6AUZHUiFlVpL00cJY=","mb/vdMDaE9L3J1vibUT8coaPWWPSUbGacfV5H5IP\u002BwU=","\u002BHDgqKS6Nqa5bRN/WtecsLITGr6T6whhbWPV0RjwQwM=","Gig3DQsXKloHGlDlRN26sGVUvT8\u002Bu50xYCWb/DK3fTE=","k5m16lGuQyO6e9aY4k1OYGzBolX0sixXAbsVhNDa7fQ=","MrFgmWKVAxban9XX2uqZQO23DWw0NGjsnWiIu9p11jo=","YQgUcWz2ue2oRWm0L9A\u002B\u002BDN/X2SNcdMG3yyz/5A0N4w=","XsOFFGStfZmGs4rkShh2uK3eN2ongLE0d9KBNjaXb6o=","7ITk8hLOO4uilCzXKB1iYKDtCVKMZ2vApR6K0z9qx0c=","RG4n1qULpz4qGNsyBiHJ1ebTfk9LKVz89pL0eSC8gPc=","4EfJtzv9kg3WWFzBqUt8CbF91bcAtW2ocJG4JUrULj8=","S2dH4yX4W/BjGC7Cp1Ov1rAVBSZJlC1sZbKwQRqMA4M=","krL8lBCCkIWVGoLQQThjIfoe6qs/xBAVnhPU3ywnuSs=","5Ad\u002Bef7REpth\u002B1aDMBr3B0HUtzchjmHZ69ipQ7F2ztQ=","0wADQAsURdwl9hsWFMFxN8u51iyhIefZ0\u002BfAdgRzQBM=","6omG1NdZNuYtZDubEy\u002BDST7\u002BfwfA5A3g2vDv80vluVI=","rRoeWHDFv91Dmdy9uNkQCarQ5nvPkifcZ5GBvZJDKDc=","4bsNytNaXkRk3ePwPIbWzq4IwszFAfZcWbCknkEszmA=","eLvoEvqRTPWrPYwFjRNV8D92N\u002BkvcZnoiJi9t9njyTo=","uoiinJcNOciOgqlO0GZQN2smtr6KoTAnah6dv5mVzek=","YoagLoMl49bUAbErIjNPzkNdCDgBDT514c90F9nGnfE=","uzjUeW\u002BKe/Mh7NhfiBvuinD0gzUKuynWF2VbhEIulVQ=","LdNXSSS5DEGYhs9mcjWxtU5uYD9N3kfGTAPRl6j6qWg=","g0y10m2DgfWcR\u002BBdcBNPC0hbivhMAc0z5cHhsqH1Tzc=","TgJ8XvI1vjoz8U9BMJ1maLQnqweAMT4a8ZSbLYUzoAE=","x8umpBTg0fvarcVhS22jEVXuAcL5hqCQF3JRc1qsxro=","s44dS6GzxTQjxM/Pb8o8DITAn8xEEod4rcdnoe\u002BHnjU=","6cZjyH6KHS45s38c7sN\u002BgpFF55ntUEhUWpNynNAafG8="],"CachedAssets":{},"CachedCopyCandidates":{}} {"GlobalPropertiesHash":"hc8FL4d4SDyJq22ZKuiHZVVsIHQC48YE/mA5pBHYKc4=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"R7Rea/YQmcweqCbKffD9oUelggfpJQX85r65aYZsas0=","InputHashes":["Hhi2dhY28P3DU8GGefeY6F0yaYH0cMHiKCpVh33YhIU=","6cZjyH6KHS45s38c7sN\u002BgpFF55ntUEhUWpNynNAafG8=","VOxc8xcqWt6gAM\u002BRuyfRLL1iQY9qPYh4n8cvKjwI3NY=","Sncp4ww/tjimD30ejpDv5D5eCiY\u002BGNCBHG31XvywcgE=","RSbekUJC7incuVtr7C0tXRzZN4BZamYDVsEZmrfQMcY=","0dj\u002B7dC25IeuLKXvwnTzfQVy\u002BUdHnl40sHhE/lKWrRI=","KPTC6joZ0rLn0eml9/Lsh6v1w6OotgKIxbWPkQPSc2U=","oc5dZJn7YA7RsQ0gtAnGAh7rgEphv3dYfFRixIhMKuU=","IBx1Zpi0iRpuwQy5fUr\u002B0BIjRN/f7k\u002BLtsRCoyIqdKg=","x60hTcC5q95RUcHEJci6kZJX\u002BOP5ZncNTZnLKMrK9TQ=","c4VjrF07youw\u002BkifvjAy7plxc6xm5/C/wcqlFxdrIoE=","MSox7E\u002BjIAaACE45MT\u002BrcCsRTWCQiB2IsO7d5a\u002BMvfY=","qTTBic4VK\u002B05MRJnLp9bSltvqEXfvU1zYGb2Yq\u002BZ1Pk=","NQukUql2iNTO4MQCyXa8T8bDU1wDElRnV\u002BBc2yCjEHg=","MgtQemV1N1h3/pFRW/IBNT4EgLJYsuxU0zbAcfbRCb4=","Goe41XQAQHCAcUIB4rTr07EWxMhW4VLC35VQ3i8zogk=","8bEfz8MdGCT\u002BUqVKCJhjT0KyMmRaMYgY/zLLZ1asfpE=","Ibz6Ix07csPbM7Pw2WcZZH0awAHeeZ0osg23I/UHwso=","icl4Xuqd3wVKdyQVGN6K0RJuiPUiZ1J3ZMQUAoAzfT0=","dweympdBNxv56b5xEWZUlkihih0FcF9WdEhWCjq2cXc=","fiFS/KvqSehFNqqcPmIkVbUMcMmBAjue0bCe3g32ZYs=","T3X1M\u002BUddK1SoFQOwNXuQKnudpv8ohop7rTlXDRkn4A=","QDGCJ/H0sJVm29CRqaE0VjtfDzWSx48qBmGqriGN89I=","WWNvV\u002BI7oSnu9ecmCS0Mck2eCGJvRs9a5UgkPxCOjRA=","Xc9BeHGukGDOMxRJ4DWKsD4Hl/eb6mEQZL6YmMBPRoY=","fOkK1386yU0SP0SXkMTynAZIbKu8kDOYliwg0q\u002BNskY=","oct6eD0w1zvUhMj0MXoNwhWFE2YjuoYqg3X96Ucuj4s=","67V7nn6u9b0acsh53M2HmglNpcktUtvOaw3gSRkwjx4=","ma1u/4RE/To974RJYUPGyGaqvCCeme6zJysx9w1ss3c=","o55JlXqf9P5uAQ2khL\u002B6zb9Tdmwm6I1og1gMy1YLpYY=","e0xtx5OOXKYFYOH5RifNbjh4spMMZ4OJe/5WIl23q7I=","5tm4FTjJTYh\u002BIfly7jRHNn4wSziZxSIN8wAEvIw\u002Bqjw=","BHdvCHnZlyS4zwSKcVy3ayvJezMLJXLcVN9R8deaH0g=","ntzaTVX8xBXsH995gvvXvmliXlCQotIsZXpZcglhOaE=","5kR/aL1DviNsyODfcczgmMzxSZCePCH9RPdTfI\u002BcgyA=","85jPWChWoCRZbXQRGb0iFqvZVPOqR7ev3FjdbkOn3N8=","Nbx2WCrP2GEddQzxS83sJa0zFj93vdmpK4GM2nty9uc=","QJPJj2QugL4XCdpHR\u002BUjqru7nIH7z/53/LJfz\u002B2u78E=","0OChFB9xM4RUbmHFnou7uAEh\u002BDlF54KM6B6j00g5Tmw=","ykyMr/QcfGzV063qPhl8tX3/1moBCOJG611QWUQ\u002BbHY=","/CLnWX/m7JPrsLGY\u002BXHRNWDTPsPKGvhpoUNMvUVySdk=","CkYBQvKkMzORePi8WPMM9aW2Lc3xVg5GJyDtKLXwYmY=","xwGlvpWqKnaz0RVaeRVxQ0PJMwOhvULJb3PN/FnF55I=","4xahvZCLorqqeX8Bk5JA9YF2zYf76VJFw\u002BFYV0Le/k0=","5SqPyjpm7H9Zc\u002BBbXBtZiOjmSi5f2cQeYLc7FuoB/ek=","0O4aVW29Vzt0B4Iet0T1oBGOM020UM\u002BLK2/yEbKH2dU=","HMwYA0Zexo0VNDlvtKgkk/e28ujKc1aNC91bm0MLMdk=","iNfcu84P3JCmFtqZp1chAvwyIZTOhH2RqhEneyvLrhs=","2hARyYn7NC4gbrlXbXtVzxaTHpcnwtUTyyjbnSGMmcs=","wHeoBQH8D12d4FpBCQgSAl7Y98J2wIbXVO87I4Oqnmo=","8cQHbaseDOOEdr82\u002B4L1dLbZfVOBGCzj7m1oStCM4RY=","8WGZEIW0hbJT1XkzSCtnaB50AHFRFH4MihnUs34mxhA=","3ZZyBE\u002BdA6aG7oGYzH8eisN1SphrAdQG8rxBn\u002BDzo/w=","BfFJRPyrADpgktkNNc2mfyFFZoBqauN9MCmAUWxe9Ug=","97Ja5zuGdMucJqedxH7CguZ\u002BiLSY4xYuyTXfJE/3mUs=","Gd2mz0U9mny2BKIeKQ\u002BRDt3csebXGOTHzvpBKmzTj9M=","ymiC674Nr\u002BpzpfZQAvz7VgMKWyqBem/OjSN8QeM3478=","tXqEhWxbNOqNYKJvB\u002B6TTsEx8KNlmzLfTndlyi8dcpg=","nYQ\u002BrXWj8wJ\u002BUt/T6U/wVc9UHvQjMUXDgcAtNNlnlcA=","qkZKbEyxkxbCDFtQ06Z9p3Fqpr6AUZHUiFlVpL00cJY=","mb/vdMDaE9L3J1vibUT8coaPWWPSUbGacfV5H5IP\u002BwU=","\u002BHDgqKS6Nqa5bRN/WtecsLITGr6T6whhbWPV0RjwQwM=","Gig3DQsXKloHGlDlRN26sGVUvT8\u002Bu50xYCWb/DK3fTE=","k5m16lGuQyO6e9aY4k1OYGzBolX0sixXAbsVhNDa7fQ=","MrFgmWKVAxban9XX2uqZQO23DWw0NGjsnWiIu9p11jo=","YQgUcWz2ue2oRWm0L9A\u002B\u002BDN/X2SNcdMG3yyz/5A0N4w=","XsOFFGStfZmGs4rkShh2uK3eN2ongLE0d9KBNjaXb6o=","7ITk8hLOO4uilCzXKB1iYKDtCVKMZ2vApR6K0z9qx0c=","RG4n1qULpz4qGNsyBiHJ1ebTfk9LKVz89pL0eSC8gPc=","4EfJtzv9kg3WWFzBqUt8CbF91bcAtW2ocJG4JUrULj8=","S2dH4yX4W/BjGC7Cp1Ov1rAVBSZJlC1sZbKwQRqMA4M=","krL8lBCCkIWVGoLQQThjIfoe6qs/xBAVnhPU3ywnuSs=","5Ad\u002Bef7REpth\u002B1aDMBr3B0HUtzchjmHZ69ipQ7F2ztQ=","0wADQAsURdwl9hsWFMFxN8u51iyhIefZ0\u002BfAdgRzQBM=","6omG1NdZNuYtZDubEy\u002BDST7\u002BfwfA5A3g2vDv80vluVI=","rRoeWHDFv91Dmdy9uNkQCarQ5nvPkifcZ5GBvZJDKDc=","4bsNytNaXkRk3ePwPIbWzq4IwszFAfZcWbCknkEszmA=","eLvoEvqRTPWrPYwFjRNV8D92N\u002BkvcZnoiJi9t9njyTo=","uoiinJcNOciOgqlO0GZQN2smtr6KoTAnah6dv5mVzek=","YoagLoMl49bUAbErIjNPzkNdCDgBDT514c90F9nGnfE=","uzjUeW\u002BKe/Mh7NhfiBvuinD0gzUKuynWF2VbhEIulVQ=","LdNXSSS5DEGYhs9mcjWxtU5uYD9N3kfGTAPRl6j6qWg=","g0y10m2DgfWcR\u002BBdcBNPC0hbivhMAc0z5cHhsqH1Tzc=","TgJ8XvI1vjoz8U9BMJ1maLQnqweAMT4a8ZSbLYUzoAE=","x8umpBTg0fvarcVhS22jEVXuAcL5hqCQF3JRc1qsxro=","s44dS6GzxTQjxM/Pb8o8DITAn8xEEod4rcdnoe\u002BHnjU=","5RyDkb5bkMHF3rqO8otxasIMg5/zCbCdvUJsmz3WVaU=","Q5qUvHyXoamo\u002BgYNAPmQ84\u002Bf8tkj8iVuJAELR9S94yM=","ieXygR5v0xhQOkugvDpC/J6UgBI\u002BJr8PduZ64tbabJo="],"CachedAssets":{},"CachedCopyCandidates":{}}

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
zroMRd2dcHXmYm65YWxO2Mn745dIiqwuztzw31lUAPU= Sceb8JetqiKI7u2xWWtnJLy4d7Cutkf8tE9PARSX2mk=

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,664 @@
/* required styles */
.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
image-rendering: -webkit-optimize-contrast;
}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
width: 1600px;
height: 1600px;
-webkit-transform-origin: 0 0;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg {
max-width: none !important;
max-height: none !important;
}
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
max-width: none !important;
max-height: none !important;
width: auto;
padding: 0;
}
.leaflet-container img.leaflet-tile {
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
mix-blend-mode: plus-lighter;
}
.leaflet-container.leaflet-touch-zoom {
-ms-touch-action: pan-x pan-y;
touch-action: pan-x pan-y;
}
.leaflet-container.leaflet-touch-drag {
-ms-touch-action: pinch-zoom;
/* Fallback for FF which doesn't support pinch-zoom */
touch-action: none;
touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
-ms-touch-action: none;
touch-action: none;
}
.leaflet-container {
-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
z-index: 800;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-pane { z-index: 400; }
.leaflet-tile-pane { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane { z-index: 500; }
.leaflet-marker-pane { z-index: 600; }
.leaflet-tooltip-pane { z-index: 650; }
.leaflet-popup-pane { z-index: 700; }
.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg { z-index: 200; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 800;
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-animated {
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
}
svg.leaflet-zoom-animated {
will-change: transform;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
-webkit-transition: none;
-moz-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-interactive {
cursor: pointer;
}
.leaflet-grab {
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab;
}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
cursor: crosshair;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
cursor: grabbing;
}
/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
pointer-events: none;
}
.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
pointer-events: auto;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline-offset: 1px;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
font-size: 12px;
font-size: 0.75rem;
line-height: 1.5;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover,
.leaflet-bar a:focus {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
.leaflet-touch .leaflet-bar a:first-child {
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.leaflet-touch .leaflet-bar a:last-child {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
font-size: 22px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-scrollbar {
overflow-y: scroll;
overflow-x: hidden;
padding-right: 5px;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
font-size: 13px;
font-size: 1.08333em;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* Default icon URLs */
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
background-image: url(images/marker-icon.png);
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.8);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
line-height: 1.4;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover,
.leaflet-control-attribution a:focus {
text-decoration: underline;
}
.leaflet-attribution-flag {
display: inline !important;
vertical-align: baseline !important;
width: 1em;
height: 0.6669em;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
white-space: nowrap;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: rgba(255, 255, 255, 0.8);
text-shadow: 1px 1px #fff;
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
margin-bottom: 20px;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 24px 13px 20px;
line-height: 1.3;
font-size: 13px;
font-size: 1.08333em;
min-height: 1px;
}
.leaflet-popup-content p {
margin: 17px 0;
margin: 1.3em 0;
}
.leaflet-popup-tip-container {
width: 40px;
height: 20px;
position: absolute;
left: 50%;
margin-top: -1px;
margin-left: -20px;
overflow: hidden;
pointer-events: none;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
pointer-events: auto;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
color: #333;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
border: none;
text-align: center;
width: 24px;
height: 24px;
font: 16px/24px Tahoma, Verdana, sans-serif;
color: #757575;
text-decoration: none;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover,
.leaflet-container a.leaflet-popup-close-button:focus {
color: #585858;
}
.leaflet-popup-scrolled {
overflow: auto;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
-ms-zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
position: absolute;
padding: 6px;
background-color: #fff;
border: 1px solid #fff;
border-radius: 3px;
color: #222;
white-space: nowrap;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
}
.leaflet-tooltip.leaflet-interactive {
cursor: pointer;
pointer-events: auto;
}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
position: absolute;
pointer-events: none;
border: 6px solid transparent;
background: transparent;
content: "";
}
/* Directions */
.leaflet-tooltip-bottom {
margin-top: 6px;
}
.leaflet-tooltip-top {
margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
left: 50%;
margin-left: -6px;
}
.leaflet-tooltip-top:before {
bottom: 0;
margin-bottom: -12px;
border-top-color: #fff;
}
.leaflet-tooltip-bottom:before {
top: 0;
margin-top: -12px;
margin-left: -6px;
border-bottom-color: #fff;
}
.leaflet-tooltip-left {
margin-left: -6px;
}
.leaflet-tooltip-right {
margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
top: 50%;
margin-top: -6px;
}
.leaflet-tooltip-left:before {
right: 0;
margin-right: -12px;
border-left-color: #fff;
}
.leaflet-tooltip-right:before {
left: 0;
margin-left: -12px;
border-right-color: #fff;
}
/* Printing */
@media print {
/* Prevent printers from removing background-images of controls. */
.leaflet-control {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long