问:
How do I Change font-color in CSS animation using CSS animation
I am trying to make it so when I open the page, test will show up as red and the testing will show up as white. There is a delay that I am using for when the page opens that I want to keep (if you run the program you will see).

Css

#hero h1 {
  display: block;
  width: fit-content;
  font-size: 3rem;
  position: relative;
  color: transparent;
  animation: text_reveal .5s ease forwards;
  animation-delay: 1s;
}

#hero h1 .slide {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0;
  background-color: crimson;
  animation: text_reveal_box 1s ease;
  animation-delay: .5s;
}

/* KetFrames */

@keyframes text_reveal_box {
  50% {
    width: 100%;
    left: 0;
  }
  100% {
    width: 0;
    left: 100%;
  }
}

@keyframes text_reveal {
  100% {
    color: white;
  }
}
```
<p><strong>HTML</strong></p>
<pre class="lang-html prettyprint-override"><code><section id="hero">
  <div class="hero container">
    <div>
      <h1><span class="red">test</span> testing<span class="slide"></span></h1>
    </div>
  </div>
</section>
</code>```

答:
Do you mean like this? See changes under /* added CSS */

body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  background-color: grey;
}

html {
  font-size: 20px;
  font-family: 'Montserrat', sans-serif;
}

#hero h1 {
  display: block;
  width: fit-content;
  font-size: 3rem;
  position: relative;
  color: transparent;
  animation: text_reveal .5s ease forwards;
  animation-delay: 1s;
}

#hero h1 .slide {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0;
  background-color: crimson;
  animation: text_reveal_box 1s ease;
  animation-delay: .5s;
}

/* KetFrames */

@keyframes text_reveal_box {
  50% {
    width: 100%;
    left: 0;
  }
  100% {
    width: 0;
    left: 100%;
  }
}

@keyframes text_reveal {
  100% {
    color: white;
  }
}

/* added CSS */
.red {
  animation: text_reveal_red ease forwards;
  animation-delay: 1s;
  animation-iteration-count: 1;
}

@keyframes text_reveal_red {
  100% {
    color: crimson;
  }
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><section id="hero">
  <div class="hero container">
    <div>
      <h1><span class="red">test</span> testing<span class="slide"></span></h1>
    </div>
  </div>
</section></code>```

Body:
I am trying to make it so when I open the page, test will show up as red and the testing will show up as white. There is a delay that I am using for when the page opens that I want to keep (if you run the program you will see).

Css

#hero h1 {
  display: block;
  width: fit-content;
  font-size: 3rem;
  position: relative;
  color: transparent;
  animation: text_reveal .5s ease forwards;
  animation-delay: 1s;
}

#hero h1 .slide {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0;
  background-color: crimson;
  animation: text_reveal_box 1s ease;
  animation-delay: .5s;
}

/* KetFrames */

@keyframes text_reveal_box {
  50% {
    width: 100%;
    left: 0;
  }
  100% {
    width: 0;
    left: 100%;
  }
}

@keyframes text_reveal {
  100% {
    color: white;
  }
}

HTML

test testing

Body:
Do you mean like this? See changes under /* added CSS */

body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  background-color: grey;
}

html {
  font-size: 20px;
  font-family: 'Montserrat', sans-serif;
}

#hero h1 {
  display: block;
  width: fit-content;
  font-size: 3rem;
  position: relative;
  color: transparent;
  animation: text_reveal .5s ease forwards;
  animation-delay: 1s;
}

#hero h1 .slide {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0;
  background-color: crimson;
  animation: text_reveal_box 1s ease;
  animation-delay: .5s;
}

/* KetFrames */

@keyframes text_reveal_box {
  50% {
    width: 100%;
    left: 0;
  }
  100% {
    width: 0;
    left: 100%;
  }
}

@keyframes text_reveal {
  100% {
    color: white;
  }
}

/* added CSS */
.red {
  animation: text_reveal_red ease forwards;
  animation-delay: 1s;
  animation-iteration-count: 1;
}

@keyframes text_reveal_red {
  100% {
    color: crimson;
  }
}

<section id="hero">
  <div class="hero container">
    <div>
      <h1><span class="red">test</span> testing<span class="slide"></span></h1>
    </div>
  </div>
</section>


来源: stackexchange

问:
Google App engine auto update
Google App Engine always wants me to download and install software when new version released.

Any option to do this task automatically ?
Why they are not implement the software auto updation ?

答:
Not really a programming related question.

People do not want their SDKs randomly updating without telling you, APIs change over time and you might not be ready.

ContentLicense: CC BY-SA 3.0

Title: Google App engine auto update


问:
How can I write out header names along with data using dlmwrite?
I use this code to write out to a csv file inside a loop. The loop will run thousands of times and store these 5 data points after every run.

```<code>dlmwrite('test.csv', [outlet_info.outlet_row, outlet_info.outlet_col,
         outlet_info.rel_err, outlet_info.new_est_darea, delta1)
</code>```

How can I put header names in the csv file as well? eg. row, col, err, area, del

How can I append 5 new data as a new row after every loop? How do I use append?

答:
You can also do this with using dlmwrite only. Just write the header first an then use the -append flag to append to it:

```<code>%prepare your header string
hdr = 'row, col, err, area, del';
%write header first
dlmwrite('test.csv', hdr, '');
%append your data to the same file
dlmwrite('test.csv', [outlet_info.outlet_row, outlet_info.outlet_col,
         outlet_info.rel_err, outlet_info.new_est_darea, delta1, '-append');
</code>```

Body:
I use this code to write out to a csv file inside a loop. The loop will run thousands of times and store these 5 data points after every run.

dlmwrite('test.csv', [outlet_info.outlet_row, outlet_info.outlet_col,
         outlet_info.rel_err, outlet_info.new_est_darea, delta1)

How can I put header names in the csv file as well? eg. row, col, err, area, del

How can I append 5 new data as a new row after every loop? How do I use append?

Body:
You can also do this with using dlmwrite only. Just write the header first an then use the -append flag to append to it:

%prepare your header string
hdr = 'row, col, err, area, del';
%write header first
dlmwrite('test.csv', hdr, '');
%append your data to the same file
dlmwrite('test.csv', [outlet_info.outlet_row, outlet_info.outlet_col,
         outlet_info.rel_err, outlet_info.new_est_darea, delta1, '-append');

ContentLicense: CC BY-SA 4.0


问:
Copying an object with a polymorphic member in C++
I wish to express that each object of type V owns an object of type B. B is a polymorphic type, and is therefor accessed through a pointer or reference to prevent slicing (C.145). I find it natural to express this as following

    class B {};

    class V {
    public:
        unique_ptr p;
    };
```
<p>I can now derive B and assign the derived to p, as such</p>
<pre class="lang-cpp prettyprint-override"><code>    class D : public B {};

    V x;
    x.p = make_unique<D>();
</code>```

Because B is a polymorphic type, it is advised to suppress copies and moves to prevent slicing (C.67).

    B(const B&) = delete;
    // etc...
```

It is impossible to copy p, because it's a unique_ptr, and I have now prevented deep copying as well, unless a clone function is implemented (C.130). Is the implementation of a virtual clone function an indication of poor design? It seems like a work-around.

By following these two rules from the C++ Core Guidelines, I have prevented the copying of V. If V is a vertex in a graph, and graphs must be copied, then I have created a problem for myself; No graphs can be copied anymore. Implementing a custom copy assignment for V doesn't solve that issue, because deep-copying of p is impossible.

After searching around the web, I found no solution which felt natural, and I concluded that there must be something very wrong with my way of thinking. Is it a bad idea to have a polymorphic member? If one should not copy a polymorphic object then one can neither copy any object owning another polymorphic object.

The member can be a shared_ptr instead, but then the semantics become wrong, because this is not a shared object. I lack a way of expressing something that is so obviously simple to conceptualize. How do I copy an object that owns another polymorphic object while not sacrificing semantics?  Every post I've read where someone poses a question regarding copying of unique_ptr, deep copying etc..., are usually met with an answer that entails a sacrifice, most likely because the way of solving the problem is wrong in the first place. I have a feeling there is a very simple and elegant solution to this.

答:
You need to ask yourself a question : Why should B not be copyable?

The example you described, with a graph owning one (or probably multiple) vertexes shows the opposite : B should be copyable!
What you don't want is two graphs sharing the same vertex instance.

So you can create a copy constructor / clone method for V along those lines :

```<code>V::V(const V& other)
{
  p = other.p->clone();
}

std::unique_ptr<B> D::clone()
{
  return std::make_unique<D>(...);
}
</code>```

Have a look at this article for a better explanation.

Body:
I wish to express that each object of type V owns an object of type B. B is a polymorphic type, and is therefor accessed through a pointer or reference to prevent slicing (C.145). I find it natural to express this as following

    class B {};

    class V {
    public:
        unique_ptr p;
    };

I can now derive B and assign the derived to p, as such

    class D : public B {};

    V x;
    x.p = make_unique<D>();

Because B is a polymorphic type, it is advised to suppress copies and moves to prevent slicing (C.67).

    B(const B&) = delete;
    // etc...

It is impossible to copy p, because it's a unique_ptr, and I have now prevented deep copying as well, unless a clone function is implemented (C.130). Is the implementation of a virtual clone function an indication of poor design? It seems like a work-around.

By following these two rules from the C++ Core Guidelines, I have prevented the copying of V. If V is a vertex in a graph, and graphs must be copied, then I have created a problem for myself; No graphs can be copied anymore. Implementing a custom copy assignment for V doesn't solve that issue, because deep-copying of p is impossible.

After searching around the web, I found no solution which felt natural, and I concluded that there must be something very wrong with my way of thinking. Is it a bad idea to have a polymorphic member? If one should not copy a polymorphic object then one can neither copy any object owning another polymorphic object.

The member can be a shared_ptr instead, but then the semantics become wrong, because this is not a shared object. I lack a way of expressing something that is so obviously simple to conceptualize. How do I copy an object that owns another polymorphic object while not sacrificing semantics?  Every post I've read where someone poses a question regarding copying of unique_ptr, deep copying etc..., are usually met with an answer that entails a sacrifice, most likely because the way of solving the problem is wrong in the first place. I have a feeling there is a very simple and elegant solution to this.

Body:
You need to ask yourself a question : Why should B not be copyable?

The example you described, with a graph owning one (or probably multiple) vertexes shows the opposite : B should be copyable!
What you don't want is two graphs sharing the same vertex instance.

So you can create a copy constructor / clone method for V along those lines :

V::V(const V& other)
{
  p = other.p->clone();
}

std::unique_ptr<B> D::clone()
{
  return std::make_unique<D>(...);
}

Have a look at this article for a better explanation.


问:
problem with adding data from DB to jtable
i want to add all my data from DB to jtable, but using this code i get only the last row from DB, added to the table severelal times.
Can someone tell where is mistake?

```<code>public Vector getOrder() throws Exception
{
    DbConnection();
    Statement st = null;
    ResultSet res =null;
    String query="Select * From Orders;";

try{
    st=connect.createStatement();
    res=st.executeQuery(query);
    Vector v =new Vector();
    Vector<String> record = new Vector<String>();
    int i=0;
    while(res.next())
    {
    record.clear();
        uzsakNr=res.getString("Uzsakymo_nr");
        priemDat=res.getString("Priemimo_data");
        irengPav=res.getString("Irenginio_pavadinimas");
        model=res.getString("Modelis");
        status=res.getString("Statusas");
        grazDat=res.getString("Grazinimo_data");
        clientId=Long.toString(res.getLong("ClientId"));

        //record.addElement(i);
        record.addElement(uzsakNr);
        record.addElement(priemDat);
        record.addElement(irengPav);
        record.addElement(model);
        record.addElement(status);
        record.addElement(grazDat);
        record.addElement(clientId);
        //record.addElement("");
        v.addElement(record);
        i++;
    }
    //Zle vydaji, daji tyko trzy takiesame ostatnie
    System.out.println(v);
    return v;
}finally {
    if(res!=null) res.close();
    if(st!=null) st.close();
}

}
</code>```

in another class

```<code>        try{
        Vector ve=db.getOrder();

        String heading[]={"uzsakNr","priemDat","irengPav","model","status","grazDat","ClientID"};
        Vector columnHeads= new Vector();
        for (int i=0;i<heading.length; i++)
            columnHeads.addElement(heading[i]);

        table = new JTable(ve,columnHeads);
        table.addMouseListener(new TableMouseListener());
        scrollPane.setViewportView(table);
        UzsakPanel.add(scrollPane);
        scrollPane.setBounds(10, 10, 901, 200);
        }catch(Exception e2){e2.printStackTrace();}
</code>```

答:
Firstly,

Replace the line containing clear()  with Vector<String> record = new Vector<String>();

Secondly, I think what you're doing is probably correct but your printing is the problem.

Since you have a vector of vectors containing strings, I would print it like so

```<code>for(Vector stringVect : v) {
    for(String s : stringVect) {
        System.out.print(s+ '\t');
  }
  System.out.println();
}
</code>```

Body:
i want to add all my data from DB to jtable, but using this code i get only the last row from DB, added to the table severelal times.
Can someone tell where is mistake?

public Vector getOrder() throws Exception
{
    DbConnection();
    Statement st = null;
    ResultSet res =null;
    String query="Select * From Orders;";

try{
    st=connect.createStatement();
    res=st.executeQuery(query);
    Vector v =new Vector();
    Vector<String> record = new Vector<String>();
    int i=0;
    while(res.next())
    {
    record.clear();
        uzsakNr=res.getString("Uzsakymo_nr");
        priemDat=res.getString("Priemimo_data");
        irengPav=res.getString("Irenginio_pavadinimas");
        model=res.getString("Modelis");
        status=res.getString("Statusas");
        grazDat=res.getString("Grazinimo_data");
        clientId=Long.toString(res.getLong("ClientId"));

        //record.addElement(i);
        record.addElement(uzsakNr);
        record.addElement(priemDat);
        record.addElement(irengPav);
        record.addElement(model);
        record.addElement(status);
        record.addElement(grazDat);
        record.addElement(clientId);
        //record.addElement("");
        v.addElement(record);
        i++;
    }
    //Zle vydaji, daji tyko trzy takiesame ostatnie
    System.out.println(v);
    return v;
}finally {
    if(res!=null) res.close();
    if(st!=null) st.close();
}

}

in another class

        try{
        Vector ve=db.getOrder();

        String heading[]={"uzsakNr","priemDat","irengPav","model","status","grazDat","ClientID"};
        Vector columnHeads= new Vector();
        for (int i=0;i<heading.length; i++)
            columnHeads.addElement(heading[i]);

        table = new JTable(ve,columnHeads);
        table.addMouseListener(new TableMouseListener());
        scrollPane.setViewportView(table);
        UzsakPanel.add(scrollPane);
        scrollPane.setBounds(10, 10, 901, 200);
        }catch(Exception e2){e2.printStackTrace();}

Body:
Firstly,

Replace the line containing clear()  with Vector<String> record = new Vector<String>();

Secondly, I think what you're doing is probably correct but your printing is the problem.

Since you have a vector of vectors containing strings, I would print it like so

for(Vector stringVect : v) {
    for(String s : stringVect) {
        System.out.print(s+ '\t');
  }
  System.out.println();
}


问:
How to make text slide in and out of the page
I need to achieve same effect as slide in and out effect like on this page :https://pangrampangram.com/products/neue-machina</p>

答:
create a div inside a another div make the child div bigger than parent div once it get done you can make the child scrolling by left or right attribute in css.</p>
```<code>`<html data-test-id="brave-new-tab-page" dir="ltr">
</code>```

        .parent
        {
            width: 500px;
            height: 100px;
            overflow: hidden;
            position: absolute;
        }
        .child
        {
            width: 1347px;
            font-size: 76px;
            position: absolute;
        }

        test test test test test test test tesenter code heret test test

        let position = 0;
        document.addEventListener('DOMContentLoaded',  () =>
        {
            setInterval(() =>
            {
                let child = document.getElementsByClassName('child')[0]
                child.setAttribute('style', 'left:-' + position + 'px')
```<code>            if ( position > ( 1347 - 500 ) )
                position = 0

            position ++
        }, 5)
    }, false);
