diff --git a/index.html b/index.html
deleted file mode 100644
index 7568cec..0000000
--- a/index.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-  
-  
-  
-  UI Lib
-  
-  
-  
-  
-
-
-
-  
-
-
-
\ No newline at end of file
diff --git a/main.js b/main.js
deleted file mode 100644
index 1367e67..0000000
--- a/main.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import './style.scss'
-// import javascriptLogo from './javascript.svg'
-// import { get } from './lib/utility'
-// import { createPicture, createAudio, createVideo, createPdf } from './lib/ui/media'
-import './lib/element/style.scss'
-import ScheduleItem from './lib/element/schedule'
-import { createElement } from './lib/functions';
-
-// document.querySelector('#js-logo').src = javascriptLogo
-
-window.consts = {
-    path: '/',
-    resver: 20231218
-}
-
-const schedule = new ScheduleItem();
-document.querySelector('#container').replaceChildren(
-    schedule.create(),
-    createElement('button', button => {
-        button.innerText = 'Get';
-        button.addEventListener('click', () => console.log(schedule.getParameters()));
-    })
-);
-
-// document.querySelector('#container').replaceChildren(
-//     // createPicture('https://fleet.foresightintelligence.com/doc/mmspart/1740581frZuuFhz5WWCysxs9oGB.jpg'),
-//     createAudio('audio/amr', 'http://vite.tsanie.org/1055003tb0DisaMu1615PeSXKG.amr'),
-//     createPdf('AG-PRO COMPANIES', 'https://fleet.foresightintelligence.com/doc/mmspart/1333321JLrYhkGYqsw6QSVMx3d.pdf'),
-//     // createPicture('https://fleet.foresightintelligence.com/doc/mmspart/138390UGZUMWRmqBsEgPnWuW16.gif'),
-//     // createVideo('https://fleet.foresightintelligence.com/doc/mmspart/17359338sR5qsG7TvS7eaUdP9PL.mp4'),
-// );
-
-/*
-init(null, {
-    template: '/res.json',
-    callback: result => console.log(result)
-}).then(() => {
-    // document.querySelector('#create-icon').appendChild(createIcon('fa-solid', 'user-edit'))
-    resolveIcon(document.querySelector('#create-icon'))
-
-    // document.querySelector('#create-checkbox').appendChild(createCheckbox({
-    //     label: 'Switch 1'
-    // }))
-    resolveCheckbox(document.querySelector('#create-checkbox'))
-
-    resolveTooltip(document.querySelector('#buttons'))
-
-    document.querySelector('#button-fetch').addEventListener('click', () => {
-        get('javascript.svg', {
-            // contentType: '',
-            customHeaders: {
-                'X-Auth': 'test/authentication'
-            }
-        })
-            .then(r => r.blob())
-            .then(blob => document.querySelector('#js-logo').src = URL.createObjectURL(blob));
-    });
-});
-*/
diff --git a/amrnb.js b/sample/amrnb.js
similarity index 100%
rename from amrnb.js
rename to sample/amrnb.js
diff --git a/sample/index.html b/sample/index.html
new file mode 100644
index 0000000..a5e6729
--- /dev/null
+++ b/sample/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+  
+  
+  
+  UI Lib
+  
+  
+  
+  
+  
+  
+
+
+
+  
+
+
+
\ No newline at end of file
diff --git a/javascript.svg b/sample/javascript.svg
similarity index 100%
rename from javascript.svg
rename to sample/javascript.svg
diff --git a/sample/main.js b/sample/main.js
new file mode 100644
index 0000000..cf36874
--- /dev/null
+++ b/sample/main.js
@@ -0,0 +1,350 @@
+// import './style.scss'
+// import javascriptLogo from './javascript.svg'
+// import { get } from './lib/utility'
+// import { createPicture, createAudio, createVideo, createPdf } from './lib/ui/media'
+// import './lib/element/style.scss'
+// import ScheduleItem from './lib/element/schedule'
+// import { createElement } from './lib/functions';
+// import Grid from './lib/ui/grid/grid';
+
+// document.querySelector('#js-logo').src = javascriptLogo
+
+window.consts = {
+    path: '/',
+    resver: 20231218
+}
+
+// const DateSelector = window['lib-ui'].DateSelector;
+// const formatDate = window['lib-ui'].formatDate;
+
+// window.addEventListener('load', () => {
+//     DateSelector.resolve(document.querySelector('#container'), function (date) {
+//         console.log(`element(#${this.element.id}), date changed to: ${formatDate(date)}`);
+
+//         const value = document.querySelector('#dateFrom').value;
+//         console.log(`dateFrom.value = '${value}', formatted: '${formatDate(value)}'`);
+//     });
+// });
+
+const Grid = window['lib-ui'].Grid;
+const createElement = window['lib-ui'].createElement;
+const toDateValue = window['lib-ui'].toDateValue;
+const showConfirm = window['lib-ui'].showConfirm;
+
+window.addEventListener('load', () => {
+    const grid = new Grid('#container');
+    grid.columns = [
+        {
+            key: 'name',
+            // type: Grid.ColumnTypes.Common,
+            caption: 'Name',
+            captionStyle: {
+                'font-style': 'italic'
+            },
+            width: 150,
+            allowFilter: true,
+            totalCss: {
+                'text-align': 'right'
+            }
+        },
+        {
+            key: 'birthday',
+            type: Grid.ColumnTypes.Date,
+            caption: 'Birthday',
+            width: 120,
+            dateMin: '1900-01-01',
+            dateMax: '2025-01-01',
+            dateValueFormatter: toDateValue
+        },
+        {
+            key: 'age',
+            type: Grid.ColumnTypes.Input,
+            caption: 'Age',
+            enabled: false,
+            align: 'right',
+            filter: item => {
+                const ms = new Date() - new Date(item.birthday);
+                const age = Math.floor(ms / 1000 / 60 / 60 / 24 / 365);
+                return String(age);
+            }
+        },
+        {
+            key: 'sex',
+            type: Grid.ColumnTypes.Dropdown,
+            caption: 'Sex',
+            source: [
+                { value: 'male', text: 'Male' },
+                { value: 'female', text: 'Female' },
+                { value: 'other', text: 'Other' }
+            ]
+        },
+        {
+            key: 'active',
+            type: Grid.ColumnTypes.Checkbox,
+            caption: 'Active'
+        },
+        {
+            key: 'remove',
+            type: Grid.ColumnTypes.Icon,
+            text: 'times',
+            resizable: false,
+            sortable: false,
+            orderable: false,
+            tooltip: 'Remove',
+            events: {
+                onclick: function () {
+                    showConfirm('Remove', `Are you sure you want to remove "${this.name}"?`, [
+                        {
+                            key: 'yes',
+                            text: 'Yes',
+                            trigger: () => {
+                                console.log('yes');
+                                return true;
+                            }
+                        },
+                        {
+                            key: 'no',
+                            text: 'No'
+                        }
+                    ], 'question')
+                }
+            }
+        }
+    ];
+    // grid.height = 700 - 36;
+    // grid.autoResize = false;
+    grid.multiSelect = true;
+    // grid.expandable = true;
+    // grid.expandableGenerator = item => ({
+    //     element: createElement('div', div => {
+    //         div.innerText = JSON.stringify(item);
+    //     })
+    // });
+    const fnames = '李王张刘陈杨赵黄周吴徐孙胡朱高林何郭马罗梁宋郑谢韩唐冯于董萧程曹袁邓许傅沈曾彭吕苏卢蒋蔡贾丁魏薛叶阎余潘杜戴夏钟汪田任姜范方石姚谭廖邹熊金陆郝孔白崔康毛邱秦江史顾侯邵孟龙万段漕钱汤尹黎易常武乔贺赖龚文';
+    const names = '先帝创业未半而中道崩殂今天下三分益州疲弊此诚危急存亡之秋也然侍卫之臣不懈于内忠志之士忘身于外者盖追先帝之殊遇欲报之于陛下也诚宜开张圣听以光先帝遗德恢弘志士之气不宜妄自菲薄引喻失义以塞忠谏之路也';
+    // grid.source = Array.from({ length: 200 }).map(() => {
+    //     const r = Math.random();
+    //     const r2 = Math.random();
+    //     const date = new Date(631152000000 + Math.floor(20 * 365 * 24 * 60 * 60 * 1000 * r));
+    //     return {
+    //         name: `${fnames[Math.floor(r * fnames.length)]}${names[Math.floor(r2 * names.length)]}`,
+    //         birthday: `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`,
+    //         sex: r > 0.5 ? 'female' : 'male',
+    //         active: r2 > 0.5 ? true : false
+    //     }
+    // });
+    const getCountFilter = key => (it) => {
+        const count = it[key];
+        if (isNaN(count)) {
+            return '';
+        }
+        // return count.toLocaleString();
+        return String(count).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+    };
+    grid.columns = [
+        { key: 'name', caption: '包名称', type: Grid.ColumnTypes.Input },
+        { key: 'version', caption: '版本号' },
+        { key: 'author', caption: '作者' },
+        { key: 'count', caption: '下载量', filter: getCountFilter('count'), align: 'right' },
+        { key: 'mauiName', caption: 'Maui 对应包' },
+        { key: 'mauiVersion', caption: '版本号' },
+        { key: 'mauiNet', caption: '.NET' },
+        { key: 'mauiCount', caption: '下载量', filter: getCountFilter('mauiCount'), align: 'right' }
+    ];
+    grid.source = [
+        {
+            name: 'Dynatrace.OneAgent.Xamarin',
+            version: '8.283.1',
+            author: 'Dynatrace',
+            count: 308681,
+            mauiName: 'Dynatrace.OneAgent.MAUI',
+            mauiVersion: '1.283.1',
+            mauiNet: '7.0',
+            mauiCount: 12351
+        },
+        {
+            name: 'Esri.ArcGISRuntime.Xamarin.Forms',
+            version: '100.15.4',
+            author: 'Esri_Inc',
+            count: 249909,
+            mauiName: 'Esri.ArcGISRuntime.Maui',
+            mauiVersion: '200.3.0',
+            mauiNet: '8.0',
+            mauiCount: 40913
+        },
+        {
+            name: 'Scandit.DataCapture.Core.Xamarin',
+            version: '6.22.0',
+            author: 'Scandit',
+            count: 527424,
+            mauiName: 'Scandit.DataCapture.Core.Maui',
+            mauiVersion: '6.22.0',
+            mauiNet: '6.0',
+            mauiCount: 14032
+        },
+        {
+            name: 'Scandit.DataCapture.Barcode.Xamarin',
+            version: '6.22.0',
+            author: 'Scandit',
+            count: 417823,
+            mauiName: 'Scandit.DataCapture.Barcode.Maui',
+            mauiVersion: '6.22.0',
+            mauiNet: '6.0',
+            mauiCount: 6048
+        },
+        {
+            name: 'SkiaSharp.Views.Forms',
+            version: '2.88.7',
+            author: 'Microsoft Xamarin',
+            count: 7229049,
+            mauiName: 'SkiaSharp.Views.Maui.Core',
+            mauiVersion: '2.88.7',
+            mauiNet: '7.0',
+            mauiCount: 558468
+        },
+        {
+            mauiName: 'SkiaSharp.Views.Maui.Controls',
+            mauiVersion: '2.88.7',
+            mauiNet: '7.0',
+            mauiCount: 550081
+        },
+        {
+            name: 'ZXing.Net.Mobile',
+            version: '2.4.1',
+            author: 'redth',
+            count: 7187155,
+            mauiName: 'ZXing.Net.Maui',
+            mauiVersion: '0.4.0',
+            mauiNet: '7.0',
+            mauiCount: 177002
+        },
+        {
+            name: 'ZXing.Net.Mobile.Forms',
+            version: '2.4.1',
+            author: 'redth',
+            count: 5494785,
+            mauiName: 'ZXing.Net.Maui.Controls',
+            mauiVersion: '0.4.0',
+            mauiNet: '7.0',
+            mauiCount: 104144
+        }
+    ]
+    grid.init();
+    // setTimeout(() => {
+    //     grid.total = { name: '合计', birthday: grid.source.length };
+    // }, 1000);
+
+    window.grid = grid;
+});
+
+/*
+window.addEventListener('load', () => {
+    const grid = new Grid('#container');
+    grid.columns = ['a', 'b'].map(i => ({
+        key: i,
+        caption: `column ${i}`,
+        width: 200,
+        allowFilter: true
+    }));
+    grid.multiSelect = true;
+    grid.init();
+
+    const items = [];
+    for (let i = 0; i < 10; ++i) {
+        items.push({ a: i + 1, b: `row ${i + 1}` });
+    }
+    grid.source = items;
+
+    window.grid = grid;
+});
+
+document.querySelector('#setItem').addEventListener('click', () => {
+    if (window.grid.selectedIndex < 0) {
+        return;
+    }
+    window.grid.setItem(window.grid.selectedIndex, {
+        a: 'new',
+        b: 'new item'
+    });
+});
+
+document.querySelector('#addItem').addEventListener('click', () => {
+    window.grid.addItem({
+        a: 'add',
+        b: 'add item'
+    }, window.grid.selectedIndex);
+});
+
+document.querySelector('#addItems').addEventListener('click', () => {
+    window.grid.addItems([
+        {
+            a: 'add1',
+            b: 'add item 1'
+        },
+        {
+            a: 'add2',
+            b: 'add item 2'
+        },
+        {
+            a: 'add3',
+            b: 'add item 3'
+        }
+    ], window.grid.selectedIndex);
+});
+
+document.querySelector('#removeItem').addEventListener('click', () => {
+    if (window.grid.selectedIndex < 0) {
+        return;
+    }
+    window.grid.removeItem(window.grid.selectedIndex);
+});
+
+document.querySelector('#removeItems').addEventListener('click', () => {
+    window.grid.removeItems(window.grid.selectedIndexes);
+});
+//*/
+
+// const schedule = new ScheduleItem();
+// document.querySelector('#container').replaceChildren(
+//     schedule.create(),
+//     createElement('button', button => {
+//         button.innerText = 'Get';
+//         button.addEventListener('click', () => console.log(schedule.getParameters()));
+//     })
+// );
+
+// document.querySelector('#container').replaceChildren(
+//     // createPicture('https://fleet.foresightintelligence.com/doc/mmspart/1740581frZuuFhz5WWCysxs9oGB.jpg'),
+//     createAudio('audio/amr', 'http://vite.tsanie.org/1055003tb0DisaMu1615PeSXKG.amr'),
+//     createPdf('AG-PRO COMPANIES', 'https://fleet.foresightintelligence.com/doc/mmspart/1333321JLrYhkGYqsw6QSVMx3d.pdf'),
+//     // createPicture('https://fleet.foresightintelligence.com/doc/mmspart/138390UGZUMWRmqBsEgPnWuW16.gif'),
+//     // createVideo('https://fleet.foresightintelligence.com/doc/mmspart/17359338sR5qsG7TvS7eaUdP9PL.mp4'),
+// );
+
+/*
+init(null, {
+    template: '/res.json',
+    callback: result => console.log(result)
+}).then(() => {
+    // document.querySelector('#create-icon').appendChild(createIcon('fa-solid', 'user-edit'))
+    resolveIcon(document.querySelector('#create-icon'))
+
+    // document.querySelector('#create-checkbox').appendChild(createCheckbox({
+    //     label: 'Switch 1'
+    // }))
+    resolveCheckbox(document.querySelector('#create-checkbox'))
+
+    resolveTooltip(document.querySelector('#buttons'))
+
+    document.querySelector('#button-fetch').addEventListener('click', () => {
+        get('javascript.svg', {
+            // contentType: '',
+            customHeaders: {
+                'X-Auth': 'test/authentication'
+            }
+        })
+            .then(r => r.blob())
+            .then(blob => document.querySelector('#js-logo').src = URL.createObjectURL(blob));
+    });
+});
+*/
diff --git a/style.css b/sample/style.css
similarity index 100%
rename from style.css
rename to sample/style.css
diff --git a/style.scss b/sample/style.scss
similarity index 100%
rename from style.scss
rename to sample/style.scss
diff --git a/sample/web.config b/sample/web.config
new file mode 100644
index 0000000..07a7d1a
--- /dev/null
+++ b/sample/web.config
@@ -0,0 +1,13 @@
+
+
+    
+        
+            
+        
+        
+            
+                
+            
+        
+    
+