</script>
</code>```

`

Body:
create a div inside a another div make the child div bigger than parent div once it get done you can make the child scrolling by left or right attribute in css.

`<html data-test-id="brave-new-tab-page" dir="ltr">

        .parent
        {
            width: 500px;
            height: 100px;
            overflow: hidden;
            position: absolute;
        }
        .child
        {
            width: 1347px;
            font-size: 76px;
            position: absolute;
        }

        test test test test test test test tesenter code heret test test

        let position = 0;
        document.addEventListener('DOMContentLoaded',  () =>
        {
            setInterval(() =>
            {
                let child = document.getElementsByClassName('child')[0]
                child.setAttribute('style', 'left:-' + position + 'px')

            if ( position > ( 1347 - 500 ) )
                position = 0

            position ++
        }, 5)
    }, false);
</script>

`


问:
Uncaught TypeError, 500 Internal Server Error, and Error 1101 while trying to deploy a worker in Cloudflare
I am using https://www.craft.do/ as a note-taking app. It has the ability to publish notes online so I want to use it to publish an online collection of notes, which I did here: https://www.craft.do/s/DNUP0iZyULDr15. However, I want to use a custom domain before the thread of random numbers and letters as in something like https://test-site.com/s/DNUP0iZyULDr15. Craft currently does not support custom domains. But a developer created a workaround here: https://zuolan.me/craft_custom_domain_en#64abd1d780c247d8a5fd9678e1d0ec80.

His solution basically uses a script that runs through a worker/service in Cloudflare. This is the script:

// Your domain name
const MY_DOMAIN = 'knu-salin.vinceimbat.workers.dev'

// Website language
const LANG = 'en'

// Favicon url
const FAVICON_URL = 'https://example.com/favicon.ico'

// Your config page link
const CONFIG_URL = 'https://www.craft.do/s/9Q1QIOQrvZNnNf'

// Your Telegram Token and ID
const TG_TOKEN = ""
const TG_CHAT_ID = ""

// END

// Default function
addEventListener('fetch', event => {
  event.respondWith(fetchAndApply(event.request))
})

// Fetch url
async function fetchAndApply(request) {
  let url = new URL(request.url)
  // Set upstream domain
  url.host = 'www.craft.do'
  let pathname = url.pathname
  let response = null

  const config_obj = await configParser()

  // Automatically generate robots.txt and sitemap.xml
  if (pathname === '/robots.txt') {
    return new Response('Sitemap: https://' + MY_DOMAIN + '/sitemap.xml')
  }
  if (pathname === '/sitemap.xml') {
    let sitemap = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
    for(var path in config_obj){
      sitemap += '<url><loc>https://' + MY_DOMAIN + '/' + path + '</loc></url>'
    }
    sitemap += '</urlset>'
    response = new Response(sitemap)
    response.headers.set('content-type', 'application/xml')
    return response
  }
  if (pathname === '/favicon.svg') {
    response = new Response('<svg xmlns="http://www.w3.org/2000/svg" width="100pt" height="100pt" viewBox="0 0 100 100"><g fill="blue" transform="translate(0.000000,100) scale(0.080000,-0.080000)"><path d="M762 1203 c-6 -15 -13 -46 -17 -68 -4 -22 -13 -49 -20 -61 -15 -23 -122 -69 -257 -109 -49 -14 -88 -28 -88 -29 0 -2 33 -20 73 -40 49 -24 87 -36 115 -36 28 0 42 -4 42 -13 0 -34 -295 -517 -390 -639 -40 -52 -4 -28 86 56 49 46 105 109 124 141 19 31 64 98 100 148 77 108 125 186 173 283 20 39 46 78 59 86 13 8 69 34 126 58 107 45 118 57 110 111 -3 21 -10 25 -78 34 l-75 10 -5 45 c-5 42 -7 45 -36 48 -26 3 -33 -1 -42 -25z"/><path d="M754 616 c-40 -19 -88 -39 -108 -46 -43 -14 -45 -30 -7 -72 25 -28 33 -31 80 -30 39 1 54 -3 58 -15 7 -18 -30 -140 -58 -192 -36 -67 6 -93 135 -84 l86 6 0 -26 c0 -14 -4 -37 -10 -51 -5 -14 -8 -26 -6 -26 7 0 110 68 129 85 11 10 17 30 17 60 0 62 -22 70 -150 57 -52 -5 -98 -6 -103 -2 -4 3 3 31 16 61 13 30 32 78 42 108 10 30 28 70 41 89 26 38 30 63 14 93 -17 31 -91 25 -176 -15z"/></g></svg>')
    response.headers.set('content-type', 'image/svg+xml')
    return response
  }

  // Default path
  if (pathname === '/') {
    url.pathname = '/s/' + config_obj['index'].slice(23)
  }

  // Prohibit other Craft.do share pages
  else if (pathname.startsWith('/s/')) {
    url.pathname = "/404"
  }

  // Proxy index blocks pages
  else if (pathname.startsWith('/b/')) {
    url.pathname = '/s/' + config_obj['index'].slice(23) + pathname
  }

  // TODO: There is an unresolved issue here
  // External pages url is troublesome to deal with.
  else if (pathname.includes('/x/')) {
    // url.pathname = '/s/' + config_obj['index'].slice(23) + pathname
    return Response.redirect('https://' + MY_DOMAIN, 301)
  }

  // Proxy js
  else if (pathname.startsWith('/share/') && pathname.endsWith('.js')) {
    response = await fetch(url)
    let body = await response.text()
    // replace all js files domain
    response = new Response(body.replace(/www.craft.do/g, MY_DOMAIN), response)
    response.headers.set('Content-Type', 'application/x-javascript')
  }

  // Proxy images
  else if (pathname.startsWith('/img/')) {
    // Proxy api.craft.do, pages preview api
    // This code can proxy "MY_DOMAIN/img/<pathname>" --> "api.craft.do/render/preview/<slug>"
    url.host = 'api.craft.do'

    let path_name = pathname.slice(5)

    let img_slug = config_obj[path_name].slice(23)
    url.pathname = pathname.replace(pathname, '/render/preview/' + img_slug)

    // Cache images
    const cacheImage = `https://${url.host}${url.pathname}`
    let response = await fetch(url.href, {
      cf: {
        // Always cache this fetch regardless of content type
        // for a max of 86400 seconds before revalidating the resource
        cacheTtl: 86400,
        cacheEverything: true,
        //Enterprise only feature, see Cache API for other plans
        cacheKey: cacheImage,
      },
    })
    // Reconstruct the Response object to make its headers mutable.
    response = new Response(response.body, response)
    // Set cache control headers to cache on browser for 25 minutes
    response.headers.set("Cache-Control", "max-age=1500")
    return response
  }

  // Disable Craft log.
  else if (pathname.startsWith('/api/log/')) {
    return new Response('Disable loging.')
  }

  // Proxy comment API.
  else if (pathname.startsWith('/api/') && (pathname.includes('submitAnon'))) {
    const init = {
      body: request.body,
      method: 'PUT',
      headers: {
        "content-type": "application/json;charset=UTF-8",
      },
    }
    const response = await fetch(url.href, init)
    const resp_json = await response.json()
    const resp_str = JSON.stringify(resp_json)

    // Telegram notify
    const comment_message = resp_json.comments[0].content
    const craft_slug = pathname.split("/")[5]
    const craft_url = 'https://www.craft.do/s/' + craft_slug
    const comment_slug = findJsonKey(config_obj, craft_url)
    const tg_message = 'Comment URL:\n'
      + 'https://' + MY_DOMAIN + '/' + comment_slug
      + '\n\n'
      + 'Comment Message:\n' + comment_message
    await sendToTelegram(tg_message)

    return new Response(resp_str)
  }

  else {
    try {
      let urlIndexSlug = null
      if (pathname.startsWith('/en/') || pathname.startsWith('/p/') || pathname.startsWith('/page/')) {
        urlIndexSlug = pathname.split("/")[1] + '/' + pathname.split("/")[2]
      } else {
        urlIndexSlug = pathname.split("/")[1]
      }

      let configPath = config_obj[urlIndexSlug].slice(23)
      url.pathname = '/s/' + configPath

      console.log(url.pathname)

      if (typeof(configPath) == "undefined") { throw new Error('404 not found: ' + configPath) }
    } catch (error) {
      if (pathname.startsWith('/api/') || pathname.endsWith('.css') || pathname.endsWith('.webmanifest') || pathname.endsWith('.svg')) {
        // nothing
      } else {
        url.pathname = '/404'
        // return new Response(error.message)
      }
    }
  }

  class AttributeRewriter {
    element(element) {
      if (element.getAttribute('property') === 'og:url') {
        element.setAttribute('content', 'https://' + MY_DOMAIN + pathname)
      }
      if (element.getAttribute('property') === 'og:image') {
        if (pathname === '/') { pathname = '/index' }
        element.setAttribute('content', 'https://' + MY_DOMAIN + '/img' + pathname)
      }
      if (element.getAttribute('name') === 'luki:api-endpoint') {
        element.setAttribute('content', 'https://' + MY_DOMAIN + '/api/')
      }
      if (element.getAttribute('lang') === 'en') {
        element.setAttribute('lang', LANG)
      }
      if (element.getAttribute('rel') === 'icon') {
        element.setAttribute('href', FAVICON_URL)
      }
      if (element.getAttribute('rel') === 'apple-touch-icon') {
        element.setAttribute('href', FAVICON_URL)
      }
    }
  }
  class RemoveElement {
    element(element) {
      element.remove()
    }
  }
  async function rewriteHTML(res) {
    res.headers.delete("Content-Security-Policy")
    return new HTMLRewriter()
      .on('body', new BodyRewriter())
      .on('head', new HeadRewriter())
      .on('html', new AttributeRewriter())
      .on('meta', new AttributeRewriter())
      .on('link', new AttributeRewriter())
      .on('meta[name="robots"]', new RemoveElement())   // SEO
      .on('head>style', new RemoveElement())   // Remove fonts
      .on('script[src="https://www.craft.do/assets/js/analytics2.js"]', new RemoveElement())    // Delete analytics js
      .transform(res)
  }

  let method = request.method
  let request_headers = request.headers
  let new_request_headers = new Headers(request_headers)

  new_request_headers.set('Host', url.hostname)
  new_request_headers.set('Referer', url.hostname)

  let original_response = await fetch(url.href, {
    method: method,
    headers: new_request_headers
  })

  let response_headers = original_response.headers
  let new_response_headers = new Headers(response_headers)
  let status = original_response.status

  response = new Response(original_response.body, {
    status,
    headers: new_response_headers
  })

  // If you want change anything in response.
  let text = await response.text()

  // Return modified response.
  let modified_response = new Response(text, {
    status: response.status,
    statusText: response.statusText,
    headers: response.headers
  })

  if (pathname.startsWith('/share/static/js/') && (pathname.includes('codehighlight'))) {
    return modified_response
  } else {
    return rewriteHTML(modified_response)
  }
}

async function configParser() {
  // Delete string "https://www.craft.do/s/"
  let config_slug = CONFIG_URL.slice(23)
  const api_url = 'https://www.craft.do/api/share/' + config_slug
  const init = {
    headers: {
      "content-type": "application/json;charset=UTF-8",
    },
  }
  const config_response = await fetch(api_url, init)       // Get www.craft.do/api/share/<slug> content.
  const response_json = await config_response.json()       // Convert the content to json format (string).
  const content_json = response_json.blocks[1].content     // Get the json data of the first block in the body.
  const content_str = JSON.stringify(content_json)         // Convert json to string.
  // Handle escape characters.
  const config_json = content_str.replace(/\\t/g, '').replace(/\\n/g, '').replace(/\\/g, '').replace('"{', '{').replace('}"', '}')
  let config_obj = JSON.parse(config_json)
  return config_obj
}

async function sendToTelegram(message) {
  const tgUrl = "https://api.telegram.org/bot" + TG_TOKEN + "/sendMessage"
  const init = {
    method: 'POST',
    headers: {
      "content-type": "application/json;charset=UTF-8",
    },
    body: JSON.stringify({
      "chat_id": TG_CHAT_ID,
      "text": message
    })
  }
  await fetch(tgUrl, init)
  // const response = await fetch(tgUrl, init)
  // const resp_text = await response.text()
  // return new Response(resp_text)
}

function findJsonKey(obj, value, compare = (a, b) => a === b) {
  return Object.keys(obj).find(k => compare(obj[k], value))
}

class BodyRewriter {
  element(element) {
    // Append your html
    element.append(`

    `, {
      html: true
    })
  }
}
class HeadRewriter {
  element(element) {
    element.append(`

    `, {
      html: true
    })
  }
}```

The only thing I added in his code was the value for const My_DOMAIN and const CONFIG_URL.

When I try to open the URL where it should deploy: https://knu-salin.vinceimbat.workers.dev/, I get Error 1101 Worker threw exception. Upon inspecting the debug console, this is what I saw:

Uncaught (in promise) TypeError and Uncaught (in response) TypeError

Was I doing something wrong? Or is there somethign wrong with his code?

答:
The error message says:

```<code>Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'slice')
  at fetchAndApply (worker.js:56)
</code>```

So, let's see what's on line 56. That appears to be:

    url.pathname = '/s/' + config_obj['index'].slice(23)
```
<p>The error message is telling us that <code>config_obj['index']</code> was undefined, and so trying to access <code>config_obj['index'].slice</code> is an error.</p>
<p>If <code>config_obj['index']</code> is undefined, that means that the property <code>index</code> is missing from <code>config_obj</code>. But where did <code>config_obj</code> come from? Up above, we see:</p>
<pre class="lang-js prettyprint-override"><code>  const config_obj = await configParser()
</code>```

OK, so the configParser() function creates this object. Let's look at that function.

async function configParser() {
  // Delete string "https://www.craft.do/s/"
  let config_slug = CONFIG_URL.slice(23)
  const api_url = 'https://www.craft.do/api/share/' + config_slug
  const init = {
    headers: {
      "content-type": "application/json;charset=UTF-8",
    },
  }
  const config_response = await fetch(api_url, init)       // Get www.craft.do/api/share/<slug> content.
  const response_json = await config_response.json()       // Convert the content to json format (string).
  const content_json = response_json.blocks[1].content     // Get the json data of the first block in the body.
  const content_str = JSON.stringify(content_json)         // Convert json to string.
  // Handle escape characters.
  const config_json = content_str.replace(/\\t/g, '').replace(/\\n/g, '').replace(/\\/g, '').replace('"{', '{').replace('}"', '}')
  let config_obj = JSON.parse(config_json)
  return config_obj
}
```

We can see that, based on the URL you specified for CONFIG_URL, this code will compute the url https://www.craft.do/api/share/9Q1QIOQrvZNnNf, fetch that URL, parse it as JSON, and return the result.

If you visit that URL, you see it does indeed return JSON. However, the JSON does not contain a top-level property called index. Hence the failure you saw.

It seems like this is either some sort of error in your craft.do configuration or a bug in the worker code, but to determine that, you'd have to talk to the developer.

Body:
I am using https://www.craft.do/ as a note-taking app. It has the ability to publish notes online so I want to use it to publish an online collection of notes, which I did here: https://www.craft.do/s/DNUP0iZyULDr15. However, I want to use a custom domain before the thread of random numbers and letters as in something like https://test-site.com/s/DNUP0iZyULDr15. Craft currently does not support custom domains. But a developer created a workaround here: https://zuolan.me/craft_custom_domain_en#64abd1d780c247d8a5fd9678e1d0ec80.

His solution basically uses a script that runs through a worker/service in Cloudflare. This is the script:

// Your domain name
const MY_DOMAIN = 'knu-salin.vinceimbat.workers.dev'

// Website language
const LANG = 'en'

// Favicon url
const FAVICON_URL = 'https://example.com/favicon.ico'

// Your config page link
const CONFIG_URL = 'https://www.craft.do/s/9Q1QIOQrvZNnNf'

// Your Telegram Token and ID
const TG_TOKEN = ""
const TG_CHAT_ID = ""

// END

// Default function
addEventListener('fetch', event => {
  event.respondWith(fetchAndApply(event.request))
})

// Fetch url
async function fetchAndApply(request) {
  let url = new URL(request.url)
  // Set upstream domain
  url.host = 'www.craft.do'
  let pathname = url.pathname
  let response = null

  const config_obj = await configParser()

  // Automatically generate robots.txt and sitemap.xml
  if (pathname === '/robots.txt') {
    return new Response('Sitemap: https://' + MY_DOMAIN + '/sitemap.xml')
  }
  if (pathname === '/sitemap.xml') {
    let sitemap = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
    for(var path in config_obj){
      sitemap += '<url><loc>https://' + MY_DOMAIN + '/' + path + '</loc></url>'
    }
    sitemap += '</urlset>'
    response = new Response(sitemap)
    response.headers.set('content-type', 'application/xml')
    return response
  }
  if (pathname === '/favicon.svg') {
    response = new Response('<svg xmlns="http://www.w3.org/2000/svg" width="100pt" height="100pt" viewBox="0 0 100 100"><g fill="blue" transform="translate(0.000000,100) scale(0.080000,-0.080000)"><path d="M762 1203 c-6 -15 -13 -46 -17 -68 -4 -22 -13 -49 -20 -61 -15 -23 -122 -69 -257 -109 -49 -14 -88 -28 -88 -29 0 -2 33 -20 73 -40 49 -24 87 -36 115 -36 28 0 42 -4 42 -13 0 -34 -295 -517 -390 -639 -40 -52 -4 -28 86 56 49 46 105 109 124 141 19 31 64 98 100 148 77 108 125 186 173 283 20 39 46 78 59 86 13 8 69 34 126 58 107 45 118 57 110 111 -3 21 -10 25 -78 34 l-75 10 -5 45 c-5 42 -7 45 -36 48 -26 3 -33 -1 -42 -25z"/><path d="M754 616 c-40 -19 -88 -39 -108 -46 -43 -14 -45 -30 -7 -72 25 -28 33 -31 80 -30 39 1 54 -3 58 -15 7 -18 -30 -140 -58 -192 -36 -67 6 -93 135 -84 l86 6 0 -26 c0 -14 -4 -37 -10 -51 -5 -14 -8 -26 -6 -26 7 0 110 68 129 85 11 10 17 30 17 60 0 62 -22 70 -150 57 -52 -5 -98 -6 -103 -2 -4 3 3 31 16 61 13 30 32 78 42 108 10 30 28 70 41 89 26 38 30 63 14 93 -17 31 -91 25 -176 -15z"/></g></svg>')
    response.headers.set('content-type', 'image/svg+xml')
    return response
  }

  // Default path
  if (pathname === '/') {
    url.pathname = '/s/' + config_obj['index'].slice(23)
  }

  // Prohibit other Craft.do share pages
  else if (pathname.startsWith('/s/')) {
    url.pathname = "/404"
  }

  // Proxy index blocks pages
  else if (pathname.startsWith('/b/')) {
    url.pathname = '/s/' + config_obj['index'].slice(23) + pathname
  }

  // TODO: There is an unresolved issue here
  // External pages url is troublesome to deal with.
  else if (pathname.includes('/x/')) {
    // url.pathname = '/s/' + config_obj['index'].slice(23) + pathname
    return Response.redirect('https://' + MY_DOMAIN, 301)
  }

  // Proxy js
  else if (pathname.startsWith('/share/') && pathname.endsWith('.js')) {
    response = await fetch(url)
    let body = await response.text()
    // replace all js files domain
    response = new Response(body.replace(/www.craft.do/g, MY_DOMAIN), response)
    response.headers.set('Content-Type', 'application/x-javascript')
  }

  // Proxy images
  else if (pathname.startsWith('/img/')) {
    // Proxy api.craft.do, pages preview api
    // This code can proxy "MY_DOMAIN/img/<pathname>" --> "api.craft.do/render/preview/<slug>"
    url.host = 'api.craft.do'

    let path_name = pathname.slice(5)

    let img_slug = config_obj[path_name].slice(23)
    url.pathname = pathname.replace(pathname, '/render/preview/' + img_slug)

    // Cache images
    const cacheImage = `https://${url.host}${url.pathname}`
    let response = await fetch(url.href, {
      cf: {
        // Always cache this fetch regardless of content type
        // for a max of 86400 seconds before revalidating the resource
        cacheTtl: 86400,
        cacheEverything: true,
        //Enterprise only feature, see Cache API for other plans
        cacheKey: cacheImage,
      },
    })
    // Reconstruct the Response object to make its headers mutable.
    response = new Response(response.body, response)
    // Set cache control headers to cache on browser for 25 minutes
    response.headers.set("Cache-Control", "max-age=1500")
    return response
  }

  // Disable Craft log.
  else if (pathname.startsWith('/api/log/')) {
    return new Response('Disable loging.')
  }

  // Proxy comment API.
  else if (pathname.startsWith('/api/') && (pathname.includes('submitAnon'))) {
    const init = {
      body: request.body,
      method: 'PUT',
      headers: {
        "content-type": "application/json;charset=UTF-8",
      },
    }
    const response = await fetch(url.href, init)
    const resp_json = await response.json()
    const resp_str = JSON.stringify(resp_json)

    // Telegram notify
    const comment_message = resp_json.comments[0].content
    const craft_slug = pathname.split("/")[5]
    const craft_url = 'https://www.craft.do/s/' + craft_slug
    const comment_slug = findJsonKey(config_obj, craft_url)
    const tg_message = 'Comment URL:\n'
      + 'https://' + MY_DOMAIN + '/' + comment_slug
      + '\n\n'
      + 'Comment Message:\n' + comment_message
    await sendToTelegram(tg_message)

    return new Response(resp_str)
  }

  else {
    try {
      let urlIndexSlug = null
      if (pathname.startsWith('/en/') || pathname.startsWith('/p/') || pathname.startsWith('/page/')) {
        urlIndexSlug = pathname.split("/")[1] + '/' + pathname.split("/")[2]
      } else {
        urlIndexSlug = pathname.split("/")[1]
      }

      let configPath = config_obj[urlIndexSlug].slice(23)
      url.pathname = '/s/' + configPath

      console.log(url.pathname)

      if (typeof(configPath) == "undefined") { throw new Error('404 not found: ' + configPath) }
    } catch (error) {
      if (pathname.startsWith('/api/') || pathname.endsWith('.css') || pathname.endsWith('.webmanifest') || pathname.endsWith('.svg')) {
        // nothing
      } else {
        url.pathname = '/404'
        // return new Response(error.message)
      }
    }
  }

  class AttributeRewriter {
    element(element) {
      if (element.getAttribute('property') === 'og:url') {
        element.setAttribute('content', 'https://' + MY_DOMAIN + pathname)
      }
      if (element.getAttribute('property') === 'og:image') {
        if (pathname === '/') { pathname = '/index' }
        element.setAttribute('content', 'https://' + MY_DOMAIN + '/img' + pathname)
      }
      if (element.getAttribute('name') === 'luki:api-endpoint') {
        element.setAttribute('content', 'https://' + MY_DOMAIN + '/api/')
      }
      if (element.getAttribute('lang') === 'en') {
        element.setAttribute('lang', LANG)
      }
      if (element.getAttribute('rel') === 'icon') {
        element.setAttribute('href', FAVICON_URL)
      }
      if (element.getAttribute('rel') === 'apple-touch-icon') {
        element.setAttribute('href', FAVICON_URL)
      }
    }
  }
  class RemoveElement {
    element(element) {
      element.remove()
    }
  }
  async function rewriteHTML(res) {
    res.headers.delete("Content-Security-Policy")
    return new HTMLRewriter()
      .on('body', new BodyRewriter())
      .on('head', new HeadRewriter())
      .on('html', new AttributeRewriter())
      .on('meta', new AttributeRewriter())
      .on('link', new AttributeRewriter())
      .on('meta[name="robots"]', new RemoveElement())   // SEO
      .on('head>style', new RemoveElement())   // Remove fonts
      .on('script[src="https://www.craft.do/assets/js/analytics2.js"]', new RemoveElement())    // Delete analytics js
      .transform(res)
  }

  let method = request.method
  let request_headers = request.headers
  let new_request_headers = new Headers(request_headers)

  new_request_headers.set('Host', url.hostname)
  new_request_headers.set('Referer', url.hostname)

  let original_response = await fetch(url.href, {
    method: method,
    headers: new_request_headers
  })

  let response_headers = original_response.headers
  let new_response_headers = new Headers(response_headers)
  let status = original_response.status

  response = new Response(original_response.body, {
    status,
    headers: new_response_headers
  })

  // If you want change anything in response.
  let text = await response.text()

  // Return modified response.
  let modified_response = new Response(text, {
    status: response.status,
    statusText: response.statusText,
    headers: response.headers
  })

  if (pathname.startsWith('/share/static/js/') && (pathname.includes('codehighlight'))) {
    return modified_response
  } else {
    return rewriteHTML(modified_response)
  }
}

async function configParser() {
  // Delete string "https://www.craft.do/s/"
  let config_slug = CONFIG_URL.slice(23)
  const api_url = 'https://www.craft.do/api/share/' + config_slug
  const init = {
    headers: {
      "content-type": "application/json;charset=UTF-8",
    },
  }
  const config_response = await fetch(api_url, init)       // Get www.craft.do/api/share/<slug> content.
  const response_json = await config_response.json()       // Convert the content to json format (string).
  const content_json = response_json.blocks[1].content     // Get the json data of the first block in the body.
  const content_str = JSON.stringify(content_json)         // Convert json to string.
  // Handle escape characters.
  const config_json = content_str.replace(/\\t/g, '').replace(/\\n/g, '').replace(/\\/g, '').replace('"{', '{').replace('}"', '}')
  let config_obj = JSON.parse(config_json)
  return config_obj
}

async function sendToTelegram(message) {
  const tgUrl = "https://api.telegram.org/bot" + TG_TOKEN + "/sendMessage"
  const init = {
    method: 'POST',
    headers: {
      "content-type": "application/json;charset=UTF-8",
    },
    body: JSON.stringify({
      "chat_id": TG_CHAT_ID,
      "text": message
    })
  }
  await fetch(tgUrl, init)
  // const response = await fetch(tgUrl, init)
  // const resp_text = await response.text()
  // return new Response(resp_text)
}

function findJsonKey(obj, value, compare = (a, b) => a === b) {
  return Object.keys(obj).find(k => compare(obj[k], value))
}

class BodyRewriter {
  element(element) {
    // Append your html
    element.append(`

    `, {
      html: true
    })
  }
}
class HeadRewriter {
  element(element) {
    element.append(`

    `, {
      html: true
    })
  }
}

The only thing I added in his code was the value for const My_DOMAIN and const CONFIG_URL.

When I try to open the URL where it should deploy: https://knu-salin.vinceimbat.workers.dev/, I get Error 1101 Worker threw exception. Upon inspecting the debug console, this is what I saw:

Uncaught (in promise) TypeError and Uncaught (in response) TypeError

Was I doing something wrong? Or is there somethign wrong with his code?

Body:
The error message says:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'slice')
  at fetchAndApply (worker.js:56)

So, let's see what's on line 56. That appears to be:

    url.pathname = '/s/' + config_obj['index'].slice(23)

The error message is telling us that config_obj['index'] was undefined, and so trying to access config_obj['index'].slice is an error.

If config_obj['index'] is undefined, that means that the property index is missing from config_obj. But where did config_obj come from? Up above, we see:

  const config_obj = await configParser()

OK, so the configParser() function creates this object. Let's look at that function.

async function configParser() {
  // Delete string "https://www.craft.do/s/"
  let config_slug = CONFIG_URL.slice(23)
  const api_url = 'https://www.craft.do/api/share/' + config_slug
  const init = {
    headers: {
      "content-type": "application/json;charset=UTF-8",
    },
  }
  const config_response = await fetch(api_url, init)       // Get www.craft.do/api/share/<slug> content.
  const response_json = await config_response.json()       // Convert the content to json format (string).
  const content_json = response_json.blocks[1].content     // Get the json data of the first block in the body.
  const content_str = JSON.stringify(content_json)         // Convert json to string.
  // Handle escape characters.
  const config_json = content_str.replace(/\\t/g, '').replace(/\\n/g, '').replace(/\\/g, '').replace('"{', '{').replace('}"', '}')
  let config_obj = JSON.parse(config_json)
  return config_obj
}

We can see that, based on the URL you specified for CONFIG_URL, this code will compute the url https://www.craft.do/api/share/9Q1QIOQrvZNnNf, fetch that URL, parse it as JSON, and return the result.

If you visit that URL, you see it does indeed return JSON. However, the JSON does not contain a top-level property called index. Hence the failure you saw.

It seems like this is either some sort of error in your craft.do configuration or a bug in the worker code, but to determine that, you'd have to talk to the developer.


问:
Multiple dynamically created comboboxes not triggering event handlers C#
The following code is for a desktop application, not a web app.  I have essentially created a  dynamic row of controls to collect phone information for a contact.  The user can push a button at the end of each row if they want to add an additional row for contact info.

Problem 1: Each row has two comboboxes (cmbo_PhoneType & cmbo_BestCalltime) with eventhandlers attached. The event handlers, cmbo_PhoneType.SelectedIndexChanged && cmbo_BestCallTime.SelectedIndexChanged are not firing for the individual comboBoxes, for each row the user creates.

Problem 2:  The selected list item visible to the user never changes.  For example they select "Home"...the combobox will find it and append, but once the user leaves the combobox the selection (for all comboboxes) are defaulting back to the first item in the list.

If this were a web app, I would think it would be related to postback and viewstate (which I have not yet created the view state, but will once I get past these issues), but since this is a desktop app, I'm not sure.  What have I missed?

```<code>    public partial class frmTestPhoneRows : Form
    {

        int leftControl = 1;
        int StartPos = 88;

        ComboBox cmbo_phoneType = new ComboBox();
        MaskedTextBox msk_phone = new MaskedTextBox();
        TextBox txt_ext = new TextBox();
        ComboBox cmbo_BestCallTime = new ComboBox();
        CheckBox isMobile = new CheckBox();
        CheckBox verified = new CheckBox();
        CheckBox SubscribeToTexts = new CheckBox();
        Button btn_addNew = new Button();

        public frmTestPhoneRows()
        {
            InitializeComponent();
            createNewRow();

        }

        private void frmTestPhoneRows_Load(object sender, EventArgs e)
        {

        }

        void createNewRow()
        {
            //connection string redacted
            MySqlConnection reConn = new MySqlConnection(sConnection);
            reConn.Open();

            MySqlCommand phoneTypeCommand = new MySqlCommand("Select * from lutable_phonetype order by Type", reConn);
            MySqlDataAdapter phoneTypeAdapter = new MySqlDataAdapter();
            DataTable phoneTypeTable = new DataTable();
            phoneTypeAdapter.SelectCommand = phoneTypeCommand;
            phoneTypeAdapter.Fill(phoneTypeTable);

            MySqlCommand bestCallTimeCommand = new MySqlCommand("Select * from lutble_bestcalltime ORDER by CallTime", reConn);
            MySqlDataAdapter bestCallTimeAdapter = new MySqlDataAdapter();
            DataTable bestCallTimeTable = new DataTable();
            bestCallTimeAdapter.SelectCommand = bestCallTimeCommand;
            bestCallTimeAdapter.Fill(bestCallTimeTable);

            ComboBox cmbo_newPhoneType = new ComboBox();
            this.Controls.Add(cmbo_newPhoneType);
            cmbo_newPhoneType.Size = new Size(121, 20);
            cmbo_newPhoneType.DropDownStyle = ComboBoxStyle.DropDown;
            cmbo_newPhoneType.AutoCompleteMode = AutoCompleteMode.Append;
            cmbo_newPhoneType.AutoCompleteSource = AutoCompleteSource.ListItems;
            cmbo_newPhoneType.Top = leftControl * StartPos;
            cmbo_newPhoneType.Left = 18;
            cmbo_newPhoneType.Font = new Font(this.Font.FontFamily, 9);
            cmbo_newPhoneType.BackColor = Color.LightBlue;
            cmbo_newPhoneType.ForeColor = Color.DarkBlue;
            cmbo_newPhoneType.DataSource = phoneTypeTable;
            cmbo_newPhoneType.DisplayMember = "Type";
            cmbo_newPhoneType.ValueMember = "TypeID";
            cmbo_newPhoneType.DataBindings.Add("Selectedvalue", phoneTypeTable, "TypeID");
            cmbo_newPhoneType.SelectedIndexChanged += new System.EventHandler(phoneType_SelectedIndexChanged);

            MaskedTextBox msk_NewPhone = new MaskedTextBox();
            this.Controls.Add(msk_NewPhone);
            msk_NewPhone.Size = new Size(100, 20);
            msk_NewPhone.Top = leftControl * StartPos;
            msk_NewPhone.Left = 143;
            msk_NewPhone.Font = new Font(this.Font.FontFamily, 9);
            msk_NewPhone.BackColor = Color.LightBlue;
            msk_NewPhone.ForeColor = Color.DarkBlue;
            msk_NewPhone.Mask = "(000) 000-0000";

            TextBox txt_newExt = new TextBox();
            this.Controls.Add(txt_newExt);
            txt_newExt.Size = new Size(61, 20);
            txt_newExt.Top = leftControl * StartPos;
            txt_newExt.Left = 247;
            txt_newExt.Font = new Font(this.Font.FontFamily, 9);
            txt_newExt.BackColor = Color.LightBlue;
            txt_newExt.ForeColor = Color.DarkBlue;

            ComboBox cmbo_newBestCallTime = new ComboBox();
            this.Controls.Add(cmbo_newBestCallTime);
            cmbo_newBestCallTime.Size = new Size(231, 20);
            cmbo_newBestCallTime.DropDownStyle = ComboBoxStyle.DropDown;
            cmbo_newBestCallTime.AutoCompleteMode = AutoCompleteMode.Append;
            cmbo_newBestCallTime.AutoCompleteSource = AutoCompleteSource.ListItems;
            cmbo_newBestCallTime.Top = leftControl * StartPos;
            cmbo_newBestCallTime.Left = 312;
            cmbo_newBestCallTime.Font = new Font(this.Font.FontFamily, 9);
            cmbo_newBestCallTime.BackColor = Color.LightBlue;
            cmbo_newBestCallTime.ForeColor = Color.DarkBlue;
            cmbo_newBestCallTime.DataSource = bestCallTimeTable;
            cmbo_newBestCallTime.DisplayMember = "CallTime";
            cmbo_newBestCallTime.ValueMember = "CallTimeId";
            cmbo_newBestCallTime.DataBindings.Add("Selectedvalue", bestCallTimeTable, "CallTimeId");
            cmbo_newBestCallTime.SelectedIndexChanged += new System.EventHandler(cmboBestCallTime_SelectedIndexChanged);

            CheckBox chkbx_newVerified = new CheckBox();
            this.Controls.Add(chkbx_newVerified);
            chkbx_newVerified.CheckState = CheckState.Unchecked;
            chkbx_newVerified.Text = "Verified";
            chkbx_newVerified.Size = new Size(75, 20);
            chkbx_newVerified.Top = leftControl * StartPos;
            chkbx_newVerified.Left = 547;
            chkbx_newVerified.Font = new Font(this.Font.FontFamily, 9);
            chkbx_newVerified.BackColor = Color.LightBlue;
            chkbx_newVerified.ForeColor = Color.DarkBlue;

            CheckBox chkbx_newIsMobile = new CheckBox();
            this.Controls.Add(chkbx_newIsMobile);
            chkbx_newIsMobile.CheckState = CheckState.Unchecked;
            chkbx_newIsMobile.Text = "Mobile";
            chkbx_newIsMobile.Size = new Size(70, 20);
            chkbx_newIsMobile.Top = leftControl * StartPos;
            chkbx_newIsMobile.Left = 626;
            chkbx_newIsMobile.Font = new Font(this.Font.FontFamily, 9);
            chkbx_newIsMobile.BackColor = Color.LightBlue;
            chkbx_newIsMobile.ForeColor = Color.DarkBlue;

            CheckBox chkbx_newSubscribeToTexts = new CheckBox();
            this.Controls.Add(chkbx_newSubscribeToTexts);
            chkbx_newSubscribeToTexts.CheckState = CheckState.Unchecked;
            chkbx_newSubscribeToTexts.Text = "Subscribe To Texts";
            chkbx_newSubscribeToTexts.Size = new Size(156, 20);
            chkbx_newSubscribeToTexts.Top = leftControl * StartPos;
            chkbx_newSubscribeToTexts.Left = 700;
            chkbx_newSubscribeToTexts.Font = new Font(Font.FontFamily, 9);
            chkbx_newSubscribeToTexts.BackColor = Color.LightBlue;
            chkbx_newSubscribeToTexts.ForeColor = Color.DarkBlue;

            Button btn_newAddNew = new Button();
            this.Controls.Add(btn_newAddNew);
            btn_newAddNew.Size = new Size(75, 20);
            btn_newAddNew.BackColor = Color.DarkBlue;
            btn_newAddNew.ForeColor = Color.LightBlue;
            btn_newAddNew.Text = "Add Another";
            btn_newAddNew.Top = leftControl * StartPos;
            btn_newAddNew.Left = 860;
            btn_newAddNew.Click += new System.EventHandler(btn_addNew_Click);

        }

        private void phoneType_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbo_phoneType.DataBindings.Clear();
        }

        private void cmboBestCallTime_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbo_BestCallTime.DataBindings.Clear();
        }

        private void btn_addNew_Click(object sender, EventArgs e)
        {
            StartPos = StartPos + 28;
            createNewRow();

        }
</code>```

答:
When you wire up the dynamic controls, the SOURCE of the event will be passed to the event handler via the SENDER parameter.

Cast "sender" to your appropriate control type and then act upon it:

```<code>private void phoneType_SelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox cb = (ComboBox)sender;
    cb.DataBindings.Clear();
}

private void cmboBestCallTime_SelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox cb = (ComboBox)sender;
    cb.DataBindings.Clear();
}
</code>```

Body:
The following code is for a desktop application, not a web app.  I have essentially created a  dynamic row of controls to collect phone information for a contact.  The user can push a button at the end of each row if they want to add an additional row for contact info.

Problem 1: Each row has two comboboxes (cmbo_PhoneType & cmbo_BestCalltime) with eventhandlers attached. The event handlers, cmbo_PhoneType.SelectedIndexChanged && cmbo_BestCallTime.SelectedIndexChanged are not firing for the individual comboBoxes, for each row the user creates.

Problem 2:  The selected list item visible to the user never changes.  For example they select "Home"...the combobox will find it and append, but once the user leaves the combobox the selection (for all comboboxes) are defaulting back to the first item in the list.

If this were a web app, I would think it would be related to postback and viewstate (which I have not yet created the view state, but will once I get past these issues), but since this is a desktop app, I'm not sure.  What have I missed?

    public partial class frmTestPhoneRows : Form
    {

        int leftControl = 1;
        int StartPos = 88;

        ComboBox cmbo_phoneType = new ComboBox();
        MaskedTextBox msk_phone = new MaskedTextBox();
        TextBox txt_ext = new TextBox();
        ComboBox cmbo_BestCallTime = new ComboBox();
        CheckBox isMobile = new CheckBox();
        CheckBox verified = new CheckBox();
        CheckBox SubscribeToTexts = new CheckBox();
        Button btn_addNew = new Button();

        public frmTestPhoneRows()
        {
            InitializeComponent();
            createNewRow();

        }

        private void frmTestPhoneRows_Load(object sender, EventArgs e)
        {

        }

        void createNewRow()
        {
            //connection string redacted
            MySqlConnection reConn = new MySqlConnection(sConnection);
            reConn.Open();

            MySqlCommand phoneTypeCommand = new MySqlCommand("Select * from lutable_phonetype order by Type", reConn);
            MySqlDataAdapter phoneTypeAdapter = new MySqlDataAdapter();
            DataTable phoneTypeTable = new DataTable();
            phoneTypeAdapter.SelectCommand = phoneTypeCommand;
            phoneTypeAdapter.Fill(phoneTypeTable);

            MySqlCommand bestCallTimeCommand = new MySqlCommand("Select * from lutble_bestcalltime ORDER by CallTime", reConn);
            MySqlDataAdapter bestCallTimeAdapter = new MySqlDataAdapter();
            DataTable bestCallTimeTable = new DataTable();
            bestCallTimeAdapter.SelectCommand = bestCallTimeCommand;
            bestCallTimeAdapter.Fill(bestCallTimeTable);

            ComboBox cmbo_newPhoneType = new ComboBox();
            this.Controls.Add(cmbo_newPhoneType);
            cmbo_newPhoneType.Size = new Size(121, 20);
            cmbo_newPhoneType.DropDownStyle = ComboBoxStyle.DropDown;
            cmbo_newPhoneType.AutoCompleteMode = AutoCompleteMode.Append;
            cmbo_newPhoneType.AutoCompleteSource = AutoCompleteSource.ListItems;
            cmbo_newPhoneType.Top = leftControl * StartPos;
            cmbo_newPhoneType.Left = 18;
            cmbo_newPhoneType.Font = new Font(this.Font.FontFamily, 9);
            cmbo_newPhoneType.BackColor = Color.LightBlue;
            cmbo_newPhoneType.ForeColor = Color.DarkBlue;
            cmbo_newPhoneType.DataSource = phoneTypeTable;
            cmbo_newPhoneType.DisplayMember = "Type";
            cmbo_newPhoneType.ValueMember = "TypeID";
            cmbo_newPhoneType.DataBindings.Add("Selectedvalue", phoneTypeTable, "TypeID");
            cmbo_newPhoneType.SelectedIndexChanged += new System.EventHandler(phoneType_SelectedIndexChanged);

            MaskedTextBox msk_NewPhone = new MaskedTextBox();
            this.Controls.Add(msk_NewPhone);
            msk_NewPhone.Size = new Size(100, 20);
            msk_NewPhone.Top = leftControl * StartPos;
            msk_NewPhone.Left = 143;
            msk_NewPhone.Font = new Font(this.Font.FontFamily, 9);
            msk_NewPhone.BackColor = Color.LightBlue;
            msk_NewPhone.ForeColor = Color.DarkBlue;
            msk_NewPhone.Mask = "(000) 000-0000";

            TextBox txt_newExt = new TextBox();
            this.Controls.Add(txt_newExt);
            txt_newExt.Size = new Size(61, 20);
            txt_newExt.Top = leftControl * StartPos;
            txt_newExt.Left = 247;
            txt_newExt.Font = new Font(this.Font.FontFamily, 9);
            txt_newExt.BackColor = Color.LightBlue;
            txt_newExt.ForeColor = Color.DarkBlue;

            ComboBox cmbo_newBestCallTime = new ComboBox();
            this.Controls.Add(cmbo_newBestCallTime);
            cmbo_newBestCallTime.Size = new Size(231, 20);
            cmbo_newBestCallTime.DropDownStyle = ComboBoxStyle.DropDown;
            cmbo_newBestCallTime.AutoCompleteMode = AutoCompleteMode.Append;
            cmbo_newBestCallTime.AutoCompleteSource = AutoCompleteSource.ListItems;
            cmbo_newBestCallTime.Top = leftControl * StartPos;
            cmbo_newBestCallTime.Left = 312;
            cmbo_newBestCallTime.Font = new Font(this.Font.FontFamily, 9);
            cmbo_newBestCallTime.BackColor = Color.LightBlue;
            cmbo_newBestCallTime.ForeColor = Color.DarkBlue;
            cmbo_newBestCallTime.DataSource = bestCallTimeTable;
            cmbo_newBestCallTime.DisplayMember = "CallTime";
            cmbo_newBestCallTime.ValueMember = "CallTimeId";
            cmbo_newBestCallTime.DataBindings.Add("Selectedvalue", bestCallTimeTable, "CallTimeId");
            cmbo_newBestCallTime.SelectedIndexChanged += new System.EventHandler(cmboBestCallTime_SelectedIndexChanged);

            CheckBox chkbx_newVerified = new CheckBox();
            this.Controls.Add(chkbx_newVerified);
            chkbx_newVerified.CheckState = CheckState.Unchecked;
            chkbx_newVerified.Text = "Verified";
            chkbx_newVerified.Size = new Size(75, 20);
            chkbx_newVerified.Top = leftControl * StartPos;
            chkbx_newVerified.Left = 547;
            chkbx_newVerified.Font = new Font(this.Font.FontFamily, 9);
            chkbx_newVerified.BackColor = Color.LightBlue;
            chkbx_newVerified.ForeColor = Color.DarkBlue;

            CheckBox chkbx_newIsMobile = new CheckBox();
            this.Controls.Add(chkbx_newIsMobile);
            chkbx_newIsMobile.CheckState = CheckState.Unchecked;
            chkbx_newIsMobile.Text = "Mobile";
            chkbx_newIsMobile.Size = new Size(70, 20);
            chkbx_newIsMobile.Top = leftControl * StartPos;
            chkbx_newIsMobile.Left = 626;
            chkbx_newIsMobile.Font = new Font(this.Font.FontFamily, 9);
            chkbx_newIsMobile.BackColor = Color.LightBlue;
            chkbx_newIsMobile.ForeColor = Color.DarkBlue;

            CheckBox chkbx_newSubscribeToTexts = new CheckBox();
            this.Controls.Add(chkbx_newSubscribeToTexts);
            chkbx_newSubscribeToTexts.CheckState = CheckState.Unchecked;
            chkbx_newSubscribeToTexts.Text = "Subscribe To Texts";
            chkbx_newSubscribeToTexts.Size = new Size(156, 20);
            chkbx_newSubscribeToTexts.Top = leftControl * StartPos;
            chkbx_newSubscribeToTexts.Left = 700;
            chkbx_newSubscribeToTexts.Font = new Font(Font.FontFamily, 9);
            chkbx_newSubscribeToTexts.BackColor = Color.LightBlue;
            chkbx_newSubscribeToTexts.ForeColor = Color.DarkBlue;

            Button btn_newAddNew = new Button();
            this.Controls.Add(btn_newAddNew);
            btn_newAddNew.Size = new Size(75, 20);
            btn_newAddNew.BackColor = Color.DarkBlue;
            btn_newAddNew.ForeColor = Color.LightBlue;
            btn_newAddNew.Text = "Add Another";
            btn_newAddNew.Top = leftControl * StartPos;
            btn_newAddNew.Left = 860;
            btn_newAddNew.Click += new System.EventHandler(btn_addNew_Click);

        }

        private void phoneType_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbo_phoneType.DataBindings.Clear();
        }

        private void cmboBestCallTime_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbo_BestCallTime.DataBindings.Clear();
        }

        private void btn_addNew_Click(object sender, EventArgs e)
        {
            StartPos = StartPos + 28;
            createNewRow();

        }

Body:
When you wire up the dynamic controls, the SOURCE of the event will be passed to the event handler via the SENDER parameter.

Cast "sender" to your appropriate control type and then act upon it:

private void phoneType_SelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox cb = (ComboBox)sender;
    cb.DataBindings.Clear();
}

private void cmboBestCallTime_SelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox cb = (ComboBox)sender;
    cb.DataBindings.Clear();
}


问:
How to combine deferred and forward rendering together?
i am trying to use deferred and forward rendering together. i have working code from opengl tutorial and i tried this to adapt to vulkan with same way.

this opengl way :

```<code>glBindFramebuffer(GL_FRAMEBUFFER, gBuffer_FrameBuffer);
//draw gBuffer

glBindFramebuffer(GL_FRAMEBUFFER, main_FrameBuffer);
//draw deferred

glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer_FrameBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, main_FrameBuffer); // write to default framebuffer
glBlitFramebuffer(0,0,SCR_WIDTH,SCR_HEIGHT,0,0,SCR_WIDTH,SCR_HEIGHT,GL_DEPTH_BUFFER_BIT,GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, main_FrameBuffer);
//draw forward
</code>```

in vulkan i set main_FrameBuffer renderpass like this for manuel clear

```<code>colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
</code>```

and tried:

```<code>vkBeginCommandBuffer()

vkCmdBeginRenderPass()//with gBuffer_FrameBuffer
//draw gBuffer
vkCmdEndRenderPass()

vkCmdBeginRenderPass()//main_FrameBuffer
vkCmdClearAttachments()// clear manuel
//draw deferred
vkCmdEndRenderPass()

vkCmdPipelineBarrier//src : gBuffer_FrameBuffer depth image
vkCmdPipelineBarrier//dst : main_FrameBuffer depth image
vkCmdBlitImage//copy gBuffer_FrameBuffer depth image to main_FrameBuffer depth image
vkCmdPipelineBarrier//src : gBuffer_FrameBuffer depth image
vkCmdPipelineBarrier//dst : main_FrameBuffer depth image

vkCmdBeginRenderPass()//main_FrameBuffer here i didn't clear manuel but i am taking black screen
//draw forward
vkCmdEndRenderPass()

vkEndCommandBuffer()
</code>```

答:
```<code>vkCmdPipelineBarrier//src : gBuffer_FrameBuffer depth ima/ge
vkCmdPipelineBarrier//dst : main_FrameBuffer depth image/
</code>```

OpenGL is not Vulkan.

In OpenGL, you effectively had 2 depth images. Your gbuffer FBO had a depth image, and the default framebuffer had a depth image. This was necessary because you cannot attach your gbuffer's depth image to the default framebuffer; you were forced to use the default framebuffer's depth image.

Vulkan has no default framebuffer. A swapchain image is not a framebuffer; it's just an image. Specifically, a color image. If you want to render to a swapchain image with depth testing, it is you who must provide a depth image.

Which can be the same one you used for your deferred rendering.

In fact, there is absolutely no reason to have more than one render pass in your system. You just need to have multiple subpasses.

The render pass contains several image attachments: whatever color attachments you need for the gbuffers, a depth attachment, and the swapchain image you're rendering to. Subpass 0 renders to the gbuffer attachments and depth attachment. Subpass 1 reads from the gbuffer&depth attachments as input attachments, and writes to the swapchain image. Subpass 2 writes to the swapchain image and depth attachment.

There is no need to copy anything in Vulkan here.

Body:
i am trying to use deferred and forward rendering together. i have working code from opengl tutorial and i tried this to adapt to vulkan with same way.

this opengl way :

glBindFramebuffer(GL_FRAMEBUFFER, gBuffer_FrameBuffer);
//draw gBuffer

glBindFramebuffer(GL_FRAMEBUFFER, main_FrameBuffer);
//draw deferred

glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer_FrameBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, main_FrameBuffer); // write to default framebuffer
glBlitFramebuffer(0,0,SCR_WIDTH,SCR_HEIGHT,0,0,SCR_WIDTH,SCR_HEIGHT,GL_DEPTH_BUFFER_BIT,GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, main_FrameBuffer);
//draw forward

in vulkan i set main_FrameBuffer renderpass like this for manuel clear

colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;

and tried:

vkBeginCommandBuffer()

vkCmdBeginRenderPass()//with gBuffer_FrameBuffer
//draw gBuffer
vkCmdEndRenderPass()

vkCmdBeginRenderPass()//main_FrameBuffer
vkCmdClearAttachments()// clear manuel
//draw deferred
vkCmdEndRenderPass()

vkCmdPipelineBarrier//src : gBuffer_FrameBuffer depth image
vkCmdPipelineBarrier//dst : main_FrameBuffer depth image
vkCmdBlitImage//copy gBuffer_FrameBuffer depth image to main_FrameBuffer depth image
vkCmdPipelineBarrier//src : gBuffer_FrameBuffer depth image
vkCmdPipelineBarrier//dst : main_FrameBuffer depth image

vkCmdBeginRenderPass()//main_FrameBuffer here i didn't clear manuel but i am taking black screen
//draw forward
vkCmdEndRenderPass()

vkEndCommandBuffer()

Body:
vkCmdPipelineBarrier//src : gBuffer_FrameBuffer depth ima/ge
vkCmdPipelineBarrier//dst : main_FrameBuffer depth image/

OpenGL is not Vulkan.

In OpenGL, you effectively had 2 depth images. Your gbuffer FBO had a depth image, and the default framebuffer had a depth image. This was necessary because you cannot attach your gbuffer's depth image to the default framebuffer; you were forced to use the default framebuffer's depth image.

Vulkan has no default framebuffer. A swapchain image is not a framebuffer; it's just an image. Specifically, a color image. If you want to render to a swapchain image with depth testing, it is you who must provide a depth image.

Which can be the same one you used for your deferred rendering.

In fact, there is absolutely no reason to have more than one render pass in your system. You just need to have multiple subpasses.

The render pass contains several image attachments: whatever color attachments you need for the gbuffers, a depth attachment, and the swapchain image you're rendering to. Subpass 0 renders to the gbuffer attachments and depth attachment. Subpass 1 reads from the gbuffer&depth attachments as input attachments, and writes to the swapchain image. Subpass 2 writes to the swapchain image and depth attachment.

There is no need to copy anything in Vulkan here.


问:
Gitlab CI .gitlab-ci.yml reference syntax for linux:build: syntax
The majority of .gitlab-ci.yml files which I have seen follow the pattern

```<code>build-code:
  stage: build
  script:
    do-somthing.
</code>```

However, I see some documentation that has steps defined like this

```<code>build:default:
  stage: build
  script:
    do-something.
</code>```

I do not understand why some steps are written with [a-z]+:[a-z]+: pattern as demonstrated by this link for "needs"

Can someone explain which concept is being used when we write steps in this pattern "linux:build:" ?

答:
You can choose the pattern build:linux: if you have other types of builds in your pipeline, like build:mac: and build:netbsd.
But if you prefer you can write build-linux:, ... instead.

It is just a question of style. No other means. And of course, it's not related to builds. In general it's used when you want to visually group similar jobs: group:action1, ...

Body:
The majority of .gitlab-ci.yml files which I have seen follow the pattern

build-code:
  stage: build
  script:
    do-somthing.

However, I see some documentation that has steps defined like this

build:default:
  stage: build
  script:
    do-something.

I do not understand why some steps are written with [a-z]+:[a-z]+: pattern as demonstrated by this link for "needs"

Can someone explain which concept is being used when we write steps in this pattern "linux:build:" ?


问:
how to drop an index key from a table
I'm using sql server 2005/2008 and I have a table that it's PK (rec_index) is also indexed.

```<code>CREATE TABLE [dbo].[MyTable]
(
    [rec_index] INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    file_desc nvarchar(50),
    is_modified bit
)
</code>```

However unfortunately I already have a table like this in my DB which O created without the index.

How can I ask if the table already is indexed do nothing, else add an index?  I can't drop it and than re-create it since i will loose data.

I'm looking for something like "if not exists <index for rec_index> do <create index for rec_index>"

答:
There are so many possibilities here, and I'm not sure which situation you're hitting, and what you want to do in each case:

```<code>USE [tempdb];

-- table with a clustered PK
CREATE TABLE dbo.TableA(rec_index INT IDENTITY(1,1) PRIMARY KEY CLUSTERED);

-- table with non-clustered PK
CREATE TABLE dbo.TableB(rec_index INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED);

-- table with no PK, no indexes
CREATE TABLE dbo.TableC(rec_index INT IDENTITY(1,1));

-- table with no PK, non-clustered non-unique index
CREATE TABLE dbo.TableD(rec_index INT IDENTITY(1,1));
CREATE INDEX d ON dbo.TableD(rec_index);

-- table with no PK, clustered non-unique index
CREATE TABLE dbo.TableE(rec_index INT IDENTITY(1,1));
CREATE CLUSTERED INDEX e ON dbo.TableE(rec_index);

-- table with no PK, non-clustered unique index
CREATE TABLE dbo.TableF(rec_index INT IDENTITY(1,1));
CREATE UNIQUE INDEX f ON dbo.TableF(rec_index);

-- table with no PK, clustered unique index
CREATE TABLE dbo.TableG(rec_index INT IDENTITY(1,1));
CREATE UNIQUE CLUSTERED INDEX g ON dbo.TableG(rec_index);

-- table with unique clustered index, but PK on different column
CREATE TABLE dbo.TableH(rec_index INT IDENTITY(1,1),
     b INT PRIMARY KEY NONCLUSTERED);
CREATE UNIQUE CLUSTERED INDEX h ON dbo.TableH(rec_index);

GO
DROP TABLE dbo.TableA,dbo.TableB,dbo.TableC,dbo.TableD,
           dbo.TableE,dbo.TableF,dbo.TableG,dbo.TableH;
GO
</code>```

You can certainly perform checks for each of these scenarios from the system metadata, and react accordingly. But you need to help us narrow down what you mean by "without the index."

Title: how to drop an index key from a table

Body:
I'm using sql server 2005/2008 and I have a table that it's PK (rec_index) is also indexed.

CREATE TABLE [dbo].[MyTable]
(
    [rec_index] INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    file_desc nvarchar(50),
    is_modified bit
)

However unfortunately I already have a table like this in my DB which O created without the index.

How can I ask if the table already is indexed do nothing, else add an index?  I can't drop it and than re-create it since i will loose data.

I'm looking for something like "if not exists <index for rec_index> do <create index for rec_index>"

Body:
There are so many possibilities here, and I'm not sure which situation you're hitting, and what you want to do in each case:

USE [tempdb];

-- table with a clustered PK
CREATE TABLE dbo.TableA(rec_index INT IDENTITY(1,1) PRIMARY KEY CLUSTERED);

-- table with non-clustered PK
CREATE TABLE dbo.TableB(rec_index INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED);

-- table with no PK, no indexes
CREATE TABLE dbo.TableC(rec_index INT IDENTITY(1,1));

-- table with no PK, non-clustered non-unique index
CREATE TABLE dbo.TableD(rec_index INT IDENTITY(1,1));
CREATE INDEX d ON dbo.TableD(rec_index);

-- table with no PK, clustered non-unique index
CREATE TABLE dbo.TableE(rec_index INT IDENTITY(1,1));
CREATE CLUSTERED INDEX e ON dbo.TableE(rec_index);

-- table with no PK, non-clustered unique index
CREATE TABLE dbo.TableF(rec_index INT IDENTITY(1,1));
CREATE UNIQUE INDEX f ON dbo.TableF(rec_index);

-- table with no PK, clustered unique index
CREATE TABLE dbo.TableG(rec_index INT IDENTITY(1,1));
CREATE UNIQUE CLUSTERED INDEX g ON dbo.TableG(rec_index);

-- table with unique clustered index, but PK on different column
CREATE TABLE dbo.TableH(rec_index INT IDENTITY(1,1),
     b INT PRIMARY KEY NONCLUSTERED);
CREATE UNIQUE CLUSTERED INDEX h ON dbo.TableH(rec_index);

GO
DROP TABLE dbo.TableA,dbo.TableB,dbo.TableC,dbo.TableD,
           dbo.TableE,dbo.TableF,dbo.TableG,dbo.TableH;
GO

You can certainly perform checks for each of these scenarios from the system metadata, and react accordingly. But you need to help us narrow down what you mean by "without the index."


问:
Excel formula to extract string between 2 specific character
I have a data table that looks like this:

And am using the following forumula:
=MID(LEFT(F2,FIND("D",F2)-1),FIND(" ",F2)+1,LEN(F2))

With the goal of extracting the numeric value after the "D" character in my Visit column. Some visits have 1 digit after the "D", some are 2, max will be 3 digits. However, the formula I've tried to use above is returning blanks and #VALUE! only. I figured the number character between the D and the space would work, but then I realize not all will have the space (see C2D16). Can someone explain what I am doing incorrectly?

TIA

Body:
Another:

=-LOOKUP(0,-(MID(F2,FIND("D",F2)+1,{1;2;3})&"**0"))


问:
SQLSTATE[42000]: Syntax error or access violation: 1064 Is given when attempting to migrate
I am attempting to migrate 3 models using:

```<code>php artisan migrate
</code>```

But I am given the error mentioned in the title
This is the rest of the error message:

```<code>SQLSTATE[42000]: Syntax error or access violation: 1064
You have an error in your SQL syntax;
check the manual that corresponds to your
MariaDB server version for the right syntax to use
near 'created_at) null, `updated_at`
timestamp(created_at) null, `created_at` times...' at line 1
</code>```

This is my code:

```<code>Schema::create('v_users', function (Blueprint $table) {
 $table->id('userid');
            $table->string('full_Name');
            $table->string('email');
            $table->string('phone_No');
            $table->string('role');
            $table->timestamps('created_at');
            $table->timestamps('updated_at');
</code>```
```<code>Schema::create('vehicles', function (Blueprint $table) {
  $table->id('v_id');
            $table->foreign('user_id')->references('userid')->on('users')->onDelete('cascade');
            $table->string('v_plate_no');
            $table->string('v_brand');
            $table->string('v_model');
            $table->string('v_color');
            $table->timestamps('created_at');
            $table->timestamps('updated_at');
</code>```
```<code>Schema::create('reports', function (Blueprint $table) {
 $table->id('reportid');
            $table->foreign('vehicleid')->references('v_id')->on('vehicles')->onDelete('cascade');
            $table->string('title');
            $table->string('description');
            $table->timestamps('created_at');
            $table->timestamps('updated_at');
</code>```

I am new to coding in general and would very much appreciate some feedback, thanks in advance.

答:
The main thing that jumps out to me in your migrations is how you're doing your timestamp columns.

The timestamps method does not take a column name, see here:

https://laravel.com/docs/master/migrations#column-method-timestamps

The only argument for this method is precision, should you want to customize that. Right now you're basically specifying a precision of created_at which I can imagine would cause a query failure.

You just need to do this...

```<code>$table->timestamps();
</code>```

... and Laravel will create both the created_at and updated_at columns for you.

If you need to explicitly create your own timestamp column, make sure you use the timestamp() method (no 's' at the end):

https://laravel.com/docs/master/migrations#column-method-timestamp

Body:
I am attempting to migrate 3 models using:

php artisan migrate

But I am given the error mentioned in the title
This is the rest of the error message:

SQLSTATE[42000]: Syntax error or access violation: 1064
You have an error in your SQL syntax;
check the manual that corresponds to your
MariaDB server version for the right syntax to use
near 'created_at) null, `updated_at`
timestamp(created_at) null, `created_at` times...' at line 1

This is my code:

Schema::create('v_users', function (Blueprint $table) {
 $table->id('userid');
            $table->string('full_Name');
            $table->string('email');
            $table->string('phone_No');
            $table->string('role');
            $table->timestamps('created_at');
            $table->timestamps('updated_at');

Schema::create('vehicles', function (Blueprint $table) {
  $table->id('v_id');
            $table->foreign('user_id')->references('userid')->on('users')->onDelete('cascade');
            $table->string('v_plate_no');
            $table->string('v_brand');
            $table->string('v_model');
            $table->string('v_color');
            $table->timestamps('created_at');
            $table->timestamps('updated_at');

Schema::create('reports', function (Blueprint $table) {
 $table->id('reportid');
            $table->foreign('vehicleid')->references('v_id')->on('vehicles')->onDelete('cascade');
            $table->string('title');
            $table->string('description');
            $table->timestamps('created_at');
            $table->timestamps('updated_at');

I am new to coding in general and would very much appreciate some feedback, thanks in advance.

Body:
The main thing that jumps out to me in your migrations is how you're doing your timestamp columns.

The timestamps method does not take a column name, see here:

https://laravel.com/docs/master/migrations#column-method-timestamps

The only argument for this method is precision, should you want to customize that. Right now you're basically specifying a precision of created_at which I can imagine would cause a query failure.

You just need to do this...

$table->timestamps();

... and Laravel will create both the created_at and updated_at columns for you.

If you need to explicitly create your own timestamp column, make sure you use the timestamp() method (no 's' at the end):

https://laravel.com/docs/master/migrations#column-method-timestamp


问:
How to get telegram messages without any delay from any server using the API or is there a get request that I can use?
So I want to get all the messages from the telegram servers I'm in and want to display the messages in the terminal.
I used the telethon python library but the delay is too much takes like 2 to 3 seconds to fetch the message after it has already appeared in the browser.
Thanks.</p>

答: The best way I found is to use the pyrogram library, it displays messages faster than the Telegram App itself which is what I wanted.</p>


问:
Hi so some of my code doesn't wanna get recognized and some of it doesn't wanna show up
So if you look at line 4 and 12 you see when i register everything the user puts in should show up in the txt file but i doesn't and if you look at line 38 it give's me an error it tells me that everything i have put in between the parentheses is not recognized.

 from __future__ import with_statement
from asyncore import write

def reg(Ussername, Password, Age, Real_name, Last_name, Email):
   global file
   file = open ("User_details.txt","a")
   file.write("\n"+Ussername+","+Password+","+Age+","+Real_name+","+Last_name+","+Email)
   file.close
def login():
    pass

def Access():
    if option1 == "login":
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")
        login()
    else:
        print ("Enter all the info we will be asking you to register")
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")

def begin():
    global option1
    print ("Hi my name is Steve would you like to register or login")
    option1 = input ("Login or Register: ")
    if option1 not in ("login", "register"):
        begin()
begin()
Access()
reg(Ussername, Password, Age, Real_name, Last_name, Email)
```

答:
You need to pass all those input strings into your reg function.  Change this:

```<code>        print ("Enter all the info we will be asking you to register")
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")
</code>```

to this:

```<code>        print("Enter all the info we will be asking you to register")
        reg(
            input("Ussername: "),
            input("Password: "),
            input("Age: "),
            input("Real name: "),
            input("Last name: "),
            input("Email: ")
        )
</code>```

Body:
You need to pass all those input strings into your reg function.  Change this:

        print ("Enter all the info we will be asking you to register")
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")

to this:

        print("Enter all the info we will be asking you to register")
        reg(
            input("Ussername: "),
            input("Password: "),
            input("Age: "),
            input("Real name: "),
            input("Last name: "),
            input("Email: ")
        )


问:
Can Maven be made less verbose?
Maven spews out far too many lines of output to my taste (I like the Unix way: no news is good news).

I want to get rid of all [INFO] lines, but I couldn't find any mention of an argument or config settings that controls the verbosity of Maven.

Is there no LOG4J-like way to set the log level?

答:
You can try the -q switch.

-q,--quiet Quiet output - only show errors

OwnerDisplayName: Asaf Bartov

Title: Can Maven be made less verbose?

OwnerDisplayName: imjorge


问:
problem about split a string
I wrote a program to read a registry entry from a file.
And the entry looks like this:

```<code>reg='HKEY_LOCAL_MACHINE\SOFTWARE\TT\Tools\SYS\exePath' #it means rootKey=HKEY_LOCAL_MACHINE, subKey='SOFTWARE\TT\Tools\SYS', property=exePath
</code>```

I want to read this entry from the file and break it into rootKey, subKey and property.
Apparently, I can do it this way:

```<code>rootKey = reg.split('\\', 1)[0]
subKey = reg.split('\\', 1)[1].rsplit('\\', 1)[0]  #might be a stupid way
property = reg.rsplit('\\, 1)[1]
</code>```

Maybe the entry is a stupid one, but any better way to break it into parts like above?

答:
```<code>import re

t=re.search(r"(.+?)\\(.+)\\(.+)", reg)
t.groups()
('HKEY_LOCAL_MACHINE', 'SOFTWARE\\TT\\Tools\\SYS', 'exePath')
</code>```

Title: problem about split a string

Body:
I wrote a program to read a registry entry from a file.
And the entry looks like this:

reg='HKEY_LOCAL_MACHINE\SOFTWARE\TT\Tools\SYS\exePath' #it means rootKey=HKEY_LOCAL_MACHINE, subKey='SOFTWARE\TT\Tools\SYS', property=exePath

I want to read this entry from the file and break it into rootKey, subKey and property.
Apparently, I can do it this way:

rootKey = reg.split('\\', 1)[0]
subKey = reg.split('\\', 1)[1].rsplit('\\', 1)[0]  #might be a stupid way
property = reg.rsplit('\\, 1)[1]

Maybe the entry is a stupid one, but any better way to break it into parts like above?


问:
check if the user has reached to bottom of the page
I am trying to trigger an event when the users scrolls down and reaches to the bottom of the page.

I searched the internet and found some posts in stackoverflow but unexpectedly the answers did not work for me.

Ex: Check if a user has scrolled to the bottom

using the answers given for the above SO post, the event I am trying to trigger is executed when reaching the top of the page and not the bottom.

Please let me know if I am going wrong:

```<code>$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
   loadmore();
}
});

function loadmore(){

var lastProd = $('.product_div').last();
var lastProdID = $('.product_div').last().prop('id');
//console.info(lastProdID); return false;
//var val = document.getElementById("row_no").value;
$.ajax({
    type: 'post',
    url: 'includes/load_products.php',
    data: { getresult:lastProdID },
    success: function (response) {
        console.log(response);
        //var content = document.getElementById("all_rows");
        //content.innerHTML = content.innerHTML+response;
        lastProd.after(response);

        // We increase the value by 10 because we limit the results by 10
        // document.getElementById("row_no").value = Number(val)+10;
    }
});
}
</code>```

答:
The only proper way to do this, at time of writing Feb/11/2022, is here: Check if a user has scrolled to the bottom in subpixel precision era

That detects bottom of scroll for any element. To do this with the "window" in a default web page, you should set element to document.documentElement or document.scrollingElement to get the result you want.

Or, apply the same Math.abs trick as in that answer with window.scrollY, but not that that does not work with scrollable in any other elements, only the documentElement (that's what element is being scrolled when saying "window scroll", and it is the root  element).

Body:
I am trying to trigger an event when the users scrolls down and reaches to the bottom of the page.

I searched the internet and found some posts in stackoverflow but unexpectedly the answers did not work for me.

Ex: Check if a user has scrolled to the bottom

using the answers given for the above SO post, the event I am trying to trigger is executed when reaching the top of the page and not the bottom.

Please let me know if I am going wrong:

$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
   loadmore();
}
});

function loadmore(){

var lastProd = $('.product_div').last();
var lastProdID = $('.product_div').last().prop('id');
//console.info(lastProdID); return false;
//var val = document.getElementById("row_no").value;
$.ajax({
    type: 'post',
    url: 'includes/load_products.php',
    data: { getresult:lastProdID },
    success: function (response) {
        console.log(response);
        //var content = document.getElementById("all_rows");
        //content.innerHTML = content.innerHTML+response;
        lastProd.after(response);

        // We increase the value by 10 because we limit the results by 10
        // document.getElementById("row_no").value = Number(val)+10;
    }
});
}

Body:
The only proper way to do this, at time of writing Feb/11/2022, is here: Check if a user has scrolled to the bottom in subpixel precision era

That detects bottom of scroll for any element. To do this with the "window" in a default web page, you should set element to document.documentElement or document.scrollingElement to get the result you want.

Or, apply the same Math.abs trick as in that answer with window.scrollY, but not that that does not work with scrollable in any other elements, only the documentElement (that's what element is being scrolled when saying "window scroll", and it is the root <html> element).


问:
Sorting over an object passing the search value via a callback results in undefined

I have multiple 'sort options' that id like to pass to make this
function re-usable, but all passed strings result in undefined when
being used to target the objects key. If I hard code the value -
name - then it will sort properly. Thanks!

```<code>const sortNames = [
  { name: "Maddox", age: 69 },
  { name: "John", age: 69 },
  { name: "Alex", age: 69 },
  { name: "Mike", age: 69 },
];

const sortSomeStuff = (param) => {
    const result = sortNames.sort((a, b) => {
    const paramA = a.param.toLowerCase();
    const paramB = a.param.toLowerCase();

    if (paramA > paramB) {
      return -1;
     }
    if (paramA < paramB) {
      return 1;
    }
    return 0;
  });
  return result;
 };

console.log(sortSomeStuff("name"));
</code>```

答:
To have a variable to map an object use [] like this. Also added sort directions.

const sortNames = [
  { name: "Maddox", age: 20 },
  { name: "John", age: 69 },
  { name: "Alex", age: 69 },
  { name: "Mike", age: 69 },
];

const sortSomeStuff = (param, dir="asc") => {
    const result = sortNames.sort((a, b) => {
    var paramA = a[param].toString().toLowerCase();
    var paramB = b[param].toString().toLowerCase();
    if(dir=="dsc"){
      paramA = b[param].toString().toLowerCase();
      paramB = a[param].toString().toLowerCase();
    }
    if (paramA < paramB) {
      return -1;
     }
    if (paramA > paramB) {
      return 1;
    }
    return 0;
  });
  return result;
 };

console.log(sortSomeStuff("age","dsc"));```

Body:
I have multiple 'sort options' that id like to pass to make this
function re-usable, but all passed strings result in undefined when
being used to target the objects key. If I hard code the value -
name - then it will sort properly. Thanks!

const sortNames = [
  { name: "Maddox", age: 69 },
  { name: "John", age: 69 },
  { name: "Alex", age: 69 },
  { name: "Mike", age: 69 },
];

const sortSomeStuff = (param) => {
    const result = sortNames.sort((a, b) => {
    const paramA = a.param.toLowerCase();
    const paramB = a.param.toLowerCase();

    if (paramA > paramB) {
      return -1;
     }
    if (paramA < paramB) {
      return 1;
    }
    return 0;
  });
  return result;
 };

console.log(sortSomeStuff("name"));


问:
Vs Code debug variables characters limited to 1026
Is there a way to increase the character limit when viewing the variables while debugging? I can't view the entire string because it's very long.

答:
See this ref.

In launch.json:

```<code>{
"version": "0.2.0",
"configurations": [
    {
        ...
        "xdebugSettings": {
            "max_data": 1500   //set a proper number.
        }
    }]
}
</code>```

Note: Large max_data number may stuck IDE. Could print the variable in terminal using this way.

Body:
See this ref.

In launch.json:

{
"version": "0.2.0",
"configurations": [
    {
        ...
        "xdebugSettings": {
            "max_data": 1500   //set a proper number.
        }
    }]
}

Note: Large max_data number may stuck IDE. Could print the variable in terminal using this way.


答:
They're not recognized because they don't exist.

You should save the user input and return it. Then, you read it when you execute the Access() function, and pass it to reg().

```<code>from __future__ import with_statement
from asyncore import write

def reg(Ussername, Password, Age, Real_name, Last_name, Email):
   global file
   file = open ("User_details.txt","a")
   file.write("\n"+Ussername+","+Password+","+Age+","+Real_name+","+Last_name+","+Email)
   file.close
def login():
    pass

def Access():
    if option1 == "login":
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")
        login()
    else:
        print ("Enter all the info we will be asking you to register")
        Ussername = input ("Ussername: ")
        Password = input ("Password: ")
        Age = input ("Age: ")
        Real = input ("Real name: ")
        Last = input ("Last name: ")
        Email = input ("Email: ")

    return Ussername, Password, Age, Real, Last, Email

def begin():
    global option1
    print ("Hi my name is Steve would you like to register or login")
    option1 = input ("Login or Register: ")
    if option1 not in ("login", "register"):
        begin()
begin()
Ussername, Password, Age, Real, Last, Email = Access()
reg(Ussername, Password, Age, Real_name, Last_name, Email)
</code>```

The same logic applies to the login part.

Title: Hi so some of my code doesn't wanna get recognized and some of it doesn't wanna show up

Body:
So if you look at line 4 and 12 you see when i register everything the user puts in should show up in the txt file but i doesn't and if you look at line 38 it give's me an error it tells me that everything i have put in between the parentheses is not recognized.

 from __future__ import with_statement
from asyncore import write

def reg(Ussername, Password, Age, Real_name, Last_name, Email):
   global file
   file = open ("User_details.txt","a")
   file.write("\n"+Ussername+","+Password+","+Age+","+Real_name+","+Last_name+","+Email)
   file.close
def login():
    pass

def Access():
    if option1 == "login":
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")
        login()
    else:
        print ("Enter all the info we will be asking you to register")
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")

def begin():
    global option1
    print ("Hi my name is Steve would you like to register or login")
    option1 = input ("Login or Register: ")
    if option1 not in ("login", "register"):
        begin()
begin()
Access()
reg(Ussername, Password, Age, Real_name, Last_name, Email)

Body:
They're not recognized because they don't exist.

You should save the user input and return it. Then, you read it when you execute the Access() function, and pass it to reg().

from __future__ import with_statement
from asyncore import write

def reg(Ussername, Password, Age, Real_name, Last_name, Email):
   global file
   file = open ("User_details.txt","a")
   file.write("\n"+Ussername+","+Password+","+Age+","+Real_name+","+Last_name+","+Email)
   file.close
def login():
    pass

def Access():
    if option1 == "login":
        input ("Ussername: ")
        input ("Password: ")
        input ("Age: ")
        input ("Real name: ")
        input ("Last name: ")
        input ("Email: ")
        login()
    else:
        print ("Enter all the info we will be asking you to register")
        Ussername = input ("Ussername: ")
        Password = input ("Password: ")
        Age = input ("Age: ")
        Real = input ("Real name: ")
        Last = input ("Last name: ")
        Email = input ("Email: ")

    return Ussername, Password, Age, Real, Last, Email

def begin():
    global option1
    print ("Hi my name is Steve would you like to register or login")
    option1 = input ("Login or Register: ")
    if option1 not in ("login", "register"):
        begin()
begin()
Ussername, Password, Age, Real, Last, Email = Access()
reg(Ussername, Password, Age, Real_name, Last_name, Email)

The same logic applies to the login part